From de69fcb842dbefca4da8319c143ed12fa6b12c54 Mon Sep 17 00:00:00 2001 From: Tom Henderson Date: Mon, 9 Jun 2008 06:40:21 -0700 Subject: [PATCH 001/495] RecvFrom() expansion, add flags parameter to some Send calls --- examples/tcp-large-transfer.cc | 2 +- src/applications/packet-sink/packet-sink.cc | 2 +- src/applications/udp-echo/udp-echo-client.cc | 2 +- src/applications/udp-echo/udp-echo-server.cc | 4 +- src/internet-node/tcp-socket-impl.cc | 34 +- src/internet-node/tcp-socket-impl.h | 12 +- src/internet-node/udp-socket-impl.cc | 49 ++- src/internet-node/udp-socket-impl.h | 9 +- src/node/packet-socket.cc | 34 +- src/node/packet-socket.h | 10 +- src/node/socket.cc | 101 +++--- src/node/socket.h | 309 ++++++++++++++----- src/node/tcp-socket.h | 10 +- src/node/udp-socket.h | 9 +- src/routing/olsr/olsr-agent-impl.cc | 2 +- 15 files changed, 410 insertions(+), 179 deletions(-) diff --git a/examples/tcp-large-transfer.cc b/examples/tcp-large-transfer.cc index c715e348a..f648d50ea 100644 --- a/examples/tcp-large-transfer.cc +++ b/examples/tcp-large-transfer.cc @@ -204,7 +204,7 @@ void WriteUntilBufferFull (Ptr localSocket, uint32_t nBytes) char m = toascii (97 + i % 26); data[i] = m; } - uint32_t amountSent = localSocket->Send (data, curSize); + uint32_t amountSent = localSocket->Send (data, curSize, 0); if(amountSent < curSize) { std::cout << "Socket blocking, returning" << std::endl; diff --git a/src/applications/packet-sink/packet-sink.cc b/src/applications/packet-sink/packet-sink.cc index d73ca1f03..1b65bfa85 100644 --- a/src/applications/packet-sink/packet-sink.cc +++ b/src/applications/packet-sink/packet-sink.cc @@ -105,7 +105,7 @@ void PacketSink::HandleRead (Ptr socket) Ptr packet; while (packet = socket->Recv ()) { - SocketRxAddressTag tag; + SocketAddressTag tag; bool found; found = packet->FindFirstMatchingTag (tag); NS_ASSERT (found); diff --git a/src/applications/udp-echo/udp-echo-client.cc b/src/applications/udp-echo/udp-echo-client.cc index 55f5bda6d..9a1efc293 100644 --- a/src/applications/udp-echo/udp-echo-client.cc +++ b/src/applications/udp-echo/udp-echo-client.cc @@ -156,7 +156,7 @@ UdpEchoClient::HandleRead (Ptr socket) Ptr packet; while (packet = socket->Recv ()) { - SocketRxAddressTag tag; + SocketAddressTag tag; bool found; found = packet->FindFirstMatchingTag (tag); NS_ASSERT (found); diff --git a/src/applications/udp-echo/udp-echo-server.cc b/src/applications/udp-echo/udp-echo-server.cc index 3851a88b7..f5bc4c93b 100644 --- a/src/applications/udp-echo/udp-echo-server.cc +++ b/src/applications/udp-echo/udp-echo-server.cc @@ -97,7 +97,7 @@ UdpEchoServer::HandleRead (Ptr socket) Ptr packet; while (packet = socket->Recv ()) { - SocketRxAddressTag tag; + SocketAddressTag tag; bool found; found = packet->FindFirstMatchingTag (tag); NS_ASSERT (found); @@ -110,7 +110,7 @@ UdpEchoServer::HandleRead (Ptr socket) address.GetIpv4()); NS_LOG_LOGIC ("Echoing packet"); - socket->SendTo (packet, from); + socket->SendTo (packet, 0, from); } } } diff --git a/src/internet-node/tcp-socket-impl.cc b/src/internet-node/tcp-socket-impl.cc index 959b793c5..7cd0d246d 100644 --- a/src/internet-node/tcp-socket-impl.cc +++ b/src/internet-node/tcp-socket-impl.cc @@ -346,8 +346,10 @@ TcpSocketImpl::Connect (const Address & address) } return -1; } + +//p here is just data, no headers int -TcpSocketImpl::Send (const Ptr p) //p here is just data, no headers +TcpSocketImpl::Send (Ptr p, uint32_t flags) { NS_LOG_FUNCTION (this << p); if (m_state == ESTABLISHED || m_state == SYN_SENT || m_state == CLOSE_WAIT) @@ -382,11 +384,6 @@ TcpSocketImpl::Send (const Ptr p) //p here is just data, no headers } } -int TcpSocketImpl::Send (const uint8_t* buf, uint32_t size) -{ - return Send (Create (buf, size)); -} - int TcpSocketImpl::DoSendTo (Ptr p, const Address &address) { NS_LOG_FUNCTION (this << p << address); @@ -420,7 +417,7 @@ int TcpSocketImpl::DoSendTo (Ptr p, Ipv4Address ipv4, uint16_t port) } int -TcpSocketImpl::SendTo (Ptr p, const Address &address) +TcpSocketImpl::SendTo (Ptr p, uint32_t flags, const Address &address) { NS_LOG_FUNCTION (this << address << p); if (!m_connected) @@ -430,7 +427,7 @@ TcpSocketImpl::SendTo (Ptr p, const Address &address) } else { - return Send (p); //drop the address according to BSD manpages + return Send (p, flags); //drop the address according to BSD manpages } } @@ -532,6 +529,23 @@ TcpSocketImpl::GetRxAvailable (void) const return m_rxAvailable; } +Ptr +TcpSocketImpl::RecvFrom (uint32_t maxSize, uint32_t flags, + Address &fromAddress) +{ + NS_LOG_FUNCTION (this << maxSize << flags); + Ptr packet = Recv (maxSize, flags); + if (packet != 0) + { + SocketAddressTag tag; + bool found; + found = packet->FindFirstMatchingTag (tag); + NS_ASSERT (found); + fromAddress = tag.GetAddress (); + } + return packet; +} + void TcpSocketImpl::ForwardUp (Ptr packet, Ipv4Address ipv4, uint16_t port) { @@ -1048,7 +1062,7 @@ void TcpSocketImpl::NewRx (Ptr p, m_nextRxSequence += s; // Advance next expected sequence //bytesReceived += s; // Statistics NS_LOG_LOGIC("Case 1, advanced nrxs to " << m_nextRxSequence ); - SocketRxAddressTag tag; + SocketAddressTag tag; tag.SetAddress (fromAddress); p->AddTag (tag); //buffer this, it'll be read by call to Recv @@ -1106,7 +1120,7 @@ void TcpSocketImpl::NewRx (Ptr p, i->second = 0; // relase reference to already buffered } // Save for later delivery - SocketRxAddressTag tag; + SocketAddressTag tag; tag.SetAddress (fromAddress); p->AddTag (tag); m_bufferedData[tcpHeader.GetSequenceNumber () ] = p; diff --git a/src/internet-node/tcp-socket-impl.h b/src/internet-node/tcp-socket-impl.h index 8f1f832f5..ca5c5a5d1 100644 --- a/src/internet-node/tcp-socket-impl.h +++ b/src/internet-node/tcp-socket-impl.h @@ -65,14 +65,14 @@ public: virtual int ShutdownSend (void); virtual int ShutdownRecv (void); virtual int Connect(const Address &address); - virtual int Send (Ptr p); - virtual int Send (const uint8_t* buf, uint32_t size); - virtual int SendTo(Ptr p, const Address &address); - virtual uint32_t GetTxAvailable (void) const; virtual int Listen(uint32_t queueLimit); - - virtual Ptr Recv (uint32_t maxSize, uint32_t flags); + virtual uint32_t GetTxAvailable (void) const; + virtual int Send (Ptr p, uint32_t flags); + virtual int SendTo(Ptr p, uint32_t flags, const Address &toAddress); virtual uint32_t GetRxAvailable (void) const; + virtual Ptr Recv (uint32_t maxSize, uint32_t flags); + virtual Ptr RecvFrom (uint32_t maxSize, uint32_t flags, + Address &fromAddress); private: friend class Tcp; diff --git a/src/internet-node/udp-socket-impl.cc b/src/internet-node/udp-socket-impl.cc index 03b0da18f..5f9872089 100644 --- a/src/internet-node/udp-socket-impl.cc +++ b/src/internet-node/udp-socket-impl.cc @@ -224,9 +224,9 @@ UdpSocketImpl::Listen (uint32_t queueLimit) } int -UdpSocketImpl::Send (Ptr p) +UdpSocketImpl::Send (Ptr p, uint32_t flags) { - NS_LOG_FUNCTION (this << p); + NS_LOG_FUNCTION (this << p << flags); if (!m_connected) { @@ -239,7 +239,7 @@ UdpSocketImpl::Send (Ptr p) int UdpSocketImpl::DoSend (Ptr p) { - NS_LOG_FUNCTION_NOARGS (); + NS_LOG_FUNCTION (this << p); if (m_endPoint == 0) { if (Bind () == -1) @@ -380,19 +380,28 @@ UdpSocketImpl::GetTxAvailable (void) const } int -UdpSocketImpl::SendTo (Ptr p, const Address &address) +UdpSocketImpl::SendTo (Ptr p, uint32_t flags, const Address &address) { - NS_LOG_FUNCTION (this << address << p); + NS_LOG_FUNCTION (this << p << flags << address); InetSocketAddress transport = InetSocketAddress::ConvertFrom (address); Ipv4Address ipv4 = transport.GetIpv4 (); uint16_t port = transport.GetPort (); return DoSendTo (p, ipv4, port); } +uint32_t +UdpSocketImpl::GetRxAvailable (void) const +{ + NS_LOG_FUNCTION_NOARGS (); + // We separately maintain this state to avoid walking the queue + // every time this might be called + return m_rxAvailable; +} + Ptr UdpSocketImpl::Recv (uint32_t maxSize, uint32_t flags) { - NS_LOG_FUNCTION_NOARGS (); + NS_LOG_FUNCTION (this << maxSize << flags); if (m_deliveryQueue.empty() ) { return 0; @@ -410,13 +419,21 @@ UdpSocketImpl::Recv (uint32_t maxSize, uint32_t flags) return p; } -uint32_t -UdpSocketImpl::GetRxAvailable (void) const +Ptr +UdpSocketImpl::RecvFrom (uint32_t maxSize, uint32_t flags, + Address &fromAddress) { - NS_LOG_FUNCTION_NOARGS (); - // We separately maintain this state to avoid walking the queue - // every time this might be called - return m_rxAvailable; + NS_LOG_FUNCTION (this << maxSize << flags); + Ptr packet = Recv (maxSize, flags); + if (packet != 0) + { + SocketAddressTag tag; + bool found; + found = packet->FindFirstMatchingTag (tag); + NS_ASSERT (found); + fromAddress = tag.GetAddress (); + } + return packet; } void @@ -431,7 +448,7 @@ UdpSocketImpl::ForwardUp (Ptr packet, Ipv4Address ipv4, uint16_t port) if ((m_rxAvailable + packet->GetSize ()) <= m_rcvBufSize) { Address address = InetSocketAddress (ipv4, port); - SocketRxAddressTag tag; + SocketAddressTag tag; tag.SetAddress (address); packet->AddTag (tag); m_deliveryQueue.push (packet); @@ -638,7 +655,7 @@ UdpSocketImplTest::RunTests (void) // Unicast test m_receivedPacket = Create (); m_receivedPacket2 = Create (); - NS_TEST_ASSERT_EQUAL (txSocket->SendTo ( Create (123), + NS_TEST_ASSERT_EQUAL (txSocket->SendTo ( Create (123), 0, InetSocketAddress (Ipv4Address("10.0.0.1"), 1234)), 123); Simulator::Run (); NS_TEST_ASSERT_EQUAL (m_receivedPacket->GetSize (), 123); @@ -651,7 +668,7 @@ UdpSocketImplTest::RunTests (void) m_receivedPacket = Create (); m_receivedPacket2 = Create (); - NS_TEST_ASSERT_EQUAL (txSocket->SendTo ( Create (123), + NS_TEST_ASSERT_EQUAL (txSocket->SendTo ( Create (123), 0, InetSocketAddress (Ipv4Address("255.255.255.255"), 1234)), 123); Simulator::Run (); NS_TEST_ASSERT_EQUAL (m_receivedPacket->GetSize (), 123); @@ -673,7 +690,7 @@ UdpSocketImplTest::RunTests (void) m_receivedPacket = Create (); m_receivedPacket2 = Create (); - NS_TEST_ASSERT_EQUAL (txSocket->SendTo (Create (123), + NS_TEST_ASSERT_EQUAL (txSocket->SendTo (Create (123), 0, InetSocketAddress (Ipv4Address("255.255.255.255"), 1234)), 123); Simulator::Run (); NS_TEST_ASSERT_EQUAL (m_receivedPacket->GetSize (), 123); diff --git a/src/internet-node/udp-socket-impl.h b/src/internet-node/udp-socket-impl.h index f7b185215..46dd51cab 100644 --- a/src/internet-node/udp-socket-impl.h +++ b/src/internet-node/udp-socket-impl.h @@ -58,12 +58,13 @@ public: virtual int ShutdownRecv (void); virtual int Connect(const Address &address); virtual int Listen (uint32_t queueLimit); - virtual int Send (Ptr p); - virtual int SendTo (Ptr p, const Address &address); virtual uint32_t GetTxAvailable (void) const; - - virtual Ptr Recv (uint32_t maxSize, uint32_t flags); + virtual int Send (Ptr p, uint32_t flags); + virtual int SendTo (Ptr p, uint32_t flags, const Address &address); virtual uint32_t GetRxAvailable (void) const; + virtual Ptr Recv (uint32_t maxSize, uint32_t flags); + virtual Ptr RecvFrom (uint32_t maxSize, uint32_t flags, + Address &fromAddress); private: // Attributes set through UdpSocket base class diff --git a/src/node/packet-socket.cc b/src/node/packet-socket.cc index d4824e36c..4e6bb847c 100644 --- a/src/node/packet-socket.cc +++ b/src/node/packet-socket.cc @@ -230,7 +230,7 @@ PacketSocket::Listen(uint32_t queueLimit) } int -PacketSocket::Send (Ptr p) +PacketSocket::Send (Ptr p, uint32_t flags) { NS_LOG_FUNCTION_NOARGS (); if (m_state == STATE_OPEN || @@ -239,7 +239,7 @@ PacketSocket::Send (Ptr p) m_errno = ERROR_NOTCONN; return -1; } - return SendTo (p, m_destAddr); + return SendTo (p, flags, m_destAddr); } uint32_t @@ -275,7 +275,7 @@ PacketSocket::GetTxAvailable (void) const } int -PacketSocket::SendTo(Ptr p, const Address &address) +PacketSocket::SendTo (Ptr p, uint32_t flags, const Address &address) { NS_LOG_FUNCTION_NOARGS (); PacketSocketAddress ad; @@ -361,7 +361,7 @@ PacketSocket::ForwardUp (Ptr device, Ptr packet, if ((m_rxAvailable + packet->GetSize ()) <= m_rcvBufSize) { - SocketRxAddressTag tag; + SocketAddressTag tag; tag.SetAddress (address); packet->AddTag (tag); m_deliveryQueue.push (packet); @@ -381,6 +381,15 @@ PacketSocket::ForwardUp (Ptr device, Ptr packet, } } +uint32_t +PacketSocket::GetRxAvailable (void) const +{ + NS_LOG_FUNCTION_NOARGS (); + // We separately maintain this state to avoid walking the queue + // every time this might be called + return m_rxAvailable; +} + Ptr PacketSocket::Recv (uint32_t maxSize, uint32_t flags) { @@ -402,13 +411,20 @@ PacketSocket::Recv (uint32_t maxSize, uint32_t flags) return p; } -uint32_t -PacketSocket::GetRxAvailable (void) const +Ptr +PacketSocket::RecvFrom (uint32_t maxSize, uint32_t flags, Address &fromAddress) { NS_LOG_FUNCTION_NOARGS (); - // We separately maintain this state to avoid walking the queue - // every time this might be called - return m_rxAvailable; + Ptr packet = Recv (maxSize, flags); + if (packet != 0) + { + SocketAddressTag tag; + bool found; + found = packet->FindFirstMatchingTag (tag); + NS_ASSERT (found); + fromAddress = tag.GetAddress (); + } + return packet; } }//namespace ns3 diff --git a/src/node/packet-socket.h b/src/node/packet-socket.h index f0647ae81..528ca740d 100644 --- a/src/node/packet-socket.h +++ b/src/node/packet-socket.h @@ -93,13 +93,13 @@ public: virtual int ShutdownRecv (void); virtual int Connect(const Address &address); virtual int Listen(uint32_t queueLimit); - virtual int Send (Ptr p); virtual uint32_t GetTxAvailable (void) const; - - virtual int SendTo(Ptr p, const Address &address); - - virtual Ptr Recv (uint32_t maxSize, uint32_t flags); + virtual int Send (Ptr p, uint32_t flags); + virtual int SendTo(Ptr p, uint32_t flags, const Address &toAddress); virtual uint32_t GetRxAvailable (void) const; + virtual Ptr Recv (uint32_t maxSize, uint32_t flags); + virtual Ptr RecvFrom (uint32_t maxSize, uint32_t flags, + Address &fromAddress); private: void ForwardUp (Ptr device, Ptr packet, diff --git a/src/node/socket.cc b/src/node/socket.cc index 0bdc167a0..e5409ca0b 100644 --- a/src/node/socket.cc +++ b/src/node/socket.cc @@ -40,13 +40,6 @@ Socket::~Socket () NS_LOG_FUNCTION_NOARGS (); } -void -Socket::SetCloseUnblocksCallback (Callback > closeUnblocks) -{ - NS_LOG_FUNCTION_NOARGS (); - m_closeUnblocks = closeUnblocks; -} - Ptr Socket::CreateSocket (Ptr node, TypeId tid) { @@ -110,6 +103,13 @@ Socket::SetRecvCallback (Callback > receivedData) m_receivedData = receivedData; } +int +Socket::Send (Ptr p) +{ + NS_LOG_FUNCTION_NOARGS (); + return Send (p, 0); +} + void Socket::NotifyCloseUnblocks (void) { @@ -125,7 +125,8 @@ int Socket::Listen (uint32_t queueLimit) return 0; //XXX the base class version does nothing } -int Socket::Send (const uint8_t* buf, uint32_t size) +int +Socket::Send (const uint8_t* buf, uint32_t size, uint32_t flags) { NS_LOG_FUNCTION_NOARGS (); Ptr p; @@ -137,24 +138,12 @@ int Socket::Send (const uint8_t* buf, uint32_t size) { p = Create (size); } - return Send (p); -} - -Ptr -Socket::Recv (void) -{ - return Recv (std::numeric_limits::max(), 0); + return Send (p, flags); } int -Socket::Recv (uint8_t* buf, uint32_t size, uint32_t flags) -{ - Ptr p = Recv (size, flags); // read up to "size" bytes - memcpy (buf, p->PeekData (), p->GetSize()); - return p->GetSize (); -} - -int Socket::SendTo (const uint8_t* buf, uint32_t size, const Address &address) +Socket::SendTo (const uint8_t* buf, uint32_t size, uint32_t flags, + const Address &toAddress) { NS_LOG_FUNCTION_NOARGS (); Ptr p; @@ -166,7 +155,48 @@ int Socket::SendTo (const uint8_t* buf, uint32_t size, const Address &address) { p = Create (size); } - return SendTo (p, address); + return SendTo (p, flags, toAddress); +} + +Ptr +Socket::Recv (void) +{ + NS_LOG_FUNCTION_NOARGS (); + return Recv (std::numeric_limits::max(), 0); +} + +int +Socket::Recv (uint8_t* buf, uint32_t size, uint32_t flags) +{ + NS_LOG_FUNCTION_NOARGS (); + Ptr p = Recv (size, flags); // read up to "size" bytes + if (p == 0) + { + return 0; + } + memcpy (buf, p->PeekData (), p->GetSize()); + return p->GetSize (); +} + +Ptr +Socket::RecvFrom (Address &fromAddress) +{ + NS_LOG_FUNCTION_NOARGS (); + return RecvFrom (std::numeric_limits::max(), 0, fromAddress); +} + +int +Socket::RecvFrom (uint8_t* buf, uint32_t size, uint32_t flags, + Address &fromAddress) +{ + NS_LOG_FUNCTION_NOARGS (); + Ptr p = RecvFrom (size, flags, fromAddress); + if (p == 0) + { + return 0; + } + memcpy (buf, p->PeekData (), p->GetSize()); + return p->GetSize (); } void @@ -281,54 +311,54 @@ Socket::NotifyDataRecv (void) * Socket Tags ***************************************************************/ -SocketRxAddressTag::SocketRxAddressTag () +SocketAddressTag::SocketAddressTag () { } void -SocketRxAddressTag::SetAddress (Address addr) +SocketAddressTag::SetAddress (Address addr) { m_address = addr; } Address -SocketRxAddressTag::GetAddress (void) const +SocketAddressTag::GetAddress (void) const { return m_address; } TypeId -SocketRxAddressTag::GetTypeId (void) +SocketAddressTag::GetTypeId (void) { - static TypeId tid = TypeId ("ns3::SocketRxAddressTag") + static TypeId tid = TypeId ("ns3::SocketAddressTag") .SetParent () - .AddConstructor () + .AddConstructor () ; return tid; } TypeId -SocketRxAddressTag::GetInstanceTypeId (void) const +SocketAddressTag::GetInstanceTypeId (void) const { return GetTypeId (); } uint32_t -SocketRxAddressTag::GetSerializedSize (void) const +SocketAddressTag::GetSerializedSize (void) const { return m_address.GetSerializedSize (); } void -SocketRxAddressTag::Serialize (TagBuffer i) const +SocketAddressTag::Serialize (TagBuffer i) const { m_address.Serialize (i); } void -SocketRxAddressTag::Deserialize (TagBuffer i) +SocketAddressTag::Deserialize (TagBuffer i) { m_address.Deserialize (i); } void -SocketRxAddressTag::Print (std::ostream &os) const +SocketAddressTag::Print (std::ostream &os) const { os << "address=" << m_address; } @@ -386,4 +416,5 @@ SocketIpTtlTag::Print (std::ostream &os) const os << "Ttl=" << (uint32_t) m_ttl; } + }//namespace ns3 diff --git a/src/node/socket.h b/src/node/socket.h index 34e018743..a15ad0061 100644 --- a/src/node/socket.h +++ b/src/node/socket.h @@ -92,27 +92,22 @@ public: * \param tid The TypeId of the socket to create */ static Ptr CreateSocket (Ptr node, TypeId tid); - /** * \return the errno associated to the last call which failed in this * socket. Each socket's errno is initialized to zero * when the socket is created. */ virtual enum Socket::SocketErrno GetErrno (void) const = 0; - /** * \returns the node this socket is associated with. */ virtual Ptr GetNode (void) const = 0; - void SetCloseUnblocksCallback (Callback > closeUnblocks); - /** * \param closeCompleted Callback invoked when the close operation is * completed. */ void SetCloseCallback (Callback > closeCompleted); - /** * \param connectionSucceeded this callback is invoked when the * connection request initiated by the user is successfully @@ -165,7 +160,8 @@ public: * user should check this return value to confirm that the * callback is supported. */ - virtual bool SetDataSentCallback (Callback, uint32_t> dataSent); + virtual bool SetDataSentCallback (Callback, + uint32_t> dataSent); /** * \brief Notify application when space in transmit buffer is added * @@ -241,13 +237,27 @@ public: */ virtual int Listen (uint32_t queueLimit) = 0; + /** + * \brief Returns the number of bytes which can be sent in a single call + * to Send. + * + * For datagram sockets, this returns the number of bytes that + * can be passed atomically through the underlying protocol. + * + * For stream sockets, this returns the available space in bytes + * left in the transmit buffer. + */ + virtual uint32_t GetTxAvailable (void) const = 0; + /** * \brief Send data (or dummy data) to the remote host * * This function matches closely in semantics to the send() function * call in the standard C library (libc): * ssize_t send (int s, const void *msg, size_t len, int flags); - * except that the function call is asynchronous. + * except that the send I/O is asynchronous. This is the + * primary Send method at this low-level API and must be implemented + * by subclasses. * * In a typical blocking sockets model, this call would block upon * lack of space to hold the message to be sent. In ns-3 at this @@ -272,96 +282,231 @@ public: * split the Packet (based on information obtained from * GetTxAvailable) and reattempt to send the data. * + * The flags argument is formed by or'ing one or more of the values: + * MSG_OOB process out-of-band data + * MSG_DONTROUTE bypass routing, use direct interface + * These flags are _unsupported_ as of ns-3.1. + * * \param p ns3::Packet to send + * \param flags Socket control flags * \returns the number of bytes accepted for transmission if no error * occurs, and -1 otherwise. - */ - virtual int Send (Ptr p) = 0; - - /** - * \brief Returns the number of bytes which can be sent in a single call - * to Send. - * - * For datagram sockets, this returns the number of bytes that - * can be passed atomically through the underlying protocol. * - * For stream sockets, this returns the available space in bytes - * left in the transmit buffer. + * \see SetSendCallback */ - virtual uint32_t GetTxAvailable (void) const = 0; + virtual int Send (Ptr p, uint32_t flags) = 0; - /** - * \brief Send data (or dummy data) to the remote host - * \param buf A pointer to a raw byte buffer of some data to send. If this - * is 0, we send dummy data whose size is specified by the second parameter - * \param size the number of bytes to copy from the buffer - * - * This is provided so as to have an API which is closer in appearance - * to that of real network or BSD sockets. - */ - int Send (const uint8_t* buf, uint32_t size); - /** * \brief Send data to a specified peer. + * + * This method has similar semantics to Send () but subclasses may + * want to provide checks on socket state, so the implementation is + * pushed to subclasses. + * * \param p packet to send - * \param address IP Address of remote host + * \param flags Socket control flags + * \param toAddress IP Address of remote host * \returns -1 in case of error or the number of bytes copied in the * internal buffer and accepted for transmission. */ - virtual int SendTo (Ptr p, const Address &address) = 0; + virtual int SendTo (Ptr p, uint32_t flags, + const Address &toAddress) = 0; - /** - * \brief Send data to a specified peer. - * \param buf A pointer to a raw byte buffer of some data to send. If this - * is 0, we send dummy data whose size is specified by the third parameter - * \param size the number of bytes to copy from the buffer - * \param address IP Address of remote host - * \returns -1 in case of error or the number of bytes copied in the - * internal buffer and accepted for transmission. - * - * This is provided so as to have an API which is closer in appearance - * to that of real network or BSD sockets. - */ - int SendTo (const uint8_t* buf, uint32_t size, const Address &address); - - /** - * \brief Read a single packet from the socket - * \param maxSize reader will accept packet up to maxSize - * \param flags Socket recv flags - * \returns Ptr of the next in-sequence packet. Returns - * 0 if the socket cannot return a next in-sequence packet conforming - * to the maxSize and flags. - */ - virtual Ptr Recv (uint32_t maxSize, uint32_t flags) = 0; - /** - * \brief Read a single packet from the socket - * - * Overloaded version of Recv(maxSize, flags) with maxSize - * implicitly set to maximum sized integer, and flags set to zero. - * - * \returns Ptr of the next in-sequence packet. Returns - * 0 if the socket cannot return a next in-sequence packet. - */ - Ptr Recv (void); - /** - * \brief Recv data (or dummy data) from the remote host - * \param buf A pointer to a raw byte buffer to write the data to. - * If the underlying packet was carring null (fake) data, this buffer - * will be zeroed up to the length specified by the return value. - * \param size Number of bytes (at most) to copy to buf - * \param flags any flags to pass to the socket - * \returns number of bytes copied into buf - * - * This is provided so as to have an API which is closer in appearance - * to that of real network or BSD sockets. - */ - int Recv (uint8_t* buf, uint32_t size, uint32_t flags); /** * Return number of bytes which can be returned from one or * multiple calls to Recv. * Must be possible to call this method from the Recv callback. */ virtual uint32_t GetRxAvailable (void) const = 0; + + /** + * \brief Read data from the socket + * + * This function matches closely in semantics to the recv() function + * call in the standard C library (libc): + * ssize_t recv (int s, void *buf, size_t len, int flags); + * except that the receive I/O is asynchronous. This is the + * primary Recv method at this low-level API and must be implemented + * by subclasses. + * + * This method is normally used only on a connected socket. + * In a typical blocking sockets model, this call would block until + * at least one byte is returned or the connection closes. + * In ns-3 at this API, the call returns immediately in such a case + * and returns 0 if nothing is available to be read. + * However, an application can set a callback, ns3::SetRecvCallback, + * to be notified of data being available to be read + * (when it conceptually unblocks); this is an asynchronous + * I/O model for recv(). + * + * This variant of Recv() uses class ns3::Packet to encapsulate + * data, rather than providing a raw pointer and length field. + * This allows an ns-3 application to attach tags if desired (such + * as a flow ID) and may allow the simulator to avoid some data + * copies. Despite the appearance of receiving Packets on a stream + * socket, just think of it as a fancy byte buffer with streaming + * semantics. + * + * The semantics depend on the type of socket. For a datagram socket, + * each Recv() returns the data from at most one Send(), and order + * is not necessarily preserved. For a stream socket, the bytes + * are delivered in order, and on-the-wire packet boundaries are + * not preserved. + * + * The flags argument is formed by or'ing one or more of the values: + * MSG_OOB process out-of-band data + * MSG_PEEK peek at incoming message + * These flags are _unsupported_ as of ns-3.1. + * + * Some variants of Recv() are supported as additional API, + * including RecvFrom(), overloaded Recv() without arguments, + * and variants that use raw character buffers. + * + * \param maxSize reader will accept packet up to maxSize + * \param flags Socket control flags + * \returns Ptr of the next in-sequence packet. Returns + * 0 if the socket cannot return a next in-sequence packet conforming + * to the maxSize and flags. + * + * \see SetRecvCallback + */ + virtual Ptr Recv (uint32_t maxSize, uint32_t flags) = 0; + + /** + * \brief Read a single packet from the socket and retrieve the sender + * address. + * + * Calls Recv(maxSize, flags) with maxSize + * implicitly set to maximum sized integer, and flags set to zero. + * + * This method has similar semantics to Recv () but subclasses may + * want to provide checks on socket state, so the implementation is + * pushed to subclasses. + * + * \param maxSize reader will accept packet up to maxSize + * \param flags Socket control flags + * \param fromAddress output parameter that will return the + * address of the sender of the received packet, if any. Remains + * untouched if no packet is received. + * \returns Ptr of the next in-sequence packet. Returns + * 0 if the socket cannot return a next in-sequence packet. + */ + virtual Ptr RecvFrom (uint32_t maxSize, uint32_t flags, + Address &fromAddress) = 0; + + ///////////////////////////////////////////////////////////////////// + // The remainder of these public methods are overloaded methods // + // or variants of Send() and Recv(), and they are non-virtual // + ///////////////////////////////////////////////////////////////////// + + /** + * \brief Send data (or dummy data) to the remote host + * + * Overloaded version of Send(..., flags) with flags set to zero. + * + * \param p ns3::Packet to send + * \returns the number of bytes accepted for transmission if no error + * occurs, and -1 otherwise. + */ + int Send (Ptr p); + + /** + * \brief Send data (or dummy data) to the remote host + * + * This method is provided so as to have an API which is closer in + * appearance to that of real network or BSD sockets. + * + * \param buf A pointer to a raw byte buffer of some data to send. If + * this buffer is 0, we send dummy data whose size is specified by the + * second parameter + * \param size the number of bytes to copy from the buffer + * \param flags Socket control flags + */ + int Send (const uint8_t* buf, uint32_t size, uint32_t flags); + + + /** + * \brief Send data to a specified peer. + * + * This method is provided so as to have an API which is closer in + * appearance to that of real network or BSD sockets. + * + * \param buf A pointer to a raw byte buffer of some data to send. + * If this is 0, we send dummy data whose size is specified by the + * third parameter + * \param size the number of bytes to copy from the buffer + * \param flags Socket control flags + * \param address IP Address of remote host + * \returns -1 in case of error or the number of bytes copied in the + * internal buffer and accepted for transmission. + * + */ + int SendTo (const uint8_t* buf, uint32_t size, uint32_t flags, + const Address &address); + + /** + * \brief Read a single packet from the socket + * + * Overloaded version of Recv(maxSize, flags) with maxSize + * implicitly set to maximum sized integer, and flags set to zero. + * + * \returns Ptr of the next in-sequence packet. Returns + * 0 if the socket cannot return a next in-sequence packet. + */ + Ptr Recv (void); + + /** + * \brief Recv data (or dummy data) from the remote host + * + * This method is provided so as to have an API which is closer in + * appearance to that of real network or BSD sockets. + * + * If the underlying packet was carring null (fake) data, this buffer + * will be zeroed up to the length specified by the return value. + * + * \param buf A pointer to a raw byte buffer to write the data to. + * \param size Number of bytes (at most) to copy to buf + * \param flags any flags to pass to the socket + * \returns number of bytes copied into buf + */ + int Recv (uint8_t* buf, uint32_t size, uint32_t flags); + + /** + * \brief Read a single packet from the socket and retrieve the sender + * address. + * + * Calls RecvFrom (maxSize, flags, fromAddress) with maxSize + * implicitly set to maximum sized integer, and flags set to zero. + * + * \param maxSize reader will accept packet up to maxSize + * \param flags Socket control flags + * \param fromAddress output parameter that will return the + * address of the sender of the received packet, if any. Remains + * untouched if no packet is received. + * \returns Ptr of the next in-sequence packet. Returns + * 0 if the socket cannot return a next in-sequence packet. + */ + Ptr RecvFrom (Address &fromAddress); + + /** + * \brief Read a single packet from the socket and retrieve the sender + * address. + * + * This method is provided so as to have an API which is closer in + * appearance to that of real network or BSD sockets. + * + * \param buf A pointer to a raw byte buffer to write the data to. + * If the underlying packet was carring null (fake) data, this buffer + * will be zeroed up to the length specified by the return value. + * \param size Number of bytes (at most) to copy to buf + * \param flags any flags to pass to the socket + * \param fromAddress output parameter that will return the + * address of the sender of the received packet, if any. Remains + * untouched if no packet is received. + * \returns number of bytes copied into buf + */ + int RecvFrom (uint8_t* buf, uint32_t size, uint32_t flags, + Address &fromAddress); protected: void NotifyCloseUnblocks (void); @@ -391,13 +536,13 @@ protected: }; /** - * \brief This class implements a tag that carries the source address - * of a packet across the receiving socket interface. + * \brief This class implements a tag that carries an address + * of a packet across the socket interface. */ -class SocketRxAddressTag : public Tag +class SocketAddressTag : public Tag { public: - SocketRxAddressTag (); + SocketAddressTag (); void SetAddress (Address addr); Address GetAddress (void) const; diff --git a/src/node/tcp-socket.h b/src/node/tcp-socket.h index 14ef39c5d..0a813b76b 100644 --- a/src/node/tcp-socket.h +++ b/src/node/tcp-socket.h @@ -58,11 +58,15 @@ public: virtual int ShutdownSend (void) = 0; virtual int ShutdownRecv (void) = 0; virtual int Connect (const Address &address) = 0; - virtual int Send (Ptr p) = 0; virtual uint32_t GetTxAvailable (void) const = 0; - virtual int SendTo (Ptr p, const Address &address) = 0; - virtual Ptr Recv (uint32_t maxSize, uint32_t flags) = 0; + virtual int Send (Ptr p, uint32_t flags) = 0; + virtual int SendTo (Ptr p, uint32_t flags, + const Address &toAddress) = 0; virtual uint32_t GetRxAvailable (void) const = 0; + virtual Ptr Recv (uint32_t maxSize, uint32_t flags) = 0; + virtual Ptr RecvFrom (uint32_t maxSize, uint32_t flags, + Address &fromAddress) = 0; + private: // Indirect the attribute setting and getting through private virtual methods diff --git a/src/node/udp-socket.h b/src/node/udp-socket.h index 61d3d2685..fa20b885d 100644 --- a/src/node/udp-socket.h +++ b/src/node/udp-socket.h @@ -57,11 +57,14 @@ public: virtual int ShutdownSend (void) = 0; virtual int ShutdownRecv (void) = 0; virtual int Connect (const Address &address) = 0; - virtual int Send (Ptr p) = 0; virtual uint32_t GetTxAvailable (void) const = 0; - virtual int SendTo (Ptr p, const Address &address) = 0; - virtual Ptr Recv (uint32_t maxSize, uint32_t flags) = 0; + virtual int Send (Ptr p, uint32_t flags) = 0; + virtual int SendTo (Ptr p, uint32_t flags, + const Address &toAddress) = 0; virtual uint32_t GetRxAvailable (void) const = 0; + virtual Ptr Recv (uint32_t maxSize, uint32_t flags) = 0; + virtual Ptr RecvFrom (uint32_t maxSize, uint32_t flags, + Address &fromAddress) = 0; private: // Indirect the attribute setting and getting through private virtual methods diff --git a/src/routing/olsr/olsr-agent-impl.cc b/src/routing/olsr/olsr-agent-impl.cc index b9a9ea7e4..cddaece12 100644 --- a/src/routing/olsr/olsr-agent-impl.cc +++ b/src/routing/olsr/olsr-agent-impl.cc @@ -305,7 +305,7 @@ AgentImpl::RecvOlsr (Ptr socket) Ptr receivedPacket; receivedPacket = socket->Recv (); - SocketRxAddressTag tag; + SocketAddressTag tag; bool found; found = receivedPacket->FindFirstMatchingTag (tag); NS_ASSERT (found); From 9ca1253956ee3b02bed7164975c90a113302d21c Mon Sep 17 00:00:00 2001 From: Tom Henderson Date: Mon, 9 Jun 2008 07:01:12 -0700 Subject: [PATCH 002/495] Change OLSR to use RecvFrom --- src/routing/olsr/olsr-agent-impl.cc | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/src/routing/olsr/olsr-agent-impl.cc b/src/routing/olsr/olsr-agent-impl.cc index cddaece12..851deef3d 100644 --- a/src/routing/olsr/olsr-agent-impl.cc +++ b/src/routing/olsr/olsr-agent-impl.cc @@ -303,13 +303,8 @@ void AgentImpl::RecvOlsr (Ptr socket) { Ptr receivedPacket; - receivedPacket = socket->Recv (); - - SocketAddressTag tag; - bool found; - found = receivedPacket->FindFirstMatchingTag (tag); - NS_ASSERT (found); - Address sourceAddress = tag.GetAddress (); + Address sourceAddress; + receivedPacket = socket->RecvFrom (sourceAddress); InetSocketAddress inetSourceAddr = InetSocketAddress::ConvertFrom (sourceAddress); Ipv4Address senderIfaceAddr = inetSourceAddr.GetIpv4 (); From aebdb9fbfd9c477e748b2e8af72e886eaf43906a Mon Sep 17 00:00:00 2001 From: Tom Henderson Date: Mon, 9 Jun 2008 20:42:31 -0700 Subject: [PATCH 003/495] Move other applications to RecvFrom () --- src/applications/packet-sink/packet-sink.cc | 9 ++------- src/applications/udp-echo/udp-echo-client.cc | 9 ++------- src/applications/udp-echo/udp-echo-server.cc | 9 ++------- 3 files changed, 6 insertions(+), 21 deletions(-) diff --git a/src/applications/packet-sink/packet-sink.cc b/src/applications/packet-sink/packet-sink.cc index 1b65bfa85..73dfda731 100644 --- a/src/applications/packet-sink/packet-sink.cc +++ b/src/applications/packet-sink/packet-sink.cc @@ -103,14 +103,9 @@ void PacketSink::StopApplication() // Called at time specified by Stop void PacketSink::HandleRead (Ptr socket) { Ptr packet; - while (packet = socket->Recv ()) + Address from; + while (packet = socket->RecvFrom (from)) { - SocketAddressTag tag; - bool found; - found = packet->FindFirstMatchingTag (tag); - NS_ASSERT (found); - Address from = tag.GetAddress (); - // XXX packet->RemoveTag (tag); if (InetSocketAddress::IsMatchingType (from)) { InetSocketAddress address = InetSocketAddress::ConvertFrom (from); diff --git a/src/applications/udp-echo/udp-echo-client.cc b/src/applications/udp-echo/udp-echo-client.cc index 9a1efc293..9580b7dbe 100644 --- a/src/applications/udp-echo/udp-echo-client.cc +++ b/src/applications/udp-echo/udp-echo-client.cc @@ -154,14 +154,9 @@ UdpEchoClient::HandleRead (Ptr socket) { NS_LOG_FUNCTION (this << socket); Ptr packet; - while (packet = socket->Recv ()) + Address from; + while (packet = socket->RecvFrom (from)) { - SocketAddressTag tag; - bool found; - found = packet->FindFirstMatchingTag (tag); - NS_ASSERT (found); - Address from = tag.GetAddress (); - // XXX packet->RemoveTag (tag); if (InetSocketAddress::IsMatchingType (from)) { InetSocketAddress address = InetSocketAddress::ConvertFrom (from); diff --git a/src/applications/udp-echo/udp-echo-server.cc b/src/applications/udp-echo/udp-echo-server.cc index f5bc4c93b..502673519 100644 --- a/src/applications/udp-echo/udp-echo-server.cc +++ b/src/applications/udp-echo/udp-echo-server.cc @@ -95,14 +95,9 @@ void UdpEchoServer::HandleRead (Ptr socket) { Ptr packet; - while (packet = socket->Recv ()) + Address from; + while (packet = socket->RecvFrom (from)) { - SocketAddressTag tag; - bool found; - found = packet->FindFirstMatchingTag (tag); - NS_ASSERT (found); - Address from = tag.GetAddress (); - // XXX packet->RemoveTag (tag); if (InetSocketAddress::IsMatchingType (from)) { InetSocketAddress address = InetSocketAddress::ConvertFrom (from); From cdb5cc083fc6a20a5d8b3ab964366d906595aad3 Mon Sep 17 00:00:00 2001 From: Tom Henderson Date: Thu, 12 Jun 2008 06:11:18 -0700 Subject: [PATCH 004/495] Doxygen for global routing --- src/routing/global-routing/global-routing.h | 79 +++++++++++++++++++++ 1 file changed, 79 insertions(+) create mode 100644 src/routing/global-routing/global-routing.h diff --git a/src/routing/global-routing/global-routing.h b/src/routing/global-routing/global-routing.h new file mode 100644 index 000000000..ad9851505 --- /dev/null +++ b/src/routing/global-routing/global-routing.h @@ -0,0 +1,79 @@ +/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ +/* + * Copyright 2008 University of Washington + * + * 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 + * + */ + +/** + * \ingroup routing + * \defgroup globalrouting Global Routing + * + * \section model Model + * + * ns-3 global routing performs pre-simulation static route computation + * on a layer-3 Ipv4 topology. The user API from the script level is + * fairly minimal; once a topology has been constructed and addresses + * assigned, the user may call ns3::GlobalRouteManager::PopulateRoutingTables() + * and the simulator will initialize the routing database and set up + * static unicast forwarding tables for each node. + * + * The model assumes that all nodes on an ns-3 channel are reachable to + * one another, regardless of whether the nodes can use the channel + * successfully (in the case of wireless). Therefore, this model + * should typically be used only on wired topologies. API does not + * yet exist to control the subset of a topology to which this global + * static routing is applied. + * + * This model also does not yet deal with the possible presence of + * layer-2 relays such as switches, bridges, and hubs, although ns-3 does + * not have such devices yet. + * + * \section api API and Usage + * + * Users must include ns3/global-route-manager.h header file. After the + * IPv4 topology has been built and addresses assigned, users call + * ns3::GlobalRouteManager::PopulateRoutingTables (), prior to the + * ns3::Simulator::Run() call. There are no other attributes or + * public methods that are typically called, or ways to parameterize + * the behavior. + * + * \section impl Implementation + * + * A singleton object, ns3::GlobalRouteManager, builds a global routing + * database of information about the topology, and executes a Dijkstra + * Shortest Path First (SPF) algorithm on the topology for each node, and + * stores the computed routes in each node's IPv4 forwarding table by + * making use of the routing API in class ns3::Ipv4. + * + * The nodes that export data are those that have had an ns3::GlobalRouter + * object aggregated to them. The ns3::GlobalRouter can be thought of + * as a per-node agent that exports topology information to the + * ns3::GlobalRouteManager. When it comes time to build the global + * routing database, the list of nodes is iterated and each node with + * an ns3::GlobalRouter object is asked to export routing information + * concerning the links to which it is attached. + * + * The format of the data exported conforms to the OSPFv2 standard + * (http://www.ietf.org/rfc/rfc2328.txt). In particular, the + * information is exported in the form of ns3::GlobalLSA objects that + * semantically match the Link State Advertisements of OSPF. + * + * By using a standard data format for reporting topology, existing + * OSPF route computation code can be reused, and that is what is done + * by the ns3::GlobalRouteManager. The main computation functions are + * ported from the quagga routing suite (http://www.quagga.net). + * + */ From cbc938e2bfcf7029c435a83c77876047cd2c2579 Mon Sep 17 00:00:00 2001 From: Tom Henderson Date: Thu, 12 Jun 2008 22:21:19 -0700 Subject: [PATCH 005/495] OLSR doxygen --- src/routing/olsr/olsr.h | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/src/routing/olsr/olsr.h b/src/routing/olsr/olsr.h index 1ba19c02d..0d5d6af30 100644 --- a/src/routing/olsr/olsr.h +++ b/src/routing/olsr/olsr.h @@ -23,6 +23,39 @@ #include "ns3/node-list.h" +/** + * \ingroup routing + * \defgroup olsr OLSR + * + * \section model Model + * + * This model implements the base specification of the Optimized + * Link State Routing (OLSR) protocol, which is a dynamic mobile ad hoc + * unicast routing protocol. It has been developed at the + * University of Murcia (Spain) by Francisco J. Ros for ns-2, and was + * ported to ns-3 by Gustavo Carneiro. + * + * Here is a summary of software's main features: + * - Compliant with core-OLSR (but the use of multiple interfaces which is currently not supported by NS2) as it is documented in RFC 3626 + * (http://www.ietf.org/rfc/rfc3626.txt). + * - Support for MAC layer feedback as described in RFC 3626. + * + * \section api API and Usage + * + * A helper class for OLSR has been written. After an IPv4 topology + * has been created and assigned IP addresses, the simulation script + * writer can call one of three overloaded functions with different scope + * to enable OLSR: ns3::OlsrHelper::Install (NodeContainer container); + * ns3::OlsrHelper::Install (Ptr node); + * or ns3::OlsrHelper::InstallAll (void); + * + * In addition, the behavior of OLSR can be modified by changing certain + * attributes. The method ns3::OlsrHelper::SetAgent () can be used + * to set OLSR attributes. These include HelloInterval, TcInterval, + * MidInterval, Willingness. Other parameters are defined as macros + * in olsr-agent-impl.cc. + */ + namespace ns3 { /** From 1e4c17bc9fbd7aeef65e9a8d5414ad694d8cb15e Mon Sep 17 00:00:00 2001 From: Tom Henderson Date: Fri, 13 Jun 2008 06:32:54 -0700 Subject: [PATCH 006/495] doxygen for applications --- src/applications/onoff/onoff-application.h | 17 ++++++++++++++- src/applications/packet-sink/packet-sink.h | 15 +++++++++++++ src/applications/udp-echo/udp-echo-client.h | 1 + src/applications/udp-echo/udp-echo-server.h | 6 ++++++ src/node/application.h | 24 ++++++++++++--------- 5 files changed, 52 insertions(+), 11 deletions(-) diff --git a/src/applications/onoff/onoff-application.h b/src/applications/onoff/onoff-application.h index ac79ff18b..58047ee6b 100644 --- a/src/applications/onoff/onoff-application.h +++ b/src/applications/onoff/onoff-application.h @@ -40,10 +40,25 @@ class RandomVariable; class Socket; /** + * \ingroup applications + * \defgroup onoff OnOffApplication + * + * This traffic generator follows an On/Off pattern: after + * Application::StartApplication + * is called, "On" and "Off" states alternate. The duration of each of + * these states is determined with the onTime and the offTime random + * variables. During the "Off" state, no traffic is generated. + * During the "On" state, cbr traffic is generated. This cbr traffic is + * characterized by the specified "data rate" and "packet size". + */ + /** + * \ingroup onoff + * * \brief Generate traffic to a single destination according to an * OnOff pattern. * - * This traffic follows an On/Off pattern: after Application::StartApplication + * This traffic generator follows an On/Off pattern: after + * Application::StartApplication * is called, "On" and "Off" states alternate. The duration of each of * these states is determined with the onTime and the offTime random * variables. During the "Off" state, no traffic is generated. diff --git a/src/applications/packet-sink/packet-sink.h b/src/applications/packet-sink/packet-sink.h index 638309aad..20781a79e 100644 --- a/src/applications/packet-sink/packet-sink.h +++ b/src/applications/packet-sink/packet-sink.h @@ -34,6 +34,21 @@ class Socket; class Packet; /** + * \ingroup applications + * \defgroup packetsink PacketSink + * + * This application was written to complement OnOffApplication, but it + * is more general so a PacketSink name was selected. Functionally it is + * important to use in multicast situations, so that reception of the layer-2 + * multicast frames of interest are enabled, but it is also useful for + * unicast as an example of how you can write something simple to receive + * packets at the application layer. Also, if an IP stack generates + * ICMP Port Unreachable errors, receiving applications will be needed. + */ + +/** + * \ingroup packetsink + * * \brief Receive and consume traffic generated to an IP address and port * * This application was written to complement OnOffApplication, but it diff --git a/src/applications/udp-echo/udp-echo-client.h b/src/applications/udp-echo/udp-echo-client.h index bfb1c3fcf..bea207918 100644 --- a/src/applications/udp-echo/udp-echo-client.h +++ b/src/applications/udp-echo/udp-echo-client.h @@ -30,6 +30,7 @@ class Socket; class Packet; /** + * \ingroup udpecho * \brief A Udp Echo client * * Every packet sent should be returned by the server and received here. diff --git a/src/applications/udp-echo/udp-echo-server.h b/src/applications/udp-echo/udp-echo-server.h index 4e2b09fce..7715761c3 100644 --- a/src/applications/udp-echo/udp-echo-server.h +++ b/src/applications/udp-echo/udp-echo-server.h @@ -30,6 +30,12 @@ class Socket; class Packet; /** + * \ingroup applications + * \defgroup udpecho UdpEcho + */ + +/** + * \ingroup udpecho * \brief A Udp Echo server * * Every packet received is sent back. diff --git a/src/node/application.h b/src/node/application.h index 1fb243691..bb706cd4f 100644 --- a/src/node/application.h +++ b/src/node/application.h @@ -33,17 +33,13 @@ class Node; class RandomVariable; /** - * \ingroup node - * \defgroup application Application - */ -/** - * \ingroup application - * \brief The base class for all ns3 applications + * \addtogroup applications Applications + * + * Class ns3::Application can be used as a base class for ns3 applications. + * Applications are associated with individual nodes. Each node + * holds a list of references (smart pointers) to its applications. * - * Class Application is the base class for all ns3 applications. - * Applications are associated with individual nodes. - * - * Conceptually, an application has zero or more Socket + * Conceptually, an application has zero or more ns3::Socket * objects associated with it, that are created using the Socket * creation API of the Kernel capability. The Socket object * API is modeled after the @@ -53,6 +49,14 @@ class RandomVariable; * in ns3. A set of "upcalls" are defined that will be called when * the previous blocking call would normally exit. THis is documented * in more detail Socket class in socket.h. + * + * The main purpose of the base class application public API is to + * provide a uniform way to start and stop applications. + */ + + /** + * \brief The base class for all ns3 applications + * */ class Application : public Object { From 8ae203ce50b5a59dbf7ce2f6561cba8c00d30f6a Mon Sep 17 00:00:00 2001 From: "Gustavo J. A. M. Carneiro" Date: Fri, 13 Jun 2008 15:35:07 +0100 Subject: [PATCH 007/495] Correct the OLSR documentation; remove dead API declarations and source file. --- src/helper/olsr-helper.h | 15 ++++++++++ src/routing/olsr/olsr.cc | 41 -------------------------- src/routing/olsr/olsr.h | 62 +++++++--------------------------------- 3 files changed, 26 insertions(+), 92 deletions(-) delete mode 100644 src/routing/olsr/olsr.cc diff --git a/src/helper/olsr-helper.h b/src/helper/olsr-helper.h index b901ab9d8..f481fe110 100644 --- a/src/helper/olsr-helper.h +++ b/src/helper/olsr-helper.h @@ -26,11 +26,17 @@ namespace ns3 { +/** + * \brief Helper class that adds OLSR routing to nodes. + */ class OlsrHelper { public: OlsrHelper (); + /** + * \brief Set default OLSR routing agent parameters + */ void SetAgent (std::string tid, std::string n0 = "", const AttributeValue &v0 = EmptyAttributeValue (), std::string n1 = "", const AttributeValue &v2 = EmptyAttributeValue (), @@ -41,8 +47,17 @@ public: std::string n6 = "", const AttributeValue &v6 = EmptyAttributeValue (), std::string n7 = "", const AttributeValue &v7 = EmptyAttributeValue ()); + /** + * \brief Enable OLSR routing for a set of nodes + */ void Install (NodeContainer container); + /** + * \brief Enable OLSR routing for a single node + */ void Install (Ptr node); + /** + * \brief Enable OLSR routing for all nodes + */ void InstallAll (void); private: ObjectFactory m_agentFactory; diff --git a/src/routing/olsr/olsr.cc b/src/routing/olsr/olsr.cc deleted file mode 100644 index 932629743..000000000 --- a/src/routing/olsr/olsr.cc +++ /dev/null @@ -1,41 +0,0 @@ -/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */ -/* - * Copyright (c) 2007 INESC Porto - * - * 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 - * - * Author: Gustavo J. A. M. Carneiro - */ - -#include "olsr-agent.h" -#include "olsr.h" - -namespace ns3 { namespace olsr { - - -void -EnableAllNodes (void) -{ - EnableNodes (NodeList::Begin (), NodeList::End ()); -} - -void -EnableNode (Ptr node) -{ - olsr::Agent::CreateDefault (node)->Start (); -} - - -}} // namespace ns3, olsr - diff --git a/src/routing/olsr/olsr.h b/src/routing/olsr/olsr.h index 0d5d6af30..f2dbb7830 100644 --- a/src/routing/olsr/olsr.h +++ b/src/routing/olsr/olsr.h @@ -21,8 +21,6 @@ #ifndef OLSR_H #define OLSR_H -#include "ns3/node-list.h" - /** * \ingroup routing * \defgroup olsr OLSR @@ -32,22 +30,23 @@ * This model implements the base specification of the Optimized * Link State Routing (OLSR) protocol, which is a dynamic mobile ad hoc * unicast routing protocol. It has been developed at the - * University of Murcia (Spain) by Francisco J. Ros for ns-2, and was - * ported to ns-3 by Gustavo Carneiro. + * University of Murcia (Spain) by Francisco J. Ros for NS-2, and was + * ported to NS-3 by Gustavo Carneiro at INESC Porto (Portugal). * * Here is a summary of software's main features: - * - Compliant with core-OLSR (but the use of multiple interfaces which is currently not supported by NS2) as it is documented in RFC 3626 - * (http://www.ietf.org/rfc/rfc3626.txt). - * - Support for MAC layer feedback as described in RFC 3626. + * - Mostly compliant with OLSR as documented in RFC 3626 (http://www.ietf.org/rfc/rfc3626.txt), with the following differences: + * - The use of multiple interfaces was not supported by the NS-2 version, but is supported in NS-3; + * - Unlike the NS-2 version, does not yet support MAC layer feedback as described in RFC 3626; + * - HNA (Host/Network Association) messages are almost-but-not-quite supported in this version. * * \section api API and Usage * * A helper class for OLSR has been written. After an IPv4 topology - * has been created and assigned IP addresses, the simulation script - * writer can call one of three overloaded functions with different scope - * to enable OLSR: ns3::OlsrHelper::Install (NodeContainer container); - * ns3::OlsrHelper::Install (Ptr node); - * or ns3::OlsrHelper::InstallAll (void); + * has been created and unique IP addresses assigned to each node, the + * simulation script writer can call one of three overloaded functions + * with different scope to enable OLSR: ns3::OlsrHelper::Install + * (NodeContainer container); ns3::OlsrHelper::Install (Ptr + * node); or ns3::OlsrHelper::InstallAll (void); * * In addition, the behavior of OLSR can be modified by changing certain * attributes. The method ns3::OlsrHelper::SetAgent () can be used @@ -56,44 +55,5 @@ * in olsr-agent-impl.cc. */ -namespace ns3 -{ - /** - * \namespace ns3::olsr - * \brief Includes a set of utility functions to enable OLSR on - * certain nodes with default parameters. For finer grained control - * of OLSR parameters, see OlsrAgent. - */ - namespace olsr - { - /// \brief Start the OLSR routing agent on all nodes - void EnableAllNodes (void); - - /// \brief Start the OLSR routing agent on a given list of nodes - template - void EnableNodes (InputIterator begin, InputIterator end); - - /// \brief Start the OLSR routing agent on the given node - void EnableNode (Ptr node); - } -} - - -// implementation -namespace ns3 -{ - namespace olsr - { - template - void EnableNodes (InputIterator begin, InputIterator end) - { - for (InputIterator i = begin; i != end; i++) - { - EnableNode (*i); - } - } - } -} - #endif /* OLSR_H */ From 9ccd6dadcb238a76b285251c0376cca982629c65 Mon Sep 17 00:00:00 2001 From: Raj Bhattacharjea Date: Fri, 13 Jun 2008 16:47:07 -0400 Subject: [PATCH 008/495] Update the internet-stack documentation --- src/internet-stack/ipv4-end-point-demux.h | 10 ++++++++++ src/internet-stack/ipv4-end-point.h | 11 +++++++++++ src/internet-stack/ipv4-interface.h | 1 + src/internet-stack/ipv4-l3-protocol.h | 3 +++ src/internet-stack/ipv4-l4-demux.h | 3 +++ src/internet-stack/ipv4-l4-protocol.h | 6 +++--- src/internet-stack/pending-data.h | 2 +- src/internet-stack/tcp-header.h | 8 ++++++++ src/internet-stack/tcp-l4-protocol.h | 11 +++++++++-- src/internet-stack/tcp-socket-factory-impl.h | 6 ++++-- src/internet-stack/tcp-socket-impl.h | 14 ++++++++++++++ src/internet-stack/udp-header.h | 4 ++++ src/internet-stack/udp-socket-impl.h | 7 +++++++ 13 files changed, 78 insertions(+), 8 deletions(-) diff --git a/src/internet-stack/ipv4-end-point-demux.h b/src/internet-stack/ipv4-end-point-demux.h index 271325164..61e580e3c 100644 --- a/src/internet-stack/ipv4-end-point-demux.h +++ b/src/internet-stack/ipv4-end-point-demux.h @@ -30,6 +30,16 @@ namespace ns3 { class Ipv4EndPoint; +/** + * \brief Demultiplexes packets to various transport layer endpoints + * + * This class serves as a lookup table to match partial or full information + * about a four-tuple to an ns3::Ipv4EndPoint. It internally contains a list + * of endpoints, and has APIs to add and find endpoints in this demux. This + * code is shared in common to TCP and UDP protocols in ns3. This demux + * sits between ns3's layer four and the socket layer + */ + class Ipv4EndPointDemux { public: typedef std::list EndPoints; diff --git a/src/internet-stack/ipv4-end-point.h b/src/internet-stack/ipv4-end-point.h index 35f0f04bc..99666f73f 100644 --- a/src/internet-stack/ipv4-end-point.h +++ b/src/internet-stack/ipv4-end-point.h @@ -30,6 +30,17 @@ namespace ns3 { class Header; class Packet; +/** + * \brief A representation of an internet endpoint/connection + * + * This class provides an internet four-tuple (source and destination ports + * and addresses). These are used in the ns3::Ipv4EndPointDemux as targets + * of lookups. The class also has a callback for notification to higher + * layers that a packet from a lower layer was received. In the ns3 + * internet-stack, these notifications are automatically registered to be + * received by the corresponding socket. + */ + class Ipv4EndPoint { public: Ipv4EndPoint (Ipv4Address address, uint16_t port); diff --git a/src/internet-stack/ipv4-interface.h b/src/internet-stack/ipv4-interface.h index 5a1e94df5..74007b09e 100644 --- a/src/internet-stack/ipv4-interface.h +++ b/src/internet-stack/ipv4-interface.h @@ -58,6 +58,7 @@ class Packet; * * Subclasses must implement the two methods: * - Ipv4Interface::SendTo + * - Ipv4Interface::GetDevice */ class Ipv4Interface : public Object { diff --git a/src/internet-stack/ipv4-l3-protocol.h b/src/internet-stack/ipv4-l3-protocol.h index 40f0be5bd..7b2879aaf 100644 --- a/src/internet-stack/ipv4-l3-protocol.h +++ b/src/internet-stack/ipv4-l3-protocol.h @@ -43,6 +43,9 @@ class Node; /** * \brief Implement the Ipv4 layer. + * + * This is the actual implementation of IP. It contains APIs to send and + * receive packets at the IP layer, as well as APIs for IP routing. */ class Ipv4L3Protocol : public Object { diff --git a/src/internet-stack/ipv4-l4-demux.h b/src/internet-stack/ipv4-l4-demux.h index fa04f8a37..54ceda210 100644 --- a/src/internet-stack/ipv4-l4-demux.h +++ b/src/internet-stack/ipv4-l4-demux.h @@ -35,6 +35,9 @@ class Node; /** * \brief L4 Ipv4 Demux + * + * This class demultiplexes IP datagrams to the correct layer four protocol + * object. This demux sits between IP and layer 4. */ class Ipv4L4Demux : public Object { diff --git a/src/internet-stack/ipv4-l4-protocol.h b/src/internet-stack/ipv4-l4-protocol.h index e7f2407ad..1a8595a5b 100644 --- a/src/internet-stack/ipv4-l4-protocol.h +++ b/src/internet-stack/ipv4-l4-protocol.h @@ -33,10 +33,10 @@ class Packet; class Ipv4Address; /** - * \brief L4 Protocol base class + * \brief L4 Protocol abstract base class * - * If you want to implement a new L4 protocol, all you have to do is - * implement a subclass of this base class and add it to an L4Demux. + * This is an abstract base class for layer four protocols which use IPv4 as + * the network layer. */ class Ipv4L4Protocol : public Object { diff --git a/src/internet-stack/pending-data.h b/src/internet-stack/pending-data.h index 7cdbe6495..eeba9ad69 100644 --- a/src/internet-stack/pending-data.h +++ b/src/internet-stack/pending-data.h @@ -32,7 +32,7 @@ namespace ns3 { class Packet; -//Doc:ClassXRef + class PendingData { public: PendingData (); diff --git a/src/internet-stack/tcp-header.h b/src/internet-stack/tcp-header.h index e676287f6..c1ba93877 100644 --- a/src/internet-stack/tcp-header.h +++ b/src/internet-stack/tcp-header.h @@ -30,6 +30,14 @@ namespace ns3 { +/** + * \brief Header for the Transmission Control Protocol + * + * This class has fields corresponding to those in a network TCP header + * (port numbers, sequence and acknowledgement numbers, flags, etc) as well + * as methods for serialization to and deserialization from a byte buffer. + */ + class TcpHeader : public Header { public: diff --git a/src/internet-stack/tcp-l4-protocol.h b/src/internet-stack/tcp-l4-protocol.h index 4555b004e..9092a7e3b 100644 --- a/src/internet-stack/tcp-l4-protocol.h +++ b/src/internet-stack/tcp-l4-protocol.h @@ -39,9 +39,16 @@ namespace ns3 { class Node; class Socket; class TcpHeader; + /** - * \brief Implementation of the TCP protocol - */ + * \brief A layer between the sockets interface and IP + * + * This class allocates "endpoint" objects (ns3::Ipv4EndPoint) for TCP, + * and SHOULD checksum packets its receives from the socket layer going down + * the stack , but currently checksumming is disabled. It also recieves + * packets from IP, and forwards them up to the endpoints. +*/ + class TcpL4Protocol : public Ipv4L4Protocol { public: static TypeId GetTypeId (void); diff --git a/src/internet-stack/tcp-socket-factory-impl.h b/src/internet-stack/tcp-socket-factory-impl.h index 673010f9f..acef1e2d9 100644 --- a/src/internet-stack/tcp-socket-factory-impl.h +++ b/src/internet-stack/tcp-socket-factory-impl.h @@ -35,11 +35,13 @@ class TcpL4Protocol; * \ingroup Tcp * \section Tcp Overview * - * The TCP code in ns3::InternetNode is ported from the + * The TCP code in ns3's internet stack is ported from the * * Georgia Tech Network Simulator (GTNetS). - * + * * Most of the logic is in class ns3::TcpSocketImpl. + * This class serves to create sockets of the TcpSocketImpl + * type. That is, it creates sockets which use the GTNetS Tahoe code. */ class TcpSocketFactoryImpl : public TcpSocketFactory { diff --git a/src/internet-stack/tcp-socket-impl.h b/src/internet-stack/tcp-socket-impl.h index 8f1f832f5..dd52f440a 100644 --- a/src/internet-stack/tcp-socket-impl.h +++ b/src/internet-stack/tcp-socket-impl.h @@ -42,6 +42,20 @@ class Packet; class TcpL4Protocol; class TcpHeader; +/** + * \ingroup socket + * + * \brief An implementation of a stream socket using TCP. + * + * This class contains an implementation of TCP Tahoe, as well as a sockets + * interface for talking to TCP. Features include connection orientation, + * reliability through cumulative acknowledgements, congestion and flow + * control. Finite send/receive buffer semantics are modeled. + * + * Asynchronous callbacks to provide notifications to higher layers that a + * protocol event has occured, such as space freeing up in the send buffer + * or new data arriving in the receive buffer. + */ class TcpSocketImpl : public TcpSocket { public: diff --git a/src/internet-stack/udp-header.h b/src/internet-stack/udp-header.h index a7bbf23e2..d2ab5e73a 100644 --- a/src/internet-stack/udp-header.h +++ b/src/internet-stack/udp-header.h @@ -29,6 +29,10 @@ namespace ns3 { /** * \brief Packet header for UDP packets + * + * This class has fields corresponding to those in a network UDP header + * (port numbers, payload size, checksum) as well as methods for serialization + * to and deserialization from a byte buffer. */ class UdpHeader : public Header { diff --git a/src/internet-stack/udp-socket-impl.h b/src/internet-stack/udp-socket-impl.h index f7b185215..ae713e9a3 100644 --- a/src/internet-stack/udp-socket-impl.h +++ b/src/internet-stack/udp-socket-impl.h @@ -36,6 +36,13 @@ class Node; class Packet; class UdpL4Protocol; +/** + * \brief A sockets interface to UDP + * + * This class subclasses ns3::UdpSocket, and provides a socket interface + * to ns3's implementation of UDP. + */ + class UdpSocketImpl : public UdpSocket { public: From 1aef4543ccb3a6e0bc1e51a903898ff06e2bfd04 Mon Sep 17 00:00:00 2001 From: Raj Bhattacharjea Date: Fri, 13 Jun 2008 17:19:53 -0700 Subject: [PATCH 009/495] bug 181: Normal Variable Infinite Value & Bounds --- src/core/random-variable.cc | 26 ++++++++++++++++++++++---- src/core/random-variable.h | 26 +++++++++++++++++++++----- 2 files changed, 43 insertions(+), 9 deletions(-) diff --git a/src/core/random-variable.cc b/src/core/random-variable.cc index 336a2a119..778cb2e45 100644 --- a/src/core/random-variable.cc +++ b/src/core/random-variable.cc @@ -1043,11 +1043,21 @@ double NormalVariableImpl::GetValue() { // Got good pair double y = sqrt((-2 * log(w))/w); m_next = m_mean + v2 * y * sqrt(m_variance); - if (fabs(m_next) > m_bound) m_next = m_bound * (m_next)/fabs(m_next); - m_nextValid = true; + //if next is in bounds, it is valid + m_nextValid = fabs(m_next-m_mean) <= m_bound; double x1 = m_mean + v1 * y * sqrt(m_variance); - if (fabs(x1) > m_bound) x1 = m_bound * (x1)/fabs(x1); - return x1; + //if x1 is in bounds, return it + if (fabs(x1-m_mean) <= m_bound) + { + return x1; + } + //otherwise try and return m_next if it is valid + else if (m_nextValid) + { + m_nextValid = false; + return m_next; + } + //otherwise, just run this loop again } } } @@ -1094,10 +1104,18 @@ double NormalVariableImpl::GetSingleValue(double m, double v, double b) NormalVariable::NormalVariable() : RandomVariable (NormalVariableImpl ()) {} +NormalVariable::NormalVariable(double m, double v) + : RandomVariable (NormalVariableImpl (m, v)) +{} NormalVariable::NormalVariable(double m, double v, double b) : RandomVariable (NormalVariableImpl (m, v, b)) {} double +NormalVariable::GetSingleValue(double m, double v) +{ + return NormalVariableImpl::GetSingleValue (m, v); +} +double NormalVariable::GetSingleValue(double m, double v, double b) { return NormalVariableImpl::GetSingleValue (m, v, b); diff --git a/src/core/random-variable.h b/src/core/random-variable.h index 4abb36bdb..a311a2bbc 100644 --- a/src/core/random-variable.h +++ b/src/core/random-variable.h @@ -490,27 +490,43 @@ public: class NormalVariable : public RandomVariable { public: - static const double INFINITE_VALUE; /** * Constructs an normal random variable with a mean * value of 0 and variance of 1. */ NormalVariable(); + /** + * \brief Construct a normal random variable with specified mean and variance. + * \param m Mean value + * \param v Variance + */ + NormalVariable(double m, double v); + /** * \brief Construct a normal random variable with specified mean and variance * \param m Mean value * \param v Variance - * \param b Bound. The NormalVariable is bounded within +-bound. + * \param b Bound. The NormalVariable is bounded symetrically about the mean + * [mean-bound,mean+bound] */ - NormalVariable(double m, double v, double b = INFINITE_VALUE); + NormalVariable(double m, double v, double b); + /** * \param m Mean value * \param v Variance - * \param b Bound. The NormalVariable is bounded within +-bound. + * \return A random number from a distribution specified by m, and v. + */ + static double GetSingleValue(double m, double v); + + /** + * \param m Mean value + * \param v Variance + * \param b Bound. The NormalVariable is bounded symetrically about the mean + * [mean-bound,mean+bound] * \return A random number from a distribution specified by m,v, and b. */ - static double GetSingleValue(double m, double v, double b = INFINITE_VALUE); + static double GetSingleValue(double m, double v, double b); }; /** From da05aa1327cc582cf20dd329a8017bfc22156682 Mon Sep 17 00:00:00 2001 From: Tom Henderson Date: Sun, 15 Jun 2008 21:27:13 -0700 Subject: [PATCH 010/495] split out manual sections from tutorial --- doc/tutorial/Makefile | 4 +- doc/tutorial/callbacks.texi | 330 ----- doc/tutorial/figures/buffer.dia | 1623 --------------------- doc/tutorial/figures/packet.obj | 227 --- doc/tutorial/figures/sockets-overview.dia | Bin 2222 -> 0 bytes doc/tutorial/packets.texi | 620 -------- doc/tutorial/routing.texi | 373 ----- doc/tutorial/sockets.texi | 243 --- doc/tutorial/tutorial.texi | 22 - 9 files changed, 2 insertions(+), 3440 deletions(-) delete mode 100644 doc/tutorial/callbacks.texi delete mode 100644 doc/tutorial/figures/buffer.dia delete mode 100644 doc/tutorial/figures/packet.obj delete mode 100644 doc/tutorial/figures/sockets-overview.dia delete mode 100644 doc/tutorial/packets.texi delete mode 100644 doc/tutorial/routing.texi delete mode 100644 doc/tutorial/sockets.texi diff --git a/doc/tutorial/Makefile b/doc/tutorial/Makefile index f0b2f4f8f..58857b0dd 100644 --- a/doc/tutorial/Makefile +++ b/doc/tutorial/Makefile @@ -7,8 +7,8 @@ CONVERT = convert CSS = --css-include=tutorial.css SPLIT = --split section -DIA_SOURCES = buffer.dia pp.dia dumbbell.dia star.dia sockets-overview.dia -TGIF_SOURCES = packet.obj helpers.obj +DIA_SOURCES = pp.dia dumbbell.dia star.dia +TGIF_SOURCES = helpers.obj DIA_EPS = ${DIA_SOURCES:.dia=.eps} DIA_PNG = ${DIA_SOURCES:.dia=.png} diff --git a/doc/tutorial/callbacks.texi b/doc/tutorial/callbacks.texi deleted file mode 100644 index 377689975..000000000 --- a/doc/tutorial/callbacks.texi +++ /dev/null @@ -1,330 +0,0 @@ -@node ns-3 Callbacks -@chapter ns-3 Callbacks - -Some new users to @command{ns-3} are unfamiliar with an extensively used -programming idiom used throughout the code: the ``ns-3 callback''. This -chapter provides some motivation on the callback, guidance on how to use -it, and details on its implementation. - -@menu -* Motivation:: -* Using the Callback API:: -* Callback locations in ns-3:: -* Implementation details:: -@end menu - -@node Motivation -@section Motivation - -Consider that you have two simulation models A and B, and you wish -to have them pass information between them during the simulation. One -way that you can do that is that you can make A and B each explicitly -knowledgable about the other, so that they can invoke methods on each -other. - -@verbatim -class A { -public: - void ReceiveInput ( // parameters ); - ... -} - -(in another source file:) - -class B { -public: - void ReceiveInput ( // parameters); - void DoSomething (void); - ... - -private: - A* a_instance; // pointer to an A -} - -void -B::DoSomething() -{ - // Tell a_instance that something happened - a_instance->ReceiveInput ( // parameters); - ... -} -@end verbatim - -This certainly works, but it has the drawback that it introduces a -dependency on A and B to know about the other at compile time (this -makes it harder to have independent compilation units in the simulator) -and is not generalized; if in a later usage scenario, B needs to talk -to a completely different C object, the source code for B needs to be -changed to add a ``c_instance'' and so forth. It is easy to see that -this is a brute force mechanism of communication that can lead to -programming cruft in the models. - -This is not to say that objects should not know about one another -if there is a hard dependency between them, but that often the model -can be made more flexible if its interactions are less constrained at -compile time. - -This is not an abstract problem for network simulation research, -but rather it has been a source of problems in previous simulators, -when researchers want to extend or modify the system to do different -things (as they are apt to do in research). Consider, for example, -a user who wants to add an IPsec security protocol sublayer -between TCP and IP: -@verbatim ------------- ----------- -| TCP | | TCP | ------------- ----------- - | becomes -> | ------------ ----------- -| IP | | IPsec | ------------ ----------- - | - ----------- - | IP | - ----------- -@end verbatim -If the simulator has -made assumptions, and hard coded into the code, that IP always talks -to a transport protocol above, the user may be forced to hack the -system to get the desired interconnections. - -An alternative that provides this flexibility is to use a level of -indirection that is commonly known in programming as a callback. -A callback function is not invoked explicitly by the caller but is -rather delegated to another function that receives the callback -function's address and can call it. - -You may be familiar with function pointers in C or C++; these can -be used to implement callbacks. For more information on introductory -callbacks, an online reference is: -@uref{http://www.inquiry.com/techtips/cpp_pro/10min/10min0300.asp,,Declaring Function Pointers and Implementing Callbacks} and -@uref{http://en.wikipedia.org/wiki/Callback_(computer_science),,Callback (computer science)-- Wikipedia}. - -The callback API in @command{ns-3} is designed to minimize the overall -coupling between various pieces of of the simulator -by making each module depend on the callback API -itself rather than depend on other modules. It acts as a sort of -third-party to which work is delegated and which forwards this -work to the proper target module. This callback API, being based -on C++ templates, -is type-safe; that is, it performs static type checks to enforce -proper signature compatibility between callers and callees. It -is therefore more type-safe to use than traditional function -pointers, but the syntax may look imposing at first. This section -is designed to walk you through the callback system so that you -can be comfortable using it in @command{ns-3}. - -@node Using the Callback API -@section Using the Callback API - -The Callback API is fairly minimal, providing only two services: -@itemize @bullet -@item callback type declaration: a way to declare a type of callback -with a given signature, and, -@item callback instantiation: a way to instantiate a -template-generated forwarding callback which can forward any calls -to another C++ class member method or C++ function. -@end itemize - -This is best observed via walking through an example, based on -@code{samples/main-callback.cc}. - -@node Using the Callback API with static functions -@subsection Using the Callback API with static functions - -Consider a function: -@verbatim -static double -CbOne (double a, double b) -{ - std::cout << "invoke cbOne a=" << a << ", b=" << b << std::endl; - return a; -} -@end verbatim - -Consider also the following main program snippett: -@verbatim -int main (int argc, char *argv[]) -{ - // return type: double - // first arg type: double - // second arg type: double - Callback one; -} -@end verbatim - -This class template Callback implements what is known as the Functor -Design Pattern. It is used to declare the type of a callback. It contains -one mandatory argument (the return type of the function to be assigned -to this callback) and up to five optional arguments, which each specify -the type of the arguments (if your function has more than five arguments, -then this can be handled by extending the callback implementation). - -So in the above, we have a declared a callback named "one" that will -eventually hold a function pointer. The function that it will hold -must return double and must support two double arguments. If one -tries to pass a function whose signature does not match the declared -callback, the compilation will fail. - -Now, we need to tie together this callback instance and the actual -target function (CbOne). Notice above that CbOne has the same function -signature types as the callback-- this is important. We can -pass in any such properly-typed function to this callback. Let's -look at this more closely: -@verbatim -static double CbOne (double a, double b) {} - ^ ^ ^ - | ---| ------| - | | | -Callback one; -@end verbatim -You can only bind a function to a callback if they have the matching -signature. The first template argument is the return type, and the -additional template arguments are the types of the arguments of -the function signature. - -Now, let's bind our callback "one" to the function that matches its -signature: -@verbatim - // build callback instance which points to cbOne function - one = MakeCallback (&CbOne); -@end verbatim - -Then, later in the program, if the callback is to be used, it can be -used as follows: -@verbatim -// this is not a null callback - NS_ASSERT (!one.IsNull ()); - // invoke cbOne function through callback instance - double retOne; - retOne = one (10.0, 20.0); -@end verbatim - -The check @code{IsNull()} ensures that the callback is not null; that there -is a function to call behind this callback. Then, @code{one()} returns the -same result as if @code{CbOne()} had been called directly. - - -@node Using the Callback API with member functions -@subsection Using the Callback API with member functions - -Generally, you will not be calling static functions but instead -public member functions of an object. In this case, an extra -argument is needed to the MakeCallback function, to tell the system -on which object the function should be invoked. Consider this example, -also from main-callback.cc: - -@verbatim -class MyCb { -public: - int CbTwo (double a) { - std::cout << "invoke cbTwo a=" << a << std::endl; - return -5; - } -}; - -int main () -{ - ... - // return type: int - // first arg type: double - Callback two; - MyCb cb; - // build callback instance which points to MyCb::cbTwo - two = MakeCallback (&MyCb::CbTwo, &cb); - ... -} -@end verbatim - -Here, we pass a (raw) pointer to the @code{MakeCallback<>} function, -that says, when @code{two ()} is invoked, to call the @code{CbTwo} function -on the object pointed to by @code{&cb}. - -A variation of this is used when objects are referred to by ns-3 smart -pointers. The MakeCallback API takes a raw pointer, so we need to -call @code{PeekPointer ()} to obtain this raw pointer. So the example -above would look like: - -@verbatim -class MyCb : public Object { -public: - int CbTwo (double a) { - std::cout << "invoke cbTwo a=" << a << std::endl; - return -5; - } -}; - -int main () -{ - ... - // return type: int - // first arg type: double - Callback two; - Ptr cb = CreateObject (); - // build callback instance which points to MyCb::cbTwo - two = MakeCallback (&MyCb::CbTwo, PeekPointer (cb)); - ... -} -@end verbatim - -@node Building Null Callbacks -@subsection Building Null Callbacks - -It is possible for callbacks to be null; hence it may be wise to -check before using them. There is a special construct for a null -callback, which is preferable to simply passing "0" as an argument; -it is the @code{MakeNullCallback<>} construct: -@verbatim - two = MakeNullCallback (); - // invoking a null callback is just like - // invoking a null function pointer: - // it will crash at runtime. - //int retTwoNull = two (20.0); - NS_ASSERT (two.IsNull ()); -@end verbatim - -@node Callback locations in ns-3 -@section Callback locations in @command{ns-3} - -Where are callbacks frequently used in @command{ns-3}? Here are some of the -more visible ones to typical users: - -@subsection Socket API -@subsection Layer-2/Layer-3 API -@subsection Tracing subsystem -@subsection Routing -Route Reply - -@node Implementation details -@section Implementation details - -This section is advanced explanation for C++ experts interested in -the implementation, and may be skipped by most users. - -This code was originally written based on the techniques described -@uref{http://www.codeproject.com/cpp/TTLFunction.asp,,here}. -It was subsequently rewritten to follow the architecture -outlined in -@uref{http://www.amazon.com/Modern-C\%2B\%2B-Design-Programming-Patterns/dp/0201704315/ref=pd_bbs_sr_1/102-0157303-1900156?ie=UTF8\&s=books\&qid=1187982662\&sr=1-1,,Modern C++ Design: Generic Programming and Design Patterns Applied-- Alexandrescu}, chapter 5, "Generalized Functors". - -This code uses: -@itemize @bullet -@item default template parameters to saves users from having to -specify empty parameters when the number of parameters -is smaller than the maximum supported number -@item the pimpl idiom: the Callback class is passed around by -value and delegates the crux of the work to its pimpl pointer. -@item two pimpl implementations which derive from CallbackImpl -FunctorCallbackImpl can be used with any functor-type -while MemPtrCallbackImpl can be used with pointers to -member functions. -@item a reference list implementation to implement the Callback's -value semantics. -@end itemize - -This code most notably departs from the Alexandrescu -implementation in that it does not use type lists to specify -and pass around the types of the callback arguments. -Of course, it also does not use copy-destruction semantics -and relies on a reference list rather than autoPtr to hold -the pointer. diff --git a/doc/tutorial/figures/buffer.dia b/doc/tutorial/figures/buffer.dia deleted file mode 100644 index b1868f7f4..000000000 --- a/doc/tutorial/figures/buffer.dia +++ /dev/null @@ -1,1623 +0,0 @@ - - - - - - - - - - - - - #A4# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #Count# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #Size# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #Initial Start# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #Dirty Start# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #Unused Area# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #Dirty Size# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #Dirty Area# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #Virtual Zero Area# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #Unused Area# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #Data# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #Zero Area Size# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #Used start# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #Used Size# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #Data# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #Zero Area Size# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #Used start# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #Used Size# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #Used# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #Used# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #Virtual Zero Area# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #Buffer# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #BufferData# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #Buffer# - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/doc/tutorial/figures/packet.obj b/doc/tutorial/figures/packet.obj deleted file mode 100644 index c6a66cd71..000000000 --- a/doc/tutorial/figures/packet.obj +++ /dev/null @@ -1,227 +0,0 @@ -%TGIF 4.1.43-QPL -state(0,37,100.000,0,64,0,32,0,9,1,1,1,0,0,0,1,0,'Courier-Bold',1,103680,0,3,0,10,0,0,1,1,0,16,0,0,1,1,1,1,1088,1408,1,0,2880,0). -% -% @(#)$Header$ -% %W% -% -unit("1 pixel/pixel"). -color_info(11,65535,0,[ - "magenta", 65535, 0, 65535, 65535, 0, 65535, 1, - "red", 65535, 0, 0, 65535, 0, 0, 1, - "green", 0, 65535, 0, 0, 65535, 0, 1, - "blue", 0, 0, 65535, 0, 0, 65535, 1, - "yellow", 65535, 65535, 0, 65535, 65535, 0, 1, - "pink", 65535, 49344, 52171, 65535, 49344, 52171, 1, - "cyan", 0, 65535, 65535, 0, 65535, 65535, 1, - "CadetBlue", 24415, 40606, 41120, 24415, 40606, 41120, 1, - "white", 65535, 65535, 65535, 65535, 65535, 65535, 1, - "black", 0, 0, 0, 0, 0, 0, 1, - "DarkSlateGray", 12079, 20303, 20303, 12079, 20303, 20303, 1 -]). -script_frac("0.6"). -fg_bg_colors('black','white'). -dont_reencode("FFDingbests:ZapfDingbats"). -page(1,"",1,''). -box('black','',32,48,240,256,0,3,1,0,0,0,0,0,0,'3',0,[ -]). -text('black',64,10,1,0,1,121,28,3,22,6,0,0,0,0,2,121,28,0,0,"",0,0,0,0,32,'',[ -minilines(121,28,0,0,0,0,0,[ -mini_line(121,22,6,0,0,0,[ -str_block(0,121,22,6,0,0,0,0,0,[ -str_seg('black','Times-Roman',0,138240,121,22,6,0,0,0,0,0,0,0, - "class Packet")]) -]) -])]). -text('black',416,100,1,0,1,116,28,15,22,6,0,0,0,0,2,116,28,0,0,"",0,0,0,0,122,'',[ -minilines(116,28,0,0,0,0,0,[ -mini_line(116,22,6,0,0,0,[ -str_block(0,116,22,6,0,0,0,0,0,[ -str_seg('black','Times-Roman',0,138240,116,22,6,0,0,0,0,0,0,0, - "class Buffer")]) -]) -])]). -text('black',48,178,4,0,1,83,69,32,14,4,0,0,0,0,2,83,69,0,0,"",0,0,0,0,192,'',[ -minilines(83,69,0,0,0,0,0,[ -mini_line(80,14,4,0,0,0,[ -str_block(0,80,14,4,0,-1,0,0,0,[ -str_seg('black','Times-Bold',1,80640,80,14,4,0,-1,0,0,0,0,0, - "private data:")]) -]), -mini_line(59,14,3,0,0,0,[ -str_block(0,59,14,3,0,0,0,0,0,[ -str_seg('black','Times-Roman',0,80640,59,14,3,0,0,0,0,0,0,0, - "- unique id")]) -]), -mini_line(83,14,3,0,0,0,[ -str_block(0,83,14,3,0,0,0,0,0,[ -str_seg('black','Times-Roman',0,80640,83,14,3,0,0,0,0,0,0,0, - "- Buffer object")]) -]), -mini_line(76,14,3,0,0,0,[ -str_block(0,76,14,3,0,0,0,0,0,[ -str_seg('black','Times-Roman',0,80640,76,14,3,0,0,0,0,0,0,0, - "- Tags object")]) -]) -])]). -text('black',112,288,1,0,1,103,28,82,22,6,0,0,0,0,2,103,28,0,0,"",0,0,0,0,310,'',[ -minilines(103,28,0,0,0,0,0,[ -mini_line(103,22,6,0,0,0,[ -str_block(0,103,22,6,0,-1,0,0,0,[ -str_seg('black','Times-Roman',0,138240,103,22,6,0,-1,0,0,0,0,0, - "class Tags")]) -]) -])]). -text('black',48,50,5,0,1,175,86,176,14,4,0,0,0,0,2,175,86,0,0,"",0,0,0,0,64,'',[ -minilines(175,86,0,0,0,0,0,[ -mini_line(105,14,4,0,0,0,[ -str_block(0,105,14,4,0,-1,0,0,0,[ -str_seg('black','Times-Bold',1,80640,105,14,4,0,-1,0,0,0,0,0, - "public functions:")]) -]), -mini_line(80,14,3,0,0,0,[ -str_block(0,80,14,3,0,-1,0,0,0,[ -str_seg('black','Times-Roman',0,80640,80,14,3,0,-1,0,0,0,0,0, - "- constructors")]) -]), -mini_line(175,14,3,0,0,0,[ -str_block(0,175,14,3,0,-1,0,0,0,[ -str_seg('black','Times-Roman',0,80640,175,14,3,0,-1,0,0,0,0,0, - "- add/remove/peek at Headers")]) -]), -mini_line(155,14,3,0,0,0,[ -str_block(0,155,14,3,0,-1,0,0,0,[ -str_seg('black','Times-Roman',0,80640,155,14,3,0,-1,0,0,0,0,0, - "- add/remove/peek at Tags")]) -]), -mini_line(88,14,3,0,0,0,[ -str_block(0,88,14,3,0,0,0,0,0,[ -str_seg('black','Times-Roman',0,80640,88,14,3,0,0,0,0,0,0,0, - "- fragmentation")]) -]) -])]). -box('black','',384,144,614,352,0,3,1,245,0,0,0,0,0,'3',0,[ -]). -text('black',400,274,4,0,1,204,69,246,14,4,0,0,0,0,2,204,69,0,0,"",0,0,0,0,288,'',[ -minilines(204,69,0,0,0,0,0,[ -mini_line(80,14,4,0,0,0,[ -str_block(0,80,14,4,0,-1,0,0,0,[ -str_seg('black','Times-Bold',1,80640,80,14,4,0,-1,0,0,0,0,0, - "private data:")]) -]), -mini_line(193,14,3,0,0,0,[ -str_block(0,193,14,3,0,0,0,0,0,[ -str_seg('black','Times-Roman',0,80640,193,14,3,0,0,0,0,0,0,0, - "- struct BufferData, a dynamically")]) -]), -mini_line(160,14,3,0,0,0,[ -str_block(0,160,14,3,0,0,0,0,0,[ -str_seg('black','Times-Roman',0,80640,160,14,3,0,0,0,0,0,0,0, - "varying byte buffer to which")]) -]), -mini_line(204,14,3,0,0,0,[ -str_block(0,204,14,3,0,0,0,0,0,[ -str_seg('black','Times-Roman',0,80640,204,14,3,0,0,0,0,0,0,0, - "data can be prepended or appended")]) -]) -])]). -text('black',400,146,5,0,1,188,86,247,14,4,0,0,0,0,2,188,86,0,0,"",0,0,0,0,160,'',[ -minilines(188,86,0,0,0,0,0,[ -mini_line(105,14,4,0,0,0,[ -str_block(0,105,14,4,0,-1,0,0,0,[ -str_seg('black','Times-Bold',1,80640,105,14,4,0,-1,0,0,0,0,0, - "public functions:")]) -]), -mini_line(172,14,3,0,0,0,[ -str_block(0,172,14,3,0,0,0,0,0,[ -str_seg('black','Times-Roman',0,80640,172,14,3,0,0,0,0,0,0,0, - "- Iterators to move byte buffer")]) -]), -mini_line(171,14,3,0,0,0,[ -str_block(0,171,14,3,0,0,0,0,0,[ -str_seg('black','Times-Roman',0,80640,171,14,3,0,0,0,0,0,0,0, - "pointers forward or backward")]) -]), -mini_line(188,14,3,0,0,0,[ -str_block(0,188,14,3,0,0,0,0,0,[ -str_seg('black','Times-Roman',0,80640,188,14,3,0,0,0,0,0,0,0, - "- functions to read and write data")]) -]), -mini_line(132,14,3,0,0,0,[ -str_block(0,132,14,3,0,-1,0,0,0,[ -str_seg('black','Times-Roman',0,80640,132,14,3,0,-1,0,0,0,0,0, - "of various sized chunks")]) -]) -])]). -box('black','',96,324,304,532,0,3,1,264,0,0,0,0,0,'3',0,[ -]). -text('black',112,454,4,0,1,167,69,265,14,4,0,0,0,0,2,167,69,0,0,"",0,0,0,0,468,'',[ -minilines(167,69,0,0,0,0,0,[ -mini_line(80,14,4,0,0,0,[ -str_block(0,80,14,4,0,-1,0,0,0,[ -str_seg('black','Times-Bold',1,80640,80,14,4,0,-1,0,0,0,0,0, - "private data:")]) -]), -mini_line(167,14,3,0,0,0,[ -str_block(0,167,14,3,0,0,0,0,0,[ -str_seg('black','Times-Roman',0,80640,167,14,3,0,0,0,0,0,0,0, - "- singly linked-list of TagData")]) -]), -mini_line(158,14,3,0,0,0,[ -str_block(0,158,14,3,0,0,0,0,0,[ -str_seg('black','Times-Roman',0,80640,158,14,3,0,0,0,0,0,0,0, - "structures, with a reference")]) -]), -mini_line(32,14,3,0,0,0,[ -str_block(0,32,14,3,0,0,0,0,0,[ -str_seg('black','Times-Roman',0,80640,32,14,3,0,0,0,0,0,0,0, - "count")]) -]) -])]). -text('black',112,326,5,0,1,155,86,266,14,4,0,0,0,0,2,155,86,0,0,"",0,0,0,0,340,'',[ -minilines(155,86,0,0,0,0,0,[ -mini_line(105,14,4,0,0,0,[ -str_block(0,105,14,4,0,-1,0,0,0,[ -str_seg('black','Times-Bold',1,80640,105,14,4,0,-1,0,0,0,0,0, - "public functions:")]) -]), -mini_line(80,14,3,0,0,0,[ -str_block(0,80,14,3,0,-1,0,0,0,[ -str_seg('black','Times-Roman',0,80640,80,14,3,0,-1,0,0,0,0,0, - "- constructors")]) -]), -mini_line(155,14,3,0,0,0,[ -str_block(0,155,14,3,0,-1,0,0,0,[ -str_seg('black','Times-Roman',0,80640,155,14,3,0,-1,0,0,0,0,0, - "- templates to add, remove,")]) -]), -mini_line(148,14,3,0,0,0,[ -str_block(0,148,14,3,0,-1,0,0,0,[ -str_seg('black','Times-Roman',0,80640,148,14,3,0,-1,0,0,0,0,0, - "or peek at Tags of various")]) -]), -mini_line(31,14,3,0,0,0,[ -str_block(0,31,14,3,0,-1,0,0,0,[ -str_seg('black','Times-Roman',0,80640,31,14,3,0,-1,0,0,0,0,0, - "types")]) -]) -])]). -poly('black','',2,[ - 59,245,96,320],0,2,1,272,0,0,3,0,0,0,0,'2',0,0, - "0","",[ - 0,10,4,0,'10','4','0'],[0,10,4,0,'10','4','0'],[ -]). -poly('black','',2,[ - 123,246,288,320],0,2,1,280,0,0,3,0,0,0,0,'2',0,0, - "0","",[ - 0,10,4,0,'10','4','0'],[0,10,4,0,'10','4','0'],[ -]). -poly('black','',2,[ - 141,219,379,147],0,2,1,286,0,0,3,0,0,0,0,'2',0,0, - "0","",[ - 0,10,4,0,'10','4','0'],[0,10,4,0,'10','4','0'],[ -]). -poly('black','',2,[ - 132,226,375,335],0,2,1,287,0,0,3,0,0,0,0,'2',0,0, - "0","",[ - 0,10,4,0,'10','4','0'],[0,10,4,0,'10','4','0'],[ -]). diff --git a/doc/tutorial/figures/sockets-overview.dia b/doc/tutorial/figures/sockets-overview.dia deleted file mode 100644 index af9e583101c90073ef2605e47f9e0ae23a91af05..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2222 zcmV;f2vPSRiwFP!000001MOYkZ{s!+e)nG?cwe@Fmli4Uht^Gsb`Qlp9NGfiJ_oYJ z*t(S^LsB;DKHT4aL&~XRTS^>Jbd!Px659&Hk3$V-z9EOy_dk4FXWmy?R%wx6jWP1a zp3E0TlIF{+@gJXm{vgIbT#vp_()c6%EX#Q9!GGkH`gS#5)%E7%bb5b(kFsqQ*F}l4 z^bS>W`oB2K;wcoGj;}|a_qc*2u48p=cQvl-GM(Sm(#zwuyc*Br#g}DS+~vu*DYYxN zD6*pTzQ)eAhH-cVS;wTSGfR>UCT$)BF?%`X*~Sf*?T%fzF_jhyF+e=68vP_ew2kt?Mj#}>1q+Z>8v(#Np?ORK=e@&}&p2@b>r+GbC z_1j^pKfXKKdhh?;P#c=sI^9DeB$f2#?qPYCCbD`)%?`_S)U?_an?Bd;$K}rLnC8-v zv(^wJPXEgk%Oqapdl;EJ;5qtPu=E?i-MxTm22bt8Ttf(ZsBZNA5#S??E%d!`F-PQ*jq~<3IFgFnt>iF z=9$Xb2k6j1J;7pq-wX)c|1w|8_PZ(byY;Ro&qQf8KV2qty0;!@n3JE1Z!OjYn_3f& zf=OW4m~cd>!kA%>z>a`D>1#)1Cf7HMqRdZ2jKM_G7@CTliuD%_@lkj%u80BF$w)p1 z69|XV<5xehYE|6dv;>~dv+5z#x5FC}Q~ec6xk40L)L+r)ub{ICegT+x{a)~wB9YG9 z+4gp)%IBP2e{1n`R@^UEaan6~QLfWG&RR@HU}`cVL@96-Zqw%hhJu)33LiLl3y!f( zpJyo3IZltFsB?G?@AMFZF7p`|7z;*2-qYr0X)d1=%t!dha9{&4HE8e3Q#;>1lwSgI zn`YS=5QlTee=ARTs;{)SI0oo2MBOt%uhj=T|7$(kBw$?`;(kE?VF4$$;DfugD@!*w ztD;Q*1a$(B`_yrBr52G#KI&j3S#HgCQme1(YBlnq=?^fzQ+hT+RfZ>YrOp9mHV#2e?X$!Qke( z7b+`|P^-BYp~ldrLVXJQfh~$Wzma*OTmLedIuy0P;Gi0d&2bajl7wxCrec856sztM z)+fFJgsZ3&;;IQyB@$4}5viG6XC;vx<&asO@(xjOm_x=~JnG_6H|6aZ*pb~6K+ZA3 z%tfFs0_{aAB4biP5D^z(6-2LV?|4Ns`*HzhVJw`Z7LHmtYT>BG+e_7p9Jg@X!iZa7 z^UbrN^7r=1MX342j$AO!G%i3cjD>UL!jTI{E*!adYve*Ln>%vh$VJbkb8Nhgo~oUo zpoZ8YsQ`>Xp{P7LLT3+<)UBR78`!FWZu#8i@;N30oaCdn@DQ7UNPq&)m`dXfC}lGR z$-)p~1TY(+?Zxy{0b3K_7&OQKTNcy1LX$kXiOaIM@8+b07*>6g$$a^AI6_S!o(*{D zu_=Aj?MRU9s z+~(?pK|K7$TY+LI4~)lNUFfADZ~xa8sFO+uVt2+nJPC$g7a`moCTwcp9tUGiXM`b6 zXf(kvP{|uOd97G{k@YBDZ!)PIyUrZ1M(-tBBJcC3-zK9!{`K3$E93j`938Yx2Rl^O zQ9`SZjt*dHLSKa1=TN(e*t>OT;sY&Iu$%}rgF;B(3Ei_@U5AjZiI!9q1OvzeM-bmW zLG1F-#(NhCQ3oJJD75OHiJp1UdaDjb-C+vhCSaV$ZB;?%ZmpUP;~flGg;5h``{Wjl zLQ%+o)HB37dPE}o+kj!rl_;poIG zrxRgg=qQS?qZ5u!y!hFa#v43{kHW^o6RS+(0VmK;YF2r}K2=K`{0$`;cuj6WDyz|Z z>}_P}Rn2t;Hd5d7B9Sib;4-;P?TYIX4{RnLkYE6N6R4yBb>E`M<}-0IeTZG)ZKl+P zsPthKyo9!Q%5+NEzA;=EW$GEqp-V*gr*1JLq4`r`L%sFO?o(l5bTF>=_eAhMix7md wL7+65Q{VP(%oYh-3+d*(hNF#}?^(Q+<@Kof0zb<#USE&?4|CyAxYdgQ0OMp;RR910 diff --git a/doc/tutorial/packets.texi b/doc/tutorial/packets.texi deleted file mode 100644 index cc00e0094..000000000 --- a/doc/tutorial/packets.texi +++ /dev/null @@ -1,620 +0,0 @@ -@node ns-3 Packets -@chapter ns-3 Packets - -The design of the Packet framework of @emph{ns} was heavily guided by a few -important use-cases: -@itemize @bullet -@item avoid changing the core of the simulator to introduce -new types of packet headers or trailers -@item maximize the ease of integration with real-world code -and systems -@item make it easy to support fragmentation, defragmentation, -and, concatenation which are important, especially in wireless systems. -@item make memory management of this object efficient -@item allow actual application data or dummy application bytes for -emulated applications -@end itemize - -@emph{ns} Packet objects contain a buffer of bytes: protocol headers and -trailers are serialized in this buffer of bytes using user-provided -serialization and deserialization routines. The content of this byte -buffer is expected to match bit-for-bit the content of a real packet on -a real network implementing the protocol of interest. - -Fragmentation and defragmentation are quite natural to implement within -this context: since we have a buffer of real bytes, we can split it in -multiple fragments and re-assemble these fragments. We expect that this -choice will make it really easy to wrap our Packet data structure within -Linux-style skb or BSD-style mbuf to integrate real-world kernel code in -the simulator. We also expect that performing a real-time plug of the -simulator to a real-world network will be easy. - -Because we understand that simulation developers often wish to store in -packet objects data which is not found in the real packets (such as -timestamps or any kind of similar in-band data), the @emph{ns} Packet class -can also store extra per-packet "Tags" which are 16 bytes blobs of data. -Any Packet can store any number of unique Tags, each of which is -uniquely identified by its C++ type. These tags make it easy to attach -per-model data to a packet without having to patch the main Packet -class or Packet facilities. - -Memory management of Packet objects is entirely automatic and extremely -efficient: memory for the application-level payload can be modelized by -a virtual buffer of zero-filled bytes for which memory is never allocated -unless explicitely requested by the user or unless the packet is fragmented. -Furthermore, copying, adding, and, removing headers or trailers to a packet -has been optimized to be virtually free through a technique known as -Copy On Write. - -Packets (messages) are fundamental objects in the simulator and -their design is important from a performance and resource management -perspective. There -are various ways to design the simulation packet, and tradeoffs -among the different approaches. In particular, there is a -tension between ease-of-use, performance, and safe interface -design. - -There are a few requirements on this object design: -@itemize @bullet -@item Creation, management, and deletion of this object -should be as simple as possible, while avoiding the -chance for memory leaks and/or heap corruption; -@item Packets should support serialization and deserialization -so that network emulation is supported; -@item Packets should support fragmentation and concatenation -(multiple packets in a data link frame), especially for wireless -support; -@item It should be natural for packets to carry actual application -data, or if there is only an emulated application and there is -no need to carry dummy bytes, smaller packets could be used with -just the headers and a record of the payload size, but not actual -application bytes, conveyed in the simulated packet. -@item Packets should facilitate BSD-like operations on mbufs, for -support of ported operating system stacks. -@item Additional side-information should be supported, such as -a tag for cross-layer information. -@end itemize - -@section Packet design overview - -Unlike @emph{ns-2}, in which Packet objects contain a buffer of C++ -structures corresponding to protocol headers, each network packet in -@emph{ns-3} contains a byte Buffer and a list of Tags: -@itemize @bullet -@item The byte buffer stores the serialized content of the chunks -added to a packet. The serialized representation of these chunks is -expected to match that of real network packets bit for bit -(although nothing forces you to do this) which means that the content -of a packet buffer is expected to be that of a real packet. -Packets can also be created with an arbitrary zero-filled payload -for which no real memory is allocated. -@item The list of tags stores an arbitrarily large set of arbitrary -user-provided data structures in the packet. Each Tag is uniquely -identified by its type; only one instance of each -type of data structure is allowed in a list of tags. These tags typically -contain per-packet cross-layer information or flow identifiers (i.e., -things that you wouldn't find in the bits on the wire). Each tag -stored in the tag list can be at most 16 bytes. -Trying to attach bigger data structures will trigger -crashes at runtime. The 16 byte limit is a modifiable compilation -constant. -@end itemize - -@float Figure,fig:packets -@caption{Implementation overview of Packet class.} -@image{figures/packet} -@end float - -Figure @ref{fig:packets} is a high-level overview of the Packet -implementation; more detail on the byte Buffer implementation -is provided later in Figure @ref{fig:buffer}. -In \nsthree, the Packet byte buffer is analogous to a Linux skbuff -or BSD mbuf; it is a serialized representation of the actual -data in the packet. The tag list is a container for extra -items useful for simulation convenience; if a Packet is converted -to an emulated packet and put over an actual network, the tags -are stripped off and the byte buffer is copied directly -into a real packet. - -The Packet class has value semantics: it can be freely copied around, -allocated on the stack, and passed to functions as arguments. Whenever -an instance is copied, the full underlying data is not copied; it -has ``copy-on-write'' (COW) semantics. Packet instances can be passed -by value to function arguments without any performance hit. - -The fundamental classes for adding to and removing from the byte -buffer are @code{class Header} and @code{class Trailer}. -Headers are more common but the below discussion also largely applies to -protocols using trailers. Every protocol header that needs to -be inserted and removed from a Packet instance should derive from -the abstract Header base class and implement the private pure -virtual methods listed below: -@itemize @bullet -@item @code{ns3::Header::SerializeTo()} -@item @code{ns3::Header::DeserializeFrom()} -@item @code{ns3::Header::GetSerializedSize()} -@item @code{ns3::Header::PrintTo()} -@end itemize -Basically, the first three functions are used to serialize and deserialize -protocol control information to/from a Buffer. For example, -one may define @code{class TCPHeader : public Header}. The -TCPHeader object will typically consist of some private data -(like a sequence number) and public interface access functions -(such as checking the bounds of an input). But the underlying -representation of the TCPHeader in a Packet Buffer is 20 serialized -bytes (plus TCP options). The TCPHeader::SerializeTo() function would -therefore be designed to write these 20 bytes properly into -the packet, in network byte order. The last function is used -to define how the Header object prints itself onto an output stream. - -Similarly, user-defined Tags can be appended to the packet. -Unlike Headers, Tags are not serialized into a contiguous buffer -but are stored in an array. By default, Tags are limited to 16 bytes in -size. Tags can be flexibly defined to be any type, but there -can only be one instance of any particular object type in -the Tags buffer at any time. The implementation makes use -of templates to generate the proper set of Add(), Remove(), -and Peek() functions for each Tag type. - -@section Packet interface - -The public member functions of a Packet object are as follows: - -@subsection Constructors -@verbatim - /** - * Create an empty packet with a new uid (as returned - * by getUid). - */ - Packet (); - /** - * Create a packet with a zero-filled payload. - * The memory necessary for the payload is not allocated: - * it will be allocated at any later point if you attempt - * to fragment this packet or to access the zero-filled - * bytes. The packet is allocated with a new uid (as - * returned by getUid). - * - * \param size the size of the zero-filled payload - */ - Packet (uint32_t size); -@end verbatim - -@subsection Adding and removing Buffer data -The below code is reproduced for Header class only; similar functions -exist for Trailers. -@verbatim - /** - * Add header to this packet. This method invokes the - * ns3::Header::serializeTo method to request the header to serialize - * itself in the packet buffer. - * - * \param header a reference to the header to add to this packet. - */ - void Add (Header const &header); - /** - * Deserialize header from this packet. This method invokes the - * ns3::Header::deserializeFrom method to request the header to deserialize - * itself from the packet buffer. This method does not remove - * the data from the buffer. It merely reads it. - * - * \param header a reference to the header to deserialize from the buffer - */ - void Peek (Header &header); - /** - * Remove a deserialized header from the internal buffer. - * This method removes the bytes read by Packet::peek from - * the packet buffer. - * - * \param header a reference to the header to remove from the internal buffer. - */ - void Remove (Header const &header); - /** - * Add trailer to this packet. This method invokes the - * ns3::Trailer::serializeTo method to request the trailer to serialize - * itself in the packet buffer. - * - * \param trailer a reference to the trailer to add to this packet. - */ -@end verbatim - -@subsection Adding and removing Tags -@verbatim - /** - * Attach a tag to this packet. The tag is fully copied - * in a packet-specific internal buffer. This operation - * is expected to be really fast. - * - * \param tag a pointer to the tag to attach to this packet. - */ - template - void AddTag (T const &tag); - /** - * Remove a tag from this packet. The data stored internally - * for this tag is copied in the input tag if an instance - * of this tag type is present in the internal buffer. If this - * tag type is not present, the input tag is not modified. - * - * This operation can be potentially slow and might trigger - * unexpectedly large memory allocations. It is thus - * usually a better idea to create a copy of this packet, - * and invoke removeAllTags on the copy to remove all - * tags rather than remove the tags one by one from a packet. - * - * \param tag a pointer to the tag to remove from this packet - * \returns true if an instance of this tag type is stored - * in this packet, false otherwise. - */ - template - bool RemoveTag (T &tag); - /** - * Copy a tag stored internally to the input tag. If no instance - * of this tag is present internally, the input tag is not modified. - * - * \param tag a pointer to the tag to read from this packet - * \returns true if an instance of this tag type is stored - * in this packet, false otherwise. - */ - template - bool PeekTag (T &tag) const; - /** - * Remove all the tags stored in this packet. This operation is - * much much faster than invoking removeTag n times. - */ - void RemoveAllTags (void); -@end verbatim - -@subsection Fragmentation -@verbatim - /** - * Create a new packet which contains a fragment of the original - * packet. The returned packet shares the same uid as this packet. - * - * \param start offset from start of packet to start of fragment to create - * \param length length of fragment to create - * \returns a fragment of the original packet - */ - Packet CreateFragment (uint32_t start, uint32_t length) const; - - /** - * Concatenate the input packet at the end of the current - * packet. This does not alter the uid of either packet. - * - * \param packet packet to concatenate - */ - void addAtEnd (Packet packet); - - /oncatenate the input packet at the end of the current - * packet. This does not alter the uid of either packet. - * - * \param packet packet to concatenate - */ - void AddAtEnd (Packet packet); - /** - * Concatenate the fragment of the input packet identified - * by the offset and size parameters at the end of the current - * packet. This does not alter the uid of either packet. - * - * \param packet to concatenate - * \param offset offset of fragment to copy from the start of the input packet - * \param size size of fragment of input packet to copy. - */ - void AddAtEnd (Packet packet, uint32_t offset, uint32_t size); - /** - * Remove size bytes from the end of the current packet - * It is safe to remove more bytes that what is present in - * the packet. - * - * \param size number of bytes from remove - */ - void RemoveAtEnd (uint32_t size); - /** - * Remove size bytes from the start of the current packet. - * It is safe to remove more bytes that what is present in - * the packet. - * - * \param size number of bytes from remove - */ - void RemoveAtStart (uint32_t size); -@end verbatim - -@subsection Miscellaneous -@verbatim - /** - * \returns the size in bytes of the packet (including the zero-filled - * initial payload) - */ - uint32_t GetSize (void) const; - /** - * If you try to change the content of the buffer - * returned by this method, you will die. - * - * \returns a pointer to the internal buffer of the packet. - */ - uint8_t const *PeekData (void) const; - /** - * A packet is allocated a new uid when it is created - * empty or with zero-filled payload. - * - * \returns an integer identifier which uniquely - * identifies this packet. - */ - uint32_t GetUid (void) const; -@end verbatim - -@section Using Headers -@emph{walk through an example of adding a UDP header} - -@section Using Tags -@emph{walk through an example of adding a flow ID} - -@section Using Fragmentation -@emph{walk through an example of link-layer fragmentation/reassembly} - -@section Sample program -The below sample program (from @code{ns3/samples/main-packet.cc}) illustrates -some use of the Packet, Header, and Tag classes. - -@verbatim -/* -*- Mode:C++; c-basic-offset:4; tab-width:4; indent-tabs-mode:nil -*- */ -#include "ns3/packet.h" -#include "ns3/header.h" -#include - -using namespace ns3; - -/* A sample Header implementation - */ -class MyHeader : public Header { -public: - MyHeader (); - virtual ~MyHeader (); - - void SetData (uint16_t data); - uint16_t GetData (void) const; -private: - virtual void PrintTo (std::ostream &os) const; - virtual void SerializeTo (Buffer::Iterator start) const; - virtual void DeserializeFrom (Buffer::Iterator start); - virtual uint32_t GetSerializedSize (void) const; - - uint16_t m_data; -}; - -MyHeader::MyHeader () -{} -MyHeader::~MyHeader () -{} -void -MyHeader::PrintTo (std::ostream &os) const -{ - os << "MyHeader data=" << m_data << std::endl; -} -uint32_t -MyHeader::GetSerializedSize (void) const -{ - return 2; -} -void -MyHeader::SerializeTo (Buffer::Iterator start) const -{ - // serialize in head of buffer - start.WriteHtonU16 (m_data); -} -void -MyHeader::DeserializeFrom (Buffer::Iterator start) -{ - // deserialize from head of buffer - m_data = start.ReadNtohU16 (); -} - -void -MyHeader::SetData (uint16_t data) -{ - m_data = data; -} -uint16_t -MyHeader::GetData (void) const -{ - return m_data; -} - -/* A sample Tag implementation - */ -struct MyTag { - uint16_t m_streamId; -}; - -static TagRegistration g_MyTagRegistration ("ns3::MyTag", 0); - - -static void -Receive (Packet p) -{ - MyHeader my; - p.Peek (my); - p.Remove (my); - std::cout << "received data=" << my.GetData () << std::endl; - struct MyTag myTag; - p.PeekTag (myTag); -} - - -int main (int argc, char *argv[]) -{ - Packet p; - MyHeader my; - my.SetData (2); - std::cout << "send data=2" << std::endl; - p.Add (my); - struct MyTag myTag; - myTag.m_streamId = 5; - p.AddTag (myTag); - Receive (p); - return 0; -} -@end verbatim - -@section Implementation details - -@subsection Private member variables - -A Packet object's interface provides access to some private -data: -@verbatim - Buffer m_buffer; - Tags m_tags; - uint32_t m_uid; - static uint32_t m_global_uid; -@end verbatim -Each Packet has a Buffer and a Tags object, and a 32-bit unique ID (m\_uid). -A static member variable keeps track of the UIDs allocated. Note -that real network packets do not have a UID; the UID is therefore an -instance of data that normally would be stored as a Tag in the packet. -However, it was felt that a UID is a special case that is so often -used in simulations that it would be more convenient to store it -in a member variable. - -@subsection Buffer implementation - -Class Buffer represents a buffer of bytes. Its size is -automatically adjusted to hold any data prepended -or appended by the user. Its implementation is optimized -to ensure that the number of buffer resizes is minimized, -by creating new Buffers of the maximum size ever used. -The correct maximum size is learned at runtime during use by -recording the maximum size of each packet. - -Authors of new Header or Trailer classes need to know the public -API of the Buffer class. (add summary here) - -The byte buffer is implemented as follows: -@verbatim - struct BufferData { - uint32_t m_count; - uint32_t m_size; - uint32_t m_initialStart; - uint32_t m_dirtyStart; - uint32_t m_dirtySize; - uint8_t m_data[1]; - }; - struct BufferData *m_data; - uint32_t m_zeroAreaSize; - uint32_t m_start; - uint32_t m_size; -@end verbatim - -@itemize @bullet -@item @code{BufferData::m_count}: reference count for BufferData structure -@item @code{BufferData::m_size}: size of data buffer stored in BufferData structure -@item @code{BufferData::m_initialStart}: offset from start of data buffer where data was first inserted -@item @code{BufferData::m_dirtyStart}: offset from start of buffer where every Buffer which holds a reference to this BufferData instance have written data so far -@item @code{BufferData::m_dirtySize}: size of area where data has been written so far -@item @code{BufferData::m_data}: pointer to data buffer -@item @code{Buffer::m_zeroAreaSize}: size of zero area which extends before @code{m_initialStart} -@item @code{Buffer::m_start}: offset from start of buffer to area used by this buffer -@item @code{Buffer::m_size}: size of area used by this Buffer in its BufferData structure -@end itemize - -@float Figure,fig:buffer -@caption{Implementation overview of a packet's byte Buffer.} -@image{figures/buffer,15cm} -@end float - -This data structure is summarized in Figure @ref{fig:buffer}. -Each Buffer holds a pointer to an instance of a BufferData. Most -Buffers should be able to share the same underlying BufferData and -thus simply increase the BufferData's reference count. If they have to -change the content of a BufferData inside the Dirty Area, and if the -reference count is not one, they first create a copy of the BufferData and -then complete their state-changing operation. - -@subsection Tags implementation -Tags are implemented by a single pointer which points to the start of a -linked list ofTagData data structures. Each TagData structure points -to the next TagData in the list (its next pointer contains zero to -indicate the end of the linked list). Each TagData contains an integer -unique id which identifies the type of the tag stored in the TagData. -@verbatim -struct TagData { - struct TagData *m_next; - uint32_t m_id; - uint32_t m_count; - uint8_t m_data[Tags::SIZE]; -}; -class Tags { - struct TagData *m_next; -}; -@end verbatim - -Adding a tag is a matter of inserting a new TagData at the head of -the linked list. Looking at a tag requires you to find the relevant -TagData in the linked list and copy its data into the user data -structure. Removing a tag and updating the content of a tag -requires a deep copy of the linked list before performing this operation. -On the other hand, copying a Packet and its tags is a matter of -copying the TagData head pointer and incrementing its reference count. - -Tags are found by the unique mapping betweent the Tag type and -its underlying id. This is why at most one instance of any Tag -can be stored in a packet. The mapping between Tag type and -underlying id is performed by a registration as follows: -@verbatim -/* A sample Tag implementation - */ -struct MyTag { - uint16_t m_streamId; -}; -@end verbatim - -@emph{add description of TagRegistration for printing} - -@subsection Memory management - -@emph{Describe free list.} - -@emph{Describe dataless vs. data-full packets.} - -@subsection Copy-on-write semantics -The current implementation of the byte buffers and tag list is based -on COW (Copy On Write). An introduction to COW can be found in Scott -Meyer's "More Effective C++", items 17 and 29). This design feature -and aspects of the public interface borrows from the packet design -of the Georgia Tech Network Simulator. -This implementation of COW uses a customized reference counting -smart pointer class. - -What COW means is that -copying packets without modifying them is very cheap (in terms of CPU -and memory usage) and modifying them can be also very cheap. What is -key for proper COW implementations is being -able to detect when a given modification of the state of a packet triggers -a full copy of the data prior to the modification: COW systems need -to detect when an operation is ``dirty'' and must therefore invoke -a true copy. - -Dirty operations: -@itemize @bullet -@item Packet::RemoveTag() -@item Packet::Add() -@item both versions of ns3::Packet::AddAtEnd() -@end itemize - -Non-dirty operations: -@itemize @bullet -@item Packet::AddTag() -@item Packet::RemoveAllTags() -@item Packet::PeekTag() -@item Packet::Peek() -@item Packet::Remove() -@item Packet::CreateFragment() -@item Packet::RemoveAtStart() -@item Packet::RemoveAtEnd() -@end itemize - -Dirty operations will always be slower than non-dirty operations, -sometimes by several orders of magnitude. However, even the -dirty operations have been optimized for common use-cases which -means that most of the time, these operations will not trigger -data copies and will thus be still very fast. - diff --git a/doc/tutorial/routing.texi b/doc/tutorial/routing.texi deleted file mode 100644 index d8250ee24..000000000 --- a/doc/tutorial/routing.texi +++ /dev/null @@ -1,373 +0,0 @@ -@node ns-3 routing overview -@chapter ns-3 routing overview - -This chapter describes the overall design of routing in the -@code{src/internet-stack} -module, and some details about the routing approachs currently -implemented. - -@node Routing-Overview -@section Overview - -We intend to support traditional routing approaches and protocols, -ports of open source routing implementations, and facilitate research -into unorthodox routing techniques. -For simulations that are not primarily focused on routing and that -simply want correct routing tables to occur somehow, we have an -global centralized routing capability. A singleton object -(GlobalRouteManager) be instantiated, builds a network map, and -populates a forwarding table on each node at time t=0 in the -simulation. Simulation script writers can use the same node -API to manually enter routes as well. - -@node Support for multiple routing protocols -@section Support for multiple routing protocols - -Typically, multiple routing protocols are supported in user space and -coordinate to write a single forwarding table in the kernel. Presently -in @command{ns-3}, the implementation instead allows for multiple routing -protocols to build/keep their own routing state, and the IPv4 implementation -will query each one of these routing protocols (in some order determined -by the simulation author) until a route is found. - -We chose this approach because it may better -faciliate the integration of disparate routing approaches that may -be difficult to coordinate the writing to a single table, approaches -where more information than destination IP address (e.g., source -routing) is used to determine the next hop, and on-demand -routing approaches where packets must be cached. - -There are presently two routing protocols defined: -@itemize @bullet -@item class Ipv4StaticRouting (covering both unicast and multicast) -@item Optimized Link State Routing (a MANET protocol defined in -@uref{http://www.ietf.org/rfc/rfc3626.txt,,RFC 3626}) -@end itemize -but first we describe how multiple routing protocols are supported. - -@subsection class Ipv4RoutingProtocol - -@code{class Ipv4RoutingProtocol} derives from ns-3 Object which means -that it supports interface aggregation and reference counting. Routing -protocols should inherit from this class, defined in src/node/ipv4.cc. - -The main function that must be supported by these protocols is called -@code{RequestRoute}. -@verbatim - * This method is called whenever a node's IPv4 forwarding engine - * needs to lookup a route for a given packet and IP header. - * - * The routing protocol implementation may determine immediately it - * should not be handling this particular the route request. For - * instance, a routing protocol may decline to search for routes for - * certain classes of addresses, like link-local. In this case, - * RequestRoute() should return false and the routeReply callback - * must not be invoked. - * - * If the routing protocol implementations assumes it can provide - * the requested route, then it should return true, and the - * routeReply callback must be invoked, either immediately before - * returning true (synchronously), or in the future (asynchronous). - * The routing protocol may use any information available in the IP - * header and packet as routing key, although most routing protocols - * use only the destination address (as given by - * ipHeader.GetDestination ()). The routing protocol is also - * allowed to add a new header to the packet, which will appear - * immediately after the IP header, although most routing do not - * insert any extra header. - */ - virtual bool RequestRoute (uint32_t ifIndex, - const Ipv4Header &ipHeader, - Ptr packet, - RouteReplyCallback routeReply) = 0; -@end verbatim - -This class also provides a typedef (used above) for a special Callback -that will pass to the callback function the Ipv4Route that is found (see the -Doxygen documentation): -@verbatim - typedef Callback, const Ipv4Header&> RouteReplyCallback; -@end verbatim - -@subsection Ipv4::AddRoutingProtocol - -Class Ipv4 provides a pure virtual function declaration for the -method that allows one to add a routing protocol: -@verbatim - void AddRoutingProtocol (Ptr routingProtocol, - int16_t priority); -@end verbatim -This method is implemented by class Ipv4L3Protocol in the internet-stack -module. - -The priority variable above governs the priority in which the routing -protocols are inserted. Notice that it is a signed int. -When the class Ipv4L3Protocol is instantiated, a single routing -protocol (Ipv4StaticRouting, introduced below) is added at priority -zero. Internally, a list of Ipv4RoutingProtocols is stored, and -and the routing protocols are each consulted in decreasing order -of priority to see whether a match is found. Therefore, if you -want your Ipv4RoutingProtocol to have priority lower than the static -routing, insert it with priority less than 0; e.g.: -@verbatim - m_ipv4->AddRoutingProtocol (m_routingTable, -10); -@end verbatim - -@subsection Ipv4L3Protocol::Lookup - -The main function for obtaining a route is shown below: -@verbatim -Ipv4L3Protocol::Lookup ( - uint32_t ifIndex, - Ipv4Header const &ipHeader, - Ptr packet, - Ipv4RoutingProtocol::RouteReplyCallback routeReply) -@end verbatim - -This function will search the list of routing protocols, in priority order, -until a route is found. It will then invoke the RouteReplyCallback -and no further routing protocols will be searched. If the caller does -not want to constrain the possible interface, it can be wildcarded -as such: -@verbatim - Lookup (Ipv4RoutingProtocol::IF_INDEX_ANY, ipHeader, packet, routeReply); -@end verbatim - -@node Roadmap and Future work -@section Roadmap and Future work - -Some goals for future support are: - -Users should be able to trace (either debug print, or redirect to a trace -file) the routing table in a format such as used in an -Unix implementation: -@verbatim -# netstat -nr (or # route -n) -Kernel IP routing table -Destination Gateway Genmask Flags MSS Window irtt Iface -127.0.0.1 * 255.255.255.255 UH 0 0 0 lo -172.16.1.0 * 255.255.255.0 U 0 0 0 eth0 -172.16.2.0 172.16.1.1 255.255.255.0 UG 0 0 0 eth0 - -# ip route show -192.168.99.0/24 dev eth0 scope link -127.0.0.0/8 dev lo scope link -default via 192.168.99.254 dev eth0 -@end verbatim - -Global computation of multicast routing should be implemented as well. -This would ignore group membership and ensure that a copy of every -sourced multicast datagram would be delivered to each node. -This might be implemented as an RPF mechanism that functioned on-demand -by querying the forwarding table, -and perhaps optimized by a small multicast forwarding cache. It is -a bit trickier to implement over wireless links where the input -interface is the same as the output interface; other aspects of the -packet must be considered and the forwarding logic slightly changed -to allow for forwarding out the same interface. - -In the future, work on bringing XORP or quagga routing to ns, but it will -take several months to port and enable. - -There are presently no roadmap plans for IPv6. - -@node Static routing -@section Static routing - -The internet-stack module provides one routing protocol (Ipv4StaticRouting) -by default. This routing protocol allows one to add unicast or multicast -static routes to a node. - -@node Unicast routing -@section Unicast routing - -The unicast static routing API may be accessed via the functions -@verbatim -void Ipv4::AddHostRouteTo () -void Ipv4::AddNetworkRouteTo () -void Ipv4::SetDefaultRoute () -uint32_t Ipv4::GetNRoutes () -Ipv4Route Ipv4::GetRoute () -@end verbatim - -@uref{http://www.nsnam.org/doxygen/index.html,,Doxygen} documentation -provides full documentation of these methods. These methods are forwarding -functions to the actual implementation in Ipv4StaticRouting, when using -the internet-stack module. - -@node Multicast routing -@section Multicast routing - -The following function is used to add a static multicast route -to a node: -@verbatim -void -Ipv4StaticRouting::AddMulticastRoute (Ipv4Address origin, - Ipv4Address group, - uint32_t inputInterface, - std::vector outputInterfaces); -@end verbatim - -A multicast route must specify an origin IP address, a multicast group and -an input network interface index as conditions and provide a vector of -output network interface indices over which packets matching the conditions -are sent. - -Typically there are two main types of multicast routes: routes of the -first kind are used during forwarding. All of the conditions must be -exlicitly provided. The second kind of routes are used to get packets off -of a local node. The difference is in the input interface. Routes for -forwarding will always have an explicit input interface specified. Routes -off of a node will always set the input interface to a wildcard specified -by the index Ipv4RoutingProtocol::IF\_INDEX\_ANY. - -For routes off of a local node wildcards may be used in the origin and -multicast group addresses. The wildcard used for Ipv4Adresses is that -address returned by Ipv4Address::GetAny () -- typically "0.0.0.0". Usage -of a wildcard allows one to specify default behavior to varying degrees. - -For example, making the origin address a wildcard, but leaving the -multicast group specific allows one (in the case of a node with multiple -interfaces) to create different routes using different output interfaces -for each multicast group. - -If the origin and multicast addresses are made wildcards, you have created -essentially a default multicast address that can forward to multiple -interfaces. Compare this to the actual default multicast address that is -limited to specifying a single output interface for compatibility with -existing functionality in other systems. - -Another command sets the default multicast route: -@verbatim -void -Ipv4StaticRouting::SetDefaultMulticastRoute (uint32_t outputInterface); -@end verbatim - -This is the multicast equivalent of the unicast version SetDefaultRoute. -We tell the routing system what to do in the case where a specific route -to a destination multicast group is not found. The system forwards -packets out the specified interface in the hope that "something out there" -knows better how to route the packet. This method is only used in -initially sending packets off of a host. The default multicast route is -not consulted during forwarding -- exact routes must be specified using -AddMulticastRoute for that case. - -Since we're basically sending packets to some entity we think may know -better what to do, we don't pay attention to "subtleties" like origin -address, nor do we worry about forwarding out multiple interfaces. If the -default multicast route is set, it is returned as the selected route from -LookupStatic irrespective of origin or multicast group if another specific -route is not found. - -Finally, a number of additional functions are provided to fetch and -remove multicast routes: -@verbatim - uint32_t GetNMulticastRoutes (void) const; - - Ipv4MulticastRoute *GetMulticastRoute (uint32_t i) const; - - Ipv4MulticastRoute *GetDefaultMulticastRoute (void) const; - - bool RemoveMulticastRoute (Ipv4Address origin, - Ipv4Address group, - uint32_t inputInterface); - - void RemoveMulticastRoute (uint32_t index); -@end verbatim - -@node Global centralized routing -@section Global centralized routing - -Presently, global centralized IPv4 @emph{unicast} routing over both -point-to-point and shared (CSMA) links is supported. -The global centralized routing will be modified in the future to -reduce computations once profiling finds the performance bottlenecks. - -@node Global Unicast Routing API -@section Global Unicast Routing API - -The public API is very minimal. User scripts include the following: -@verbatim -#include "ns3/global-route-manager.h" -@end verbatim - -After IP addresses are configured, the following function call will -cause all of the nodes that have an Ipv4 interface to receive -forwarding tables entered automatically by the GlobalRouteManager: -@verbatim - GlobalRouteManager::PopulateRoutingTables (); -@end verbatim - -@emph{Note:} A reminder that the wifi NetDevice is not yet supported -(only CSMA and PointToPoint). - -@node Global Routing Implementation -@section Global Routing Implementation - -A singleton object (GlobalRouteManager) is responsible for populating -the static routes on each node, using the public Ipv4 API of that node. -It queries each node in the topology for a "globalRouter" interface. -If found, it uses the API of that interface to obtain a "link state -advertisement (LSA)" for the router. Link State Advertisements -are used in OSPF routing, and we follow their formatting. - -The GlobalRouteManager populates a link state database with LSAs -gathered from the entire topology. Then, for each router in the topology, -the GlobalRouteManager executes the OSPF shortest path first (SPF) -computation on the database, and populates the routing tables on each -node. - -The quagga (http://www.quagga.net) OSPF implementation was used as the -basis for the routing computation logic. -One benefit of following an existing OSPF SPF implementation is that -OSPF already has defined link state advertisements for all common -types of network links: -@itemize @bullet -@item point-to-point (serial links) -@item point-to-multipoint (Frame Relay, ad hoc wireless) -@item non-broadcast multiple access (ATM) -@item broadcast (Ethernet) -@end itemize -Therefore, we think that enabling these other link types will be more -straightforward now that the underlying OSPF SPF framework is in place. - -Presently, we can handle IPv4 point-to-point, numbered links, as well -as shared broadcast (CSMA) links, and we do not do equal-cost multipath. - -The GlobalRouteManager first walks the list of nodes and aggregates -a GlobalRouter interface to each one as follows: -@verbatim - typedef std::vector < Ptr >::iterator Iterator; - for (Iterator i = NodeList::Begin (); i != NodeList::End (); i++) - { - Ptr node = *i; - Ptr globalRouter = CreateObject (node); - node->AggregateObject (globalRouter); - } -@end verbatim - -This interface is later queried and used to generate a Link State -Advertisement for each router, and this link state database is -fed into the OSPF shortest path computation logic. The Ipv4 API -is finally used to populate the routes themselves. - -@node Optimized Link State Routing (OLSR) -@section Optimized Link State Routing (OLSR) - -This is the first dynamic routing protocol for @command{ns-3}. The implementation -is found in the src/routing/olsr directory, and an example script is in -examples/simple-point-to-point-olsr.cc. - -The following commands will enable OLSR in a simulation. - -@verbatim - olsr::EnableAllNodes (); // Start OLSR on all nodes - olsr::EnableNodes(InputIterator begin, InputIterator end); // Start on - // a list of nodes - olsr::EnableNode (Ptr node); // Start OLSR on "node" only -@end verbatim - -Once instantiated, the agent can be started with the Start() command, -and the OLSR "main interface" can be set with the SetMainInterface() -command. A number of protocol constants are defined in olsr-agent-impl.cc. - diff --git a/doc/tutorial/sockets.texi b/doc/tutorial/sockets.texi deleted file mode 100644 index 0c17cde02..000000000 --- a/doc/tutorial/sockets.texi +++ /dev/null @@ -1,243 +0,0 @@ -@node Sockets APIs -@chapter Sockets APIs - -The @uref{http://en.wikipedia.org/wiki/Berkeley_sockets,,sockets API} -is a long-standing API used by user-space applications to access -network services in the kernel. A ``socket'' is an abstraction, like -a Unix file handle, that allows applications to connect to other -Internet hosts and exchange reliable byte streams and unreliable -datagrams, among other services. - -ns-3 provides two types of sockets APIs, and it is important to -understand the differences between them. The first is a @emph{native} -ns-3 API, while the second uses the services of the native API to -provide a @uref{http://en.wikipedia.org/wiki/POSIX,,POSIX-like} -API as part of an overall application process. Both APIs strive -to be close to the typical sockets API that application writers -on Unix systems are accustomed to, but the POSIX variant is much -closer to a real system's sockets API. - -@section ns-3 sockets API - -The native sockets API for ns-3 provides an interface to various -types of transport protocols (TCP, UDP) as well as to packet sockets -and, in the future, Netlink-like sockets. However, users are cautioned -to understand that the semantics are @strong{not} the exact same as -one finds in a real system (for an API which is very much aligned -to real systems, see the next section). - -@code{class ns3::Socket} is defined in @code{src/node/socket.cc,h}. -Readers will note that many public member functions are aligned -with real sockets function calls, and all other things being equal, -we have tried to align with a Posix sockets API. However, note that: - -@itemize @bullet -@item ns-3 applications handle a smart pointer to a Socket object, not -a file descriptor; -@item there is no notion of synchronous API or a ``blocking'' API; -in fact, the model for interaction between application and socket is -one of asynchronous I/O, which is not typically found in real systems -(more on this below); -@item the C-style socket address structures are not used; -@item the API is not a complete sockets API, such as supporting -all socket options or all function variants; -@item many calls use @code{ns3::Packet} class to transfer data -between application and socket. This may seem a little funny to -people to pass ``Packets'' across a stream socket API, but think -of these packets as just fancy byte buffers at this level (more -on this also below). -@end itemize - -@subsection Basic operation and calls - -@float Figure,fig:sockets-overview -@caption{Implementation overview of native sockets API} -@image{figures/sockets-overview, 10cm} -@end float - -@subsubsection Creating sockets - -An application that wants to use sockets must first create one. -On real systems, this is accomplished by calling socket(): -@verbatim - int - socket(int domain, int type, int protocol); -@end verbatim -which creates a socket in the system and returns an integer descriptor. - -In ns-3, we have no equivalent of a system call at the lower layers, -so we adopt the following model. There are certain @emph{factory} -objects that can create sockets. Each factory is capable of creating -one type of socket, and if sockets of a particular type are able to -be created on a given node, then a factory that can create such sockets -must be aggregated to the Node. -@verbatim - static Ptr CreateSocket (Ptr node, TypeId tid); -@end verbatim -Examples of TypeIds to pass to this method are @code{TcpSocketFactory}, -@code{PacketSocketFactory}, and @code{UdpSocketFactory}. - -This method returns a smart pointer to a Socket object. Here is an -example: -@verbatim - Ptr n0; - // Do some stuff to build up the Node's internet stack - Ptr localSocket = Socket::CreateSocket (n0, TcpSocketFactory::GetTypeId ()); -@end verbatim - -In some ns-3 code, sockets will not be explicitly created by user's -main programs, if an ns-3 application does it. For instance, for -@code{class ns3::OnOffApplication}, the function @code{StartApplication()} -performs the socket creation, and the application holds the socket -pointer. - -@subsubsection Using sockets - -Below is a typical sequence of socket calls for a TCP client in a -real implementation: -@itemize @bullet -@item @code{sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);} -@item @code{bind(sock, ...);} -@item @code{connect(sock, ...);} -@item @code{send(sock, ...);} -@item @code{recv(sock, ...);} -@item @code{close(sock);} -@end itemize - -There are analogs to all of these calls in ns-3, but we will focus on -two aspects here. First, most usage of sockets in real systems -requires a way to manage I/O between the application and kernel. -These models include @emph{blocking sockets}, @emph{signal-based I/O}, -and @emph{non-blocking sockets} with polling. In ns-3, we make use -of the callback mechanisms to support a fourth mode, which is -analogous to POSIX @emph{asynchronous I/O}. - -In this model, on the sending side, if the @code{send()} call were to -fail because of insufficient buffers, the application suspends the -sending of more data until a function registered at the -@code{SetSendCallback()} callback is invoked. An application can -also ask the socket how much space is available by calling -@code{GetTxAvailable ()}. A typical sequence of events for -sending data (ignoring connection setup) might be: - -@itemize @bullet -@item @code{SetSendCallback (MakeCallback(&HandleSendCallback));} -@item @code{Send ();} -@item @code{Send ();} -@item ... -@item @code{// Send fails because buffer is full} -@item (wait until HandleSendCallback() is called) -@item (HandleSendCallback() is called by socket, since space now available) -@item @code{Send (); // Start sending again} -@end itemize - -Similarly, on the receive side, the socket user does not block on -a call to @code{recv()}. Instead, the application sets a callback -with @code{SetRecvCallback ()} in which the socket will notify the -application when (and how much) there is data to be read, and -the application then calls @code{Recv()} to read the data until -no more can be read. - -@subsection Packet vs. buffer variants - -There are two basic variants of @code{Send()} and @code{Recv()} supported: -@verbatim - virtual int Send (Ptr p) = 0; - int Send (const uint8_t* buf, uint32_t size); - - Ptr Recv (void); - int Recv (uint8_t* buf, uint32_t size); -@end verbatim - -The non-Packet variants are left for legacy API reasons. When calling -the raw buffer variant of @code{Send()}, the buffer is immediately -written into a Packet and the @code{Send (Ptr p)} is invoked. - -Users may find it semantically odd to pass a Packet to a stream socket -such as TCP. However, do not let the name bother you; think of -@code{ns3::Packet} to be a fancy byte buffer. There are a few reasons why -the Packet variants are more likely to be preferred in ns-3: - -@itemize @bullet -@item Users can use the Tags facility of packets to, for example, encode -a flow ID or other helper data. -@item Users can exploit the copy-on-write implementation to avoid -memory copies (on the receive side, the conversion back to a -@code{uint8_t* buf} may sometimes incur an additional copy). -@item Use of Packet is more aligned with the rest of the ns-3 API -@end itemize - -@subsection Sending dummy data - -Sometimes, users want the simulator to just pretend that there is an -actual data payload in the packet (e.g. to calculate transmission delay) -but do not want to actually produce or consume the data. This is -straightforward to support in ns-3; have applications call -@code{Create (size);} instead of @code{Create (buffer, size);}. -Similarly, passing in a zero to the pointer argument in the raw buffer -variants has the same effect. Note that, if some subsequent code tries -to read the Packet data buffer, the fake buffer will be converted to -a real (zero'ed) buffer on the spot, and the efficiency will be lost there. - -@subsection Socket options - -@emph{to be completed} - -@subsection Socket errno - -@emph{to be completed} - -@subsection Example programs - -@emph{to be completed} - -@section POSIX-like sockets API - -@emph{this capability is under development and is scheduled for -inclusion in August 2008 timeframe; see the repository -http://code.nsnam.org/mathieu/ns-3-simu for details} - -The below is excerpted from Mathieu's post to ns-developers list -on April 4, 2008. - -"To summarize, the goal is that the full posix/socket API is defined in -src/process/simu.h: each posix type and function is re-defined there -with a simu_ or SIMU_ prefix to avoid ugly name clashes and collisions -(feel free to come up with a better prefix). - -Each process is created with a call to ProcessManager::Create and is -attached to that ProcessManager instance. So, if the ProcessManager -(which is aggregated to a Node in src/helper/process-helper.cc) is -killed when the simulation ends, the system will automatically reclaim -all the resources of each process associated to each manager. The same -happens when an application "exits" from its main function. - -The example application defines two posix "processes": the function -ClientProgram creates a udp socket on the localhost port 2000 and the -function ServerProgram creates a udp socket on the localhost port 2000. -The code does not work right now because I did not get the details of -simu_read right yet but, I do plan to make this work at some point. - -I really think that this approach is worthwhile for many reasons, a few -of which are outlined below: -@itemize @bullet -@item makes porting real world application code _much_ easier - -@item makes write applications for new users much easier because they can -read the bsd socket api reference and documentation and write code -directly. - -@item can be used to write applications which work in both simulation and -in the real world at the same time. To do this, all you have to do is -write your application to use the simu_ API, and, then, you can chose at -compile-time which implementation of that API you want to use: you can -pick one implementation which forwards all calls to the system BSD -socket API or another one which forwards all calls to the attached -ProcessManager. Arguably, I did not implement the version which forwards -to system BSD sockets but, that should be pretty trivial. -@end itemize - -So, anyway, comments about the overall API would be welcome. Students -interested in the gsoc project for real-world code integration should -consider looking at this also." - diff --git a/doc/tutorial/tutorial.texi b/doc/tutorial/tutorial.texi index 64185d03c..d2e7a4813 100644 --- a/doc/tutorial/tutorial.texi +++ b/doc/tutorial/tutorial.texi @@ -92,21 +92,6 @@ Part 3: Reconfiguring Existing ns-3 Scripts * Statistics:: Part 4: Creating New or Revised Topologies * Helper Functions:: -* Other-network-topologies:: -Part 5: Key ns-3 objects and systems -* ns-3 Packets:: -* ns-3 Callbacks:: -* Sockets APIs:: -* ns-3 routing overview:: -Part 6: Extending ns-3 -* Nonlinear-Thinking:: -* Summary:: -* Object-Model:: -* The-Doxygen-Documentation-System:: -* How-To-Change-Things:: -* How-To-Set-Default-Values:: -* How-To-Write-A-New-Application:: -@ Troubleshooting @end menu @include introduction.texi @@ -114,13 +99,6 @@ Part 6: Extending ns-3 @include attributes.texi @include statistics.texi @include helpers.texi -@include packets.texi -@include callbacks.texi -@include sockets.texi -@c @include output.texi -@include routing.texi -@c @include other.texi -@include troubleshoot.texi @printindex cp From c11554b553b0ed268ebd155c88129f3b15a10916 Mon Sep 17 00:00:00 2001 From: Tom Henderson Date: Sun, 15 Jun 2008 21:38:13 -0700 Subject: [PATCH 011/495] Split out non-tutorial sections from tutorial; place into a doc/manual directory --- doc/manual/Makefile | 49 + doc/manual/attributes.texi | 535 ++++++ doc/manual/callbacks.texi | 330 ++++ doc/manual/figures/README | 18 + doc/manual/figures/buffer.dia | 1623 +++++++++++++++++ doc/manual/figures/packet.obj | 227 +++ doc/manual/figures/sockets-overview.dia | Bin 0 -> 2222 bytes doc/manual/log.texi | 24 + doc/manual/manual.css | 156 ++ doc/manual/manual.texi | 97 + doc/manual/other.texi | 2189 +++++++++++++++++++++++ doc/manual/output.texi | 462 +++++ doc/manual/packets.texi | 620 +++++++ doc/manual/routing.texi | 373 ++++ doc/manual/sockets.texi | 243 +++ doc/manual/statistics.texi | 9 + doc/manual/troubleshoot.texi | 82 + 17 files changed, 7037 insertions(+) create mode 100644 doc/manual/Makefile create mode 100644 doc/manual/attributes.texi create mode 100644 doc/manual/callbacks.texi create mode 100644 doc/manual/figures/README create mode 100644 doc/manual/figures/buffer.dia create mode 100644 doc/manual/figures/packet.obj create mode 100644 doc/manual/figures/sockets-overview.dia create mode 100644 doc/manual/log.texi create mode 100644 doc/manual/manual.css create mode 100644 doc/manual/manual.texi create mode 100644 doc/manual/other.texi create mode 100644 doc/manual/output.texi create mode 100644 doc/manual/packets.texi create mode 100644 doc/manual/routing.texi create mode 100644 doc/manual/sockets.texi create mode 100644 doc/manual/statistics.texi create mode 100644 doc/manual/troubleshoot.texi diff --git a/doc/manual/Makefile b/doc/manual/Makefile new file mode 100644 index 000000000..8e60864ed --- /dev/null +++ b/doc/manual/Makefile @@ -0,0 +1,49 @@ +TEXI2HTML = texi2html +TEXI2PDF = texi2dvi --pdf +EPSTOPDF = epstopdf +TGIF = tgif +DIA = dia +CONVERT = convert +CSS = --css-include=manual.css +SPLIT = --split section + +DIA_SOURCES = buffer.dia sockets-overview.dia +TGIF_SOURCES = packet.obj + +DIA_EPS = ${DIA_SOURCES:.dia=.eps} +DIA_PNG = ${DIA_SOURCES:.dia=.png} +DIA_PDF = ${DIA_SOURCES:.dia=.pdf} + +TGIF_EPS = ${TGIF_SOURCES:.obj=.eps} +TGIF_PNG = ${TGIF_SOURCES:.obj=.png} +TGIF_PDF = ${TGIF_SOURCES:.obj=.pdf} + +all: images html split-html pdf + +# Note: tgif requires a valid x display to convert from .obj to .png. +# If running this makefile on a remote console, the X virtual frame +# buffer may be needed (xorg-x11-server-Xvfb) to provide a "fake" +# display +images: + cd figures/; $(DIA) -t png $(DIA_SOURCES) + cd figures/; $(DIA) -t eps $(DIA_SOURCES) + cd figures/; $(foreach FILE,$(DIA_EPS),$(EPSTOPDF) $(FILE);) + cd figures/; $(TGIF) -print -png $(TGIF_SOURCES) + cd figures/; $(TGIF) -print -eps $(TGIF_SOURCES) + cd figures/; $(foreach FILE,$(TGIF_EPS),$(EPSTOPDF) $(FILE);) + +html: images + $(TEXI2HTML) ${CSS} manual.texi + +split-html: images + $(TEXI2HTML) ${CSS} ${SPLIT} manual.texi + +pdf: images + $(TEXI2PDF) manual.texi + +figures-clean: + cd figures/; rm -rf $(DIA_EPS); rm -rf $(DIA_PNG); rm -rf $(DIA_PDF) + cd figures/; rm -rf $(TGIF_EPS); rm -rf $(TGIF_PNG); rm -rf $(TGIF_PDF) + +clean: figures-clean + rm -rf manual.aux manual.cp manual.cps manual.fn manual.ky manual.pg manual.tp manual.vr manual.toc manual.log manual.pdf manual.html manual/ diff --git a/doc/manual/attributes.texi b/doc/manual/attributes.texi new file mode 100644 index 000000000..192d6a8fe --- /dev/null +++ b/doc/manual/attributes.texi @@ -0,0 +1,535 @@ +@node ns-3 Attributes +@chapter ns-3 Attributes +@anchor{chap:Attributes} + +In ns-3 simulations, there are two main aspects to configuration: +@itemize @bullet +@item the simulation topology and how objects are connected +@item the values used by the models instantiated in the topology +@end itemize + +This chapter focuses on the second item above: how the many values +in use in ns-3 are organized, documented, and modifiable by ns-3 users. +The ns-3 attribute system is also the underpinning of how traces +and statistics are gathered in the simulator. + +Before delving into details of the attribute value system, +it will help to review some basic properties of @code{class ns3::Object}. + +@node Object Overview +@section Object Overview + +ns-3 is fundamentally a C++ object-based system. By this we mean that +new C++ classes (types) can be declared, defined, and subclassed +as usual. + +Many ns-3 objects inherit from the @code{ns3::Object} base class. These +objects have some additional properties that we exploit for +organizing the system and improving the memory management +of our objects: + +@itemize @bullet +@item a "metadata" system that links the class name to a lot of +meta-information about the object, including the base class of the subclass, +the set of accessible constructors in the subclass, and the set of +"attributes" of the subclass +@item a reference counting smart pointer implementation, for memory +management. +@end itemize + +ns-3 objects that use the attribute system derive from either +@code{ns3::Object} or @code{ns3::ObjectBase}. Most ns-3 objects +we will discuss derive from @code{ns3::Object}, but a few that +are outside the smart pointer memory management framework derive +from @code{ns3::ObjectBase}. + +Let's review a couple of properties of these objects. + +@node Smart pointers +@subsection Smart pointers + +As introduced above in @ref{Smart Pointers 101}, ns-3 objects +are memory managed by a +@uref{http://en.wikipedia.org/wiki/Smart_pointer,,reference counting smart pointer implementation}, @code{class ns3::Ptr}. + +Smart pointers are used extensively in the ns-3 APIs, to avoid passing +references to heap-allocated objects that may cause memory leaks. +For most basic usage (syntax), treat a smart pointer like a regular pointer: +@verbatim + Ptr nd = ...; + nd->CallSomeFunction (); + // etc. +@end verbatim + +@node CreateObject +@subsection CreateObject + +As we discussed above in @ref{Object Creation}, +at the lowest-level API, objects of type @code{ns3::Object} are +not instantiated using @code{operator new} as usual but instead by +a templated function called @code{CreateObject()}. + +A typical way to create such an object is as follows: +@verbatim + Ptr nd = CreateObject (); +@end verbatim + +You can think of this as being functionally equivalent to: +@verbatim + WifiNetDevice* nd = new WifiNetDevice (); +@end verbatim + +Objects that derive from @code{ns3::Object} must be allocated +on the heap using CreateObject(). Those deriving from +@code{ns3::ObjectBase}, such as ns-3 helper functions and packet +headers and trailers, can be allocated on the stack. + +In some scripts, you may not see a lot of CreateObject() calls +in the code; +this is because there are some helper objects in effect that +are doing the CreateObject()s for you. + +@node TypeId +@subsection TypeId + +ns-3 classes that derive from class ns3::Object can include +a metadata class called @code{TypeId} that records meta-information +about the class, for use in the object aggregation and component +manager systems: +@itemize @bullet + @item a unique string identifying the class + @item the base class of the subclass, within the metadata system + @item the set of accessible constructors in the subclass +@end itemize + +@node Object Summary +@subsection Object Summary + +Putting all of these concepts together, let's look at a specific +example: @code{class ns3::Node}. + +The public header file node.h has a declaration that includes +a static GetTypeId function call: +@verbatim +class Node : public Object +{ +public: + static TypeId GetTypeId (void); + ... +@end verbatim + +This is defined in the node.cc file as follows: +@verbatim +TypeId +Node::GetTypeId (void) +{ + static TypeId tid = TypeId ("ns3::Node") + .SetParent () + return tid; +} +@end verbatim +Finally, when users want to create Nodes, they call: +@verbatim + Ptr n = CreateObject n; +@end verbatim + +We next discuss how attributes (values associated with member variables +or functions of the class) are plumbed into the above TypeId. + +@node Attribute Overview +@section Attribute Overview + +The goal of the attribute system is to organize the access of +internal member objects of a simulation. This goal arises because, +typically in simulation, users will cut and paste/modify existing +simulation scripts, or will use higher-level simulation constructs, +but often will be interested in studying or tracing particular +internal variables. For instance, use cases such as: +@itemize @bullet +@item "I want to trace the packets on the wireless interface only on +the first access point" +@item "I want to trace the value of the TCP congestion window (every +time it changes) on a particular TCP socket" +@item "I want a dump of all values that were used in my simulation." +@end itemize + +Similarly, users may want fine-grained access to internal +variables in the simulation, or may want to broadly change the +initial value used for a particular parameter in all subsequently +created objects. Finally, users may wish to know what variables +are settable and retrievable in a simulation configuration. This +is not just for direct simulation interaction on the command line; +consider also a (future) graphical user interface +that would like to be able to provide a feature whereby a user +might right-click on an node on the canvas and see a hierarchical, +organized list of parameters that are settable on the node and its +constituent member objects, and help text and default values for +each parameter. + +@node Functional overview +@subsection Functional overview + +We provide a way for users to access values deep in the system, without +having to plumb accessors (pointers) through the system and walk +pointer chains to get to them. Consider a class DropTailQueue that +has a member variable that is an unsigned integer @code{m_maxPackets}; +this member variable controls the depth of the queue. + +If we look at the declaration of DropTailQueue, we see the following: +@verbatim +class DropTailQueue : public Queue { +public: + static TypeId GetTypeId (void); + ... + +private: + std::queue > m_packets; + uint32_t m_maxPackets; +}; +@end verbatim + +Let's consider things that a user may want to do with the value of +m_maxPackets: + +@itemize @bullet +@item Set a default value for the system, such that whenever a new +DropTailQueue is created, this member is initialized to that default. +@item Set or get the value on an already instantiated queue. +@end itemize + +The above things typically require providing Set() and Get() functions, +and some type of global default value. + +In the ns-3 attribute system, these value definitions and accessor +functions are moved into the TypeId class; e.g.: +@verbatim +TypeId DropTailQueue::GetTypeId (void) +{ + static TypeId tid = TypeId ("ns3::DropTailQueue") + .SetParent () + .AddConstructor () + .AddAttribute ("MaxPackets", "The maximum number of packets accepted by this DropTailQueue.", + Uinteger (100), + MakeUintegerAccessor (&DropTailQueue::m_maxPackets), + MakeUintegerChecker ()) + ; + + return tid; +} +@end verbatim + +The AddAttribute() method is performing a number of things with this +value: +@itemize @bullet +@item Binding the variable m_maxPackets to a string "MaxPackets" +@item Providing a default value (100 packets) +@item Providing some help text defining the value +@item Providing a "checker" (not used in this example) that can be used to set +bounds on the allowable range of values +@end itemize + +The key point is that now the value of this variable and its default +value are accessible in the attribute namespace, which is based on +strings such as "MaxPackets" and TypeId strings. In the next +section, we will provide an example script that shows how users +may manipulate these values. + +@node Basic usage +@subsection Basic usage + +Let's look at how a user script might access these values. +This is based on the script found at @code{samples/main-attribute-value.cc}, +with some details stripped out. +@verbatim +// +// This is a basic example of how to use the attribute system to +// set and get a value in the underlying system; namely, an unsigned +// integer of the maximum number of packets in a queue +// + +int +main (int argc, char *argv[]) +{ + + // By default, the MaxPackets attribute has a value of 100 packets + // (this default can be observed in the function DropTailQueue::GetTypeId) + // + // Here, we set it to 80 packets. We could use one of two value types: + // a string-based value or a Uinteger value + Config::SetDefault ("ns3::DropTailQueue::MaxPackets", String ("80")); + // The below function call is redundant + Config::SetDefault ("ns3::DropTailQueue::MaxPackets", Uinteger(80)); + + // Allow the user to override any of the defaults and the above + // SetDefaults() at run-time, via command-line arguments + CommandLine cmd; + cmd.Parse (argc, argv); +@end verbatim + +The main thing to notice in the above are the two calls to +@code{Config::SetDefault}. This is how we set the default value +for all subsequently instantiated DropTailQueues. We illustrate +that two types of Value classes, a String and a Uinteger class, +can be used to assign the value to the attribute named by +"ns3::DropTailQueue::MaxPackets". + +Now, we will create a few objects using the low-level API; here, +our newly created queues will not have a m_maxPackets initialized to +100 packets but to 80 packets, because of what we did above with +default values. +@verbatim + Ptr n0 = CreateObject (); + + Ptr net0 = CreateObject (); + n0->AddDevice (net0); + + Ptr q = CreateObject (); + net0->AddQueue(q); +@end verbatim + +At this point, we have created a single node (Node 0) and a +single PointToPointNetDevice (NetDevice 0) and added a +DropTailQueue to it. + +Now, we can manipulate the MaxPackets value of the already +instantiated DropTailQueue. Here are various ways to do that. + +@subsubsection Pointer-based access + +We assume that a smart pointer (Ptr) to a relevant network device is +in hand; here, it is the net0 pointer. + +One way to change the value is to access a pointer to the +underlying queue and modify its attribute. + +First, we observe that we can get a pointer to the (base class) +queue via the PointToPointNetDevice attributes, where it is called +TxQueue +@verbatim + Ptr txQueue = net0->GetAttribute ("TxQueue"); +@end verbatim + +Using the GetObject function, we can perform a safe downcast +to a DropTailQueue, where MaxPackets is a member +@verbatim + Ptr dtq = txQueue->GetObject (); + NS_ASSERT (dtq); +@end verbatim + +Next, we can get the value of an attribute on this queue +We have introduced wrapper "Value" classes for the underlying +data types, similar to Java wrappers around these types, since +the attribute system stores values and not disparate types. +Here, the attribute value is assigned to a Uinteger, and +the Get() method on this value produces the (unwrapped) uint32_t. +@verbatim + Uinteger limit = dtq->GetAttribute ("MaxPackets"); + NS_LOG_INFO ("1. dtq limit: " << limit.Get () << " packets"); +@end verbatim + +Note that the above downcast is not really needed; we could have +done the same using the Ptr even though the attribute +is a member of the subclass +@verbatim + limit = txQueue->GetAttribute ("MaxPackets"); + NS_LOG_INFO ("2. txQueue limit: " << limit.Get () << " packets"); +@end verbatim + +Now, let's set it to another value (60 packets) +@verbatim + txQueue->SetAttribute("MaxPackets", Uinteger (60)); + limit = txQueue->GetAttribute ("MaxPackets"); + NS_LOG_INFO ("3. txQueue limit changed: " << limit.Get () << " packets"); +@end verbatim + +@subsubsection Namespace-based access + +An alternative way to get at the attribute is to use the configuration +namespace. Here, this attribute resides on a known path in this +namespace; this approach is useful if one doesn't have access to +the underlying pointers and would like to configure a specific +attribute with a single statement. +@verbatim + Config::Set ("/NodeList/0/DeviceList/0/TxQueue/MaxPackets", Uinteger (25)); + limit = txQueue->GetAttribute ("MaxPackets"); + NS_LOG_INFO ("4. txQueue limit changed through namespace: " << + limit.Get () << " packets"); +@end verbatim + +We could have also used wildcards to set this value for all nodes +and all net devices (which in this simple example has the same +effect as the previous Set()) +@verbatim + Config::Set ("/NodeList/*/DeviceList/*/TxQueue/MaxPackets", Uinteger (15)); + limit = txQueue->GetAttribute ("MaxPackets"); + NS_LOG_INFO ("5. txQueue limit changed through wildcarded namespace: " << + limit.Get () << " packets"); +@end verbatim + +@node Setting through constructors and helper classes +@subsection Setting through constructors helper classes + +Arbitrary combinations of attributes can be set and fetched from +the helper and low-level APIs; either from the constructors themselves: +@verbatim +Ptr p = CreateObject ("n1", v1, "n2", v2, ...); +@end verbatim +or from the higher-level helper APIs, such as: +@verbatim + mobility.SetPositionAllocator ("GridPositionAllocator", + "MinX", FpValue (-100.0), + "MinY", FpValue (-100.0), + "DeltaX", FpValue (5.0), + "DeltaY", FpValue (20.0), + "GridWidth", UintValue (20), + "LayoutType", "RowFirst"); +@end verbatim + +@node Value classes +@subsection Value classes +Readers will note the new Value classes. These can be thought of as +an intermediate class that can be used to convert from raw types to the +Values that are used by the system. Recall that this database is holding +objects of many types with a single generic type. Conversions to this +type can either be done using an intermediate class (IntValue, FpValue for +"floating point") or via strings. Direct implicit conversion of types +to Value is not really practical. So in the above, users have a choice +of using strings or values: +@verbatim +p->Set ("cwnd", "100"); // string-based setter +p->Set ("cwnd", IntValue(100)); // value-based setter +@end verbatim + +The system provides some macros that help users declare and define +new Value subclasses for new types that they want to introduce into +the attribute system. + +@node Extending attributes +@section Extending attributes + +The ns-3 system will place a number of internal values under the +attribute system, but undoubtedly users will want to extend this +to pick up ones we have missed, or to add their own classes to this. + +@subsection Adding an existing internal variable to the metadata system + +// XXX revise me + +Consider this variable in class TcpSocket: +@verbatim + uint32_t m_cWnd; // Congestion window +@end verbatim + +Suppose that someone working with Tcp wanted to get or set the +value of that variable using the metadata system. If it were not +already provided by ns-3, the user could declare the following addition +in the metadata system (to the TypeId declaration for TcpSocket): +@verbatim + .AddParameter ("Congestion window", + "Tcp congestion window (bytes)", + MakeUIntParamSpec (&TcpSocket::m_cWnd, 1)); + +@end verbatim + +Now, the user with a pointer to the TcpSocket can perform operations +such as setting and getting the value, without having to add these +functions explicitly. Furthermore, access controls can be applied, such +as allowing the parameter to be read and not written, or bounds +checking on the permissible values can be applied. + +@subsection Adding a new TypeId + +Here, we discuss the impact on a user who wants to add a new class to +ns-3; what additional things must be done to hook it into this system. + +We've already introduced what a TypeId definition looks like: +@verbatim +TypeId +RandomWalk2dMobilityModel::GetTypeId (void) +{ + static TypeId tid = TypeId ("RandomWalkMobilityModel") + .SetParent () + .SetGroupName ("Mobility") + .AddConstructor () + // followed by a number of Parameters + .AddParameter ("bounds", + "Bounds of the area to cruise.", + MakeRectangleParamSpec (&RandomWalk2dMobilityModel::m_bounds, Rectangle (0.0, 0.0, 100.0, 100.0))) + .AddParameter ("time", + "Change current direction and speed after moving for this delay.", + MakeTimeParamSpec (&RandomWalk2dMobilityModel::m_modeTime, + Seconds (1.0))) + + // etc (more parameters). +@end verbatim + +The declaration for this in the class declaration is one-line public +member method: +@verbatim + public: + static TypeId GetTypeId (void); +@end verbatim + +@section Adding new class type to the Value system + +From the perspective of the user who writes a new class in the system and +wants to hook it in to the attribute system, there is mainly the matter +of writing +the conversions to/from strings and Values. Most of this can be +copy/pasted with macro-ized code. For instance, consider class +Rectangle in the @code{src/mobility/} directory: + +One line is added to the class declaration: +@verbatim +/** + * \brief a 2d rectangle + */ +class Rectangle +{ +... + + VALUE_HELPER_HEADER_1 (Rectangle); +}; +@end verbatim + +One templatized declaration, and two operators, are added below the +class declaration: + +@verbatim +std::ostream &operator << (std::ostream &os, const Rectangle &rectangle); +std::istream &operator >> (std::istream &is, Rectangle &rectangle); + +VALUE_HELPER_HEADER_2 (Rectangle); +@end verbatim + +In the class definition, the code looks like this: + +@verbatim +VALUE_HELPER_CPP (Rectangle); + +std::ostream & +operator << (std::ostream &os, const Rectangle &rectangle) +{ + os << rectangle.xMin << "|" << rectangle.xMax << "|" << rectangle.yMin << "|" << rectangle.yMax; + return os; +} +std::istream & +operator >> (std::istream &is, Rectangle &rectangle) + { + char c1, c2, c3; + is >> rectangle.xMin >> c1 >> rectangle.xMax >> c2 >> rectangle.yMin >> c3 >> rectangle.yMax; + if (c1 != '|' || + c2 != '|' || + c3 != '|') + { + is.setstate (std::ios_base::failbit); + } + return is; +} +@end verbatim + +These stream operators simply convert from a string representation of the +Rectangle ("xMin|xMax|yMin|yMax") to the underlying Rectangle, and the +modeler must specify these operators and the string syntactical representation +of an instance of the new class. + diff --git a/doc/manual/callbacks.texi b/doc/manual/callbacks.texi new file mode 100644 index 000000000..377689975 --- /dev/null +++ b/doc/manual/callbacks.texi @@ -0,0 +1,330 @@ +@node ns-3 Callbacks +@chapter ns-3 Callbacks + +Some new users to @command{ns-3} are unfamiliar with an extensively used +programming idiom used throughout the code: the ``ns-3 callback''. This +chapter provides some motivation on the callback, guidance on how to use +it, and details on its implementation. + +@menu +* Motivation:: +* Using the Callback API:: +* Callback locations in ns-3:: +* Implementation details:: +@end menu + +@node Motivation +@section Motivation + +Consider that you have two simulation models A and B, and you wish +to have them pass information between them during the simulation. One +way that you can do that is that you can make A and B each explicitly +knowledgable about the other, so that they can invoke methods on each +other. + +@verbatim +class A { +public: + void ReceiveInput ( // parameters ); + ... +} + +(in another source file:) + +class B { +public: + void ReceiveInput ( // parameters); + void DoSomething (void); + ... + +private: + A* a_instance; // pointer to an A +} + +void +B::DoSomething() +{ + // Tell a_instance that something happened + a_instance->ReceiveInput ( // parameters); + ... +} +@end verbatim + +This certainly works, but it has the drawback that it introduces a +dependency on A and B to know about the other at compile time (this +makes it harder to have independent compilation units in the simulator) +and is not generalized; if in a later usage scenario, B needs to talk +to a completely different C object, the source code for B needs to be +changed to add a ``c_instance'' and so forth. It is easy to see that +this is a brute force mechanism of communication that can lead to +programming cruft in the models. + +This is not to say that objects should not know about one another +if there is a hard dependency between them, but that often the model +can be made more flexible if its interactions are less constrained at +compile time. + +This is not an abstract problem for network simulation research, +but rather it has been a source of problems in previous simulators, +when researchers want to extend or modify the system to do different +things (as they are apt to do in research). Consider, for example, +a user who wants to add an IPsec security protocol sublayer +between TCP and IP: +@verbatim +------------ ----------- +| TCP | | TCP | +------------ ----------- + | becomes -> | +----------- ----------- +| IP | | IPsec | +----------- ----------- + | + ----------- + | IP | + ----------- +@end verbatim +If the simulator has +made assumptions, and hard coded into the code, that IP always talks +to a transport protocol above, the user may be forced to hack the +system to get the desired interconnections. + +An alternative that provides this flexibility is to use a level of +indirection that is commonly known in programming as a callback. +A callback function is not invoked explicitly by the caller but is +rather delegated to another function that receives the callback +function's address and can call it. + +You may be familiar with function pointers in C or C++; these can +be used to implement callbacks. For more information on introductory +callbacks, an online reference is: +@uref{http://www.inquiry.com/techtips/cpp_pro/10min/10min0300.asp,,Declaring Function Pointers and Implementing Callbacks} and +@uref{http://en.wikipedia.org/wiki/Callback_(computer_science),,Callback (computer science)-- Wikipedia}. + +The callback API in @command{ns-3} is designed to minimize the overall +coupling between various pieces of of the simulator +by making each module depend on the callback API +itself rather than depend on other modules. It acts as a sort of +third-party to which work is delegated and which forwards this +work to the proper target module. This callback API, being based +on C++ templates, +is type-safe; that is, it performs static type checks to enforce +proper signature compatibility between callers and callees. It +is therefore more type-safe to use than traditional function +pointers, but the syntax may look imposing at first. This section +is designed to walk you through the callback system so that you +can be comfortable using it in @command{ns-3}. + +@node Using the Callback API +@section Using the Callback API + +The Callback API is fairly minimal, providing only two services: +@itemize @bullet +@item callback type declaration: a way to declare a type of callback +with a given signature, and, +@item callback instantiation: a way to instantiate a +template-generated forwarding callback which can forward any calls +to another C++ class member method or C++ function. +@end itemize + +This is best observed via walking through an example, based on +@code{samples/main-callback.cc}. + +@node Using the Callback API with static functions +@subsection Using the Callback API with static functions + +Consider a function: +@verbatim +static double +CbOne (double a, double b) +{ + std::cout << "invoke cbOne a=" << a << ", b=" << b << std::endl; + return a; +} +@end verbatim + +Consider also the following main program snippett: +@verbatim +int main (int argc, char *argv[]) +{ + // return type: double + // first arg type: double + // second arg type: double + Callback one; +} +@end verbatim + +This class template Callback implements what is known as the Functor +Design Pattern. It is used to declare the type of a callback. It contains +one mandatory argument (the return type of the function to be assigned +to this callback) and up to five optional arguments, which each specify +the type of the arguments (if your function has more than five arguments, +then this can be handled by extending the callback implementation). + +So in the above, we have a declared a callback named "one" that will +eventually hold a function pointer. The function that it will hold +must return double and must support two double arguments. If one +tries to pass a function whose signature does not match the declared +callback, the compilation will fail. + +Now, we need to tie together this callback instance and the actual +target function (CbOne). Notice above that CbOne has the same function +signature types as the callback-- this is important. We can +pass in any such properly-typed function to this callback. Let's +look at this more closely: +@verbatim +static double CbOne (double a, double b) {} + ^ ^ ^ + | ---| ------| + | | | +Callback one; +@end verbatim +You can only bind a function to a callback if they have the matching +signature. The first template argument is the return type, and the +additional template arguments are the types of the arguments of +the function signature. + +Now, let's bind our callback "one" to the function that matches its +signature: +@verbatim + // build callback instance which points to cbOne function + one = MakeCallback (&CbOne); +@end verbatim + +Then, later in the program, if the callback is to be used, it can be +used as follows: +@verbatim +// this is not a null callback + NS_ASSERT (!one.IsNull ()); + // invoke cbOne function through callback instance + double retOne; + retOne = one (10.0, 20.0); +@end verbatim + +The check @code{IsNull()} ensures that the callback is not null; that there +is a function to call behind this callback. Then, @code{one()} returns the +same result as if @code{CbOne()} had been called directly. + + +@node Using the Callback API with member functions +@subsection Using the Callback API with member functions + +Generally, you will not be calling static functions but instead +public member functions of an object. In this case, an extra +argument is needed to the MakeCallback function, to tell the system +on which object the function should be invoked. Consider this example, +also from main-callback.cc: + +@verbatim +class MyCb { +public: + int CbTwo (double a) { + std::cout << "invoke cbTwo a=" << a << std::endl; + return -5; + } +}; + +int main () +{ + ... + // return type: int + // first arg type: double + Callback two; + MyCb cb; + // build callback instance which points to MyCb::cbTwo + two = MakeCallback (&MyCb::CbTwo, &cb); + ... +} +@end verbatim + +Here, we pass a (raw) pointer to the @code{MakeCallback<>} function, +that says, when @code{two ()} is invoked, to call the @code{CbTwo} function +on the object pointed to by @code{&cb}. + +A variation of this is used when objects are referred to by ns-3 smart +pointers. The MakeCallback API takes a raw pointer, so we need to +call @code{PeekPointer ()} to obtain this raw pointer. So the example +above would look like: + +@verbatim +class MyCb : public Object { +public: + int CbTwo (double a) { + std::cout << "invoke cbTwo a=" << a << std::endl; + return -5; + } +}; + +int main () +{ + ... + // return type: int + // first arg type: double + Callback two; + Ptr cb = CreateObject (); + // build callback instance which points to MyCb::cbTwo + two = MakeCallback (&MyCb::CbTwo, PeekPointer (cb)); + ... +} +@end verbatim + +@node Building Null Callbacks +@subsection Building Null Callbacks + +It is possible for callbacks to be null; hence it may be wise to +check before using them. There is a special construct for a null +callback, which is preferable to simply passing "0" as an argument; +it is the @code{MakeNullCallback<>} construct: +@verbatim + two = MakeNullCallback (); + // invoking a null callback is just like + // invoking a null function pointer: + // it will crash at runtime. + //int retTwoNull = two (20.0); + NS_ASSERT (two.IsNull ()); +@end verbatim + +@node Callback locations in ns-3 +@section Callback locations in @command{ns-3} + +Where are callbacks frequently used in @command{ns-3}? Here are some of the +more visible ones to typical users: + +@subsection Socket API +@subsection Layer-2/Layer-3 API +@subsection Tracing subsystem +@subsection Routing +Route Reply + +@node Implementation details +@section Implementation details + +This section is advanced explanation for C++ experts interested in +the implementation, and may be skipped by most users. + +This code was originally written based on the techniques described +@uref{http://www.codeproject.com/cpp/TTLFunction.asp,,here}. +It was subsequently rewritten to follow the architecture +outlined in +@uref{http://www.amazon.com/Modern-C\%2B\%2B-Design-Programming-Patterns/dp/0201704315/ref=pd_bbs_sr_1/102-0157303-1900156?ie=UTF8\&s=books\&qid=1187982662\&sr=1-1,,Modern C++ Design: Generic Programming and Design Patterns Applied-- Alexandrescu}, chapter 5, "Generalized Functors". + +This code uses: +@itemize @bullet +@item default template parameters to saves users from having to +specify empty parameters when the number of parameters +is smaller than the maximum supported number +@item the pimpl idiom: the Callback class is passed around by +value and delegates the crux of the work to its pimpl pointer. +@item two pimpl implementations which derive from CallbackImpl +FunctorCallbackImpl can be used with any functor-type +while MemPtrCallbackImpl can be used with pointers to +member functions. +@item a reference list implementation to implement the Callback's +value semantics. +@end itemize + +This code most notably departs from the Alexandrescu +implementation in that it does not use type lists to specify +and pass around the types of the callback arguments. +Of course, it also does not use copy-destruction semantics +and relies on a reference list rather than autoPtr to hold +the pointer. diff --git a/doc/manual/figures/README b/doc/manual/figures/README new file mode 100644 index 000000000..4f63268dc --- /dev/null +++ b/doc/manual/figures/README @@ -0,0 +1,18 @@ +Please write image files in a vector graphics format, when possible, and +generate the .png and .pdf versions on the fly (see ../Makefile). + +Currently supported tools are dia and tgif. xfig could be added similarly +if someone wants to add it. The main requirement for adding another format +is that the tool to edit it is freely available and that a cron script can +autogenerate the pdf and png from the figure source. + +Store the .dia, or .obj versions in mercurial, but not the .png or .pdfs. +If the figure is not available in a vector graphics format, store both +a .png and a .pdf version in this directory. + +If you add a source (.dia, .obj) file here, remember to add it to +the list of figure sources in the Makefile in the directory above + +Note: tgif can convert from .obj to .pdf, but the pdf that results takes +up a whole page. Instead, we convert to an intermediate .eps step, and +then run epstopdf. diff --git a/doc/manual/figures/buffer.dia b/doc/manual/figures/buffer.dia new file mode 100644 index 000000000..b1868f7f4 --- /dev/null +++ b/doc/manual/figures/buffer.dia @@ -0,0 +1,1623 @@ + + + + + + + + + + + + + #A4# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #Count# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #Size# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #Initial Start# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #Dirty Start# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #Unused Area# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #Dirty Size# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #Dirty Area# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #Virtual Zero Area# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #Unused Area# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #Data# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #Zero Area Size# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #Used start# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #Used Size# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #Data# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #Zero Area Size# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #Used start# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #Used Size# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #Used# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #Used# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #Virtual Zero Area# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #Buffer# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #BufferData# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #Buffer# + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/doc/manual/figures/packet.obj b/doc/manual/figures/packet.obj new file mode 100644 index 000000000..c6a66cd71 --- /dev/null +++ b/doc/manual/figures/packet.obj @@ -0,0 +1,227 @@ +%TGIF 4.1.43-QPL +state(0,37,100.000,0,64,0,32,0,9,1,1,1,0,0,0,1,0,'Courier-Bold',1,103680,0,3,0,10,0,0,1,1,0,16,0,0,1,1,1,1,1088,1408,1,0,2880,0). +% +% @(#)$Header$ +% %W% +% +unit("1 pixel/pixel"). +color_info(11,65535,0,[ + "magenta", 65535, 0, 65535, 65535, 0, 65535, 1, + "red", 65535, 0, 0, 65535, 0, 0, 1, + "green", 0, 65535, 0, 0, 65535, 0, 1, + "blue", 0, 0, 65535, 0, 0, 65535, 1, + "yellow", 65535, 65535, 0, 65535, 65535, 0, 1, + "pink", 65535, 49344, 52171, 65535, 49344, 52171, 1, + "cyan", 0, 65535, 65535, 0, 65535, 65535, 1, + "CadetBlue", 24415, 40606, 41120, 24415, 40606, 41120, 1, + "white", 65535, 65535, 65535, 65535, 65535, 65535, 1, + "black", 0, 0, 0, 0, 0, 0, 1, + "DarkSlateGray", 12079, 20303, 20303, 12079, 20303, 20303, 1 +]). +script_frac("0.6"). +fg_bg_colors('black','white'). +dont_reencode("FFDingbests:ZapfDingbats"). +page(1,"",1,''). +box('black','',32,48,240,256,0,3,1,0,0,0,0,0,0,'3',0,[ +]). +text('black',64,10,1,0,1,121,28,3,22,6,0,0,0,0,2,121,28,0,0,"",0,0,0,0,32,'',[ +minilines(121,28,0,0,0,0,0,[ +mini_line(121,22,6,0,0,0,[ +str_block(0,121,22,6,0,0,0,0,0,[ +str_seg('black','Times-Roman',0,138240,121,22,6,0,0,0,0,0,0,0, + "class Packet")]) +]) +])]). +text('black',416,100,1,0,1,116,28,15,22,6,0,0,0,0,2,116,28,0,0,"",0,0,0,0,122,'',[ +minilines(116,28,0,0,0,0,0,[ +mini_line(116,22,6,0,0,0,[ +str_block(0,116,22,6,0,0,0,0,0,[ +str_seg('black','Times-Roman',0,138240,116,22,6,0,0,0,0,0,0,0, + "class Buffer")]) +]) +])]). +text('black',48,178,4,0,1,83,69,32,14,4,0,0,0,0,2,83,69,0,0,"",0,0,0,0,192,'',[ +minilines(83,69,0,0,0,0,0,[ +mini_line(80,14,4,0,0,0,[ +str_block(0,80,14,4,0,-1,0,0,0,[ +str_seg('black','Times-Bold',1,80640,80,14,4,0,-1,0,0,0,0,0, + "private data:")]) +]), +mini_line(59,14,3,0,0,0,[ +str_block(0,59,14,3,0,0,0,0,0,[ +str_seg('black','Times-Roman',0,80640,59,14,3,0,0,0,0,0,0,0, + "- unique id")]) +]), +mini_line(83,14,3,0,0,0,[ +str_block(0,83,14,3,0,0,0,0,0,[ +str_seg('black','Times-Roman',0,80640,83,14,3,0,0,0,0,0,0,0, + "- Buffer object")]) +]), +mini_line(76,14,3,0,0,0,[ +str_block(0,76,14,3,0,0,0,0,0,[ +str_seg('black','Times-Roman',0,80640,76,14,3,0,0,0,0,0,0,0, + "- Tags object")]) +]) +])]). +text('black',112,288,1,0,1,103,28,82,22,6,0,0,0,0,2,103,28,0,0,"",0,0,0,0,310,'',[ +minilines(103,28,0,0,0,0,0,[ +mini_line(103,22,6,0,0,0,[ +str_block(0,103,22,6,0,-1,0,0,0,[ +str_seg('black','Times-Roman',0,138240,103,22,6,0,-1,0,0,0,0,0, + "class Tags")]) +]) +])]). +text('black',48,50,5,0,1,175,86,176,14,4,0,0,0,0,2,175,86,0,0,"",0,0,0,0,64,'',[ +minilines(175,86,0,0,0,0,0,[ +mini_line(105,14,4,0,0,0,[ +str_block(0,105,14,4,0,-1,0,0,0,[ +str_seg('black','Times-Bold',1,80640,105,14,4,0,-1,0,0,0,0,0, + "public functions:")]) +]), +mini_line(80,14,3,0,0,0,[ +str_block(0,80,14,3,0,-1,0,0,0,[ +str_seg('black','Times-Roman',0,80640,80,14,3,0,-1,0,0,0,0,0, + "- constructors")]) +]), +mini_line(175,14,3,0,0,0,[ +str_block(0,175,14,3,0,-1,0,0,0,[ +str_seg('black','Times-Roman',0,80640,175,14,3,0,-1,0,0,0,0,0, + "- add/remove/peek at Headers")]) +]), +mini_line(155,14,3,0,0,0,[ +str_block(0,155,14,3,0,-1,0,0,0,[ +str_seg('black','Times-Roman',0,80640,155,14,3,0,-1,0,0,0,0,0, + "- add/remove/peek at Tags")]) +]), +mini_line(88,14,3,0,0,0,[ +str_block(0,88,14,3,0,0,0,0,0,[ +str_seg('black','Times-Roman',0,80640,88,14,3,0,0,0,0,0,0,0, + "- fragmentation")]) +]) +])]). +box('black','',384,144,614,352,0,3,1,245,0,0,0,0,0,'3',0,[ +]). +text('black',400,274,4,0,1,204,69,246,14,4,0,0,0,0,2,204,69,0,0,"",0,0,0,0,288,'',[ +minilines(204,69,0,0,0,0,0,[ +mini_line(80,14,4,0,0,0,[ +str_block(0,80,14,4,0,-1,0,0,0,[ +str_seg('black','Times-Bold',1,80640,80,14,4,0,-1,0,0,0,0,0, + "private data:")]) +]), +mini_line(193,14,3,0,0,0,[ +str_block(0,193,14,3,0,0,0,0,0,[ +str_seg('black','Times-Roman',0,80640,193,14,3,0,0,0,0,0,0,0, + "- struct BufferData, a dynamically")]) +]), +mini_line(160,14,3,0,0,0,[ +str_block(0,160,14,3,0,0,0,0,0,[ +str_seg('black','Times-Roman',0,80640,160,14,3,0,0,0,0,0,0,0, + "varying byte buffer to which")]) +]), +mini_line(204,14,3,0,0,0,[ +str_block(0,204,14,3,0,0,0,0,0,[ +str_seg('black','Times-Roman',0,80640,204,14,3,0,0,0,0,0,0,0, + "data can be prepended or appended")]) +]) +])]). +text('black',400,146,5,0,1,188,86,247,14,4,0,0,0,0,2,188,86,0,0,"",0,0,0,0,160,'',[ +minilines(188,86,0,0,0,0,0,[ +mini_line(105,14,4,0,0,0,[ +str_block(0,105,14,4,0,-1,0,0,0,[ +str_seg('black','Times-Bold',1,80640,105,14,4,0,-1,0,0,0,0,0, + "public functions:")]) +]), +mini_line(172,14,3,0,0,0,[ +str_block(0,172,14,3,0,0,0,0,0,[ +str_seg('black','Times-Roman',0,80640,172,14,3,0,0,0,0,0,0,0, + "- Iterators to move byte buffer")]) +]), +mini_line(171,14,3,0,0,0,[ +str_block(0,171,14,3,0,0,0,0,0,[ +str_seg('black','Times-Roman',0,80640,171,14,3,0,0,0,0,0,0,0, + "pointers forward or backward")]) +]), +mini_line(188,14,3,0,0,0,[ +str_block(0,188,14,3,0,0,0,0,0,[ +str_seg('black','Times-Roman',0,80640,188,14,3,0,0,0,0,0,0,0, + "- functions to read and write data")]) +]), +mini_line(132,14,3,0,0,0,[ +str_block(0,132,14,3,0,-1,0,0,0,[ +str_seg('black','Times-Roman',0,80640,132,14,3,0,-1,0,0,0,0,0, + "of various sized chunks")]) +]) +])]). +box('black','',96,324,304,532,0,3,1,264,0,0,0,0,0,'3',0,[ +]). +text('black',112,454,4,0,1,167,69,265,14,4,0,0,0,0,2,167,69,0,0,"",0,0,0,0,468,'',[ +minilines(167,69,0,0,0,0,0,[ +mini_line(80,14,4,0,0,0,[ +str_block(0,80,14,4,0,-1,0,0,0,[ +str_seg('black','Times-Bold',1,80640,80,14,4,0,-1,0,0,0,0,0, + "private data:")]) +]), +mini_line(167,14,3,0,0,0,[ +str_block(0,167,14,3,0,0,0,0,0,[ +str_seg('black','Times-Roman',0,80640,167,14,3,0,0,0,0,0,0,0, + "- singly linked-list of TagData")]) +]), +mini_line(158,14,3,0,0,0,[ +str_block(0,158,14,3,0,0,0,0,0,[ +str_seg('black','Times-Roman',0,80640,158,14,3,0,0,0,0,0,0,0, + "structures, with a reference")]) +]), +mini_line(32,14,3,0,0,0,[ +str_block(0,32,14,3,0,0,0,0,0,[ +str_seg('black','Times-Roman',0,80640,32,14,3,0,0,0,0,0,0,0, + "count")]) +]) +])]). +text('black',112,326,5,0,1,155,86,266,14,4,0,0,0,0,2,155,86,0,0,"",0,0,0,0,340,'',[ +minilines(155,86,0,0,0,0,0,[ +mini_line(105,14,4,0,0,0,[ +str_block(0,105,14,4,0,-1,0,0,0,[ +str_seg('black','Times-Bold',1,80640,105,14,4,0,-1,0,0,0,0,0, + "public functions:")]) +]), +mini_line(80,14,3,0,0,0,[ +str_block(0,80,14,3,0,-1,0,0,0,[ +str_seg('black','Times-Roman',0,80640,80,14,3,0,-1,0,0,0,0,0, + "- constructors")]) +]), +mini_line(155,14,3,0,0,0,[ +str_block(0,155,14,3,0,-1,0,0,0,[ +str_seg('black','Times-Roman',0,80640,155,14,3,0,-1,0,0,0,0,0, + "- templates to add, remove,")]) +]), +mini_line(148,14,3,0,0,0,[ +str_block(0,148,14,3,0,-1,0,0,0,[ +str_seg('black','Times-Roman',0,80640,148,14,3,0,-1,0,0,0,0,0, + "or peek at Tags of various")]) +]), +mini_line(31,14,3,0,0,0,[ +str_block(0,31,14,3,0,-1,0,0,0,[ +str_seg('black','Times-Roman',0,80640,31,14,3,0,-1,0,0,0,0,0, + "types")]) +]) +])]). +poly('black','',2,[ + 59,245,96,320],0,2,1,272,0,0,3,0,0,0,0,'2',0,0, + "0","",[ + 0,10,4,0,'10','4','0'],[0,10,4,0,'10','4','0'],[ +]). +poly('black','',2,[ + 123,246,288,320],0,2,1,280,0,0,3,0,0,0,0,'2',0,0, + "0","",[ + 0,10,4,0,'10','4','0'],[0,10,4,0,'10','4','0'],[ +]). +poly('black','',2,[ + 141,219,379,147],0,2,1,286,0,0,3,0,0,0,0,'2',0,0, + "0","",[ + 0,10,4,0,'10','4','0'],[0,10,4,0,'10','4','0'],[ +]). +poly('black','',2,[ + 132,226,375,335],0,2,1,287,0,0,3,0,0,0,0,'2',0,0, + "0","",[ + 0,10,4,0,'10','4','0'],[0,10,4,0,'10','4','0'],[ +]). diff --git a/doc/manual/figures/sockets-overview.dia b/doc/manual/figures/sockets-overview.dia new file mode 100644 index 0000000000000000000000000000000000000000..af9e583101c90073ef2605e47f9e0ae23a91af05 GIT binary patch literal 2222 zcmV;f2vPSRiwFP!000001MOYkZ{s!+e)nG?cwe@Fmli4Uht^Gsb`Qlp9NGfiJ_oYJ z*t(S^LsB;DKHT4aL&~XRTS^>Jbd!Px659&Hk3$V-z9EOy_dk4FXWmy?R%wx6jWP1a zp3E0TlIF{+@gJXm{vgIbT#vp_()c6%EX#Q9!GGkH`gS#5)%E7%bb5b(kFsqQ*F}l4 z^bS>W`oB2K;wcoGj;}|a_qc*2u48p=cQvl-GM(Sm(#zwuyc*Br#g}DS+~vu*DYYxN zD6*pTzQ)eAhH-cVS;wTSGfR>UCT$)BF?%`X*~Sf*?T%fzF_jhyF+e=68vP_ew2kt?Mj#}>1q+Z>8v(#Np?ORK=e@&}&p2@b>r+GbC z_1j^pKfXKKdhh?;P#c=sI^9DeB$f2#?qPYCCbD`)%?`_S)U?_an?Bd;$K}rLnC8-v zv(^wJPXEgk%Oqapdl;EJ;5qtPu=E?i-MxTm22bt8Ttf(ZsBZNA5#S??E%d!`F-PQ*jq~<3IFgFnt>iF z=9$Xb2k6j1J;7pq-wX)c|1w|8_PZ(byY;Ro&qQf8KV2qty0;!@n3JE1Z!OjYn_3f& zf=OW4m~cd>!kA%>z>a`D>1#)1Cf7HMqRdZ2jKM_G7@CTliuD%_@lkj%u80BF$w)p1 z69|XV<5xehYE|6dv;>~dv+5z#x5FC}Q~ec6xk40L)L+r)ub{ICegT+x{a)~wB9YG9 z+4gp)%IBP2e{1n`R@^UEaan6~QLfWG&RR@HU}`cVL@96-Zqw%hhJu)33LiLl3y!f( zpJyo3IZltFsB?G?@AMFZF7p`|7z;*2-qYr0X)d1=%t!dha9{&4HE8e3Q#;>1lwSgI zn`YS=5QlTee=ARTs;{)SI0oo2MBOt%uhj=T|7$(kBw$?`;(kE?VF4$$;DfugD@!*w ztD;Q*1a$(B`_yrBr52G#KI&j3S#HgCQme1(YBlnq=?^fzQ+hT+RfZ>YrOp9mHV#2e?X$!Qke( z7b+`|P^-BYp~ldrLVXJQfh~$Wzma*OTmLedIuy0P;Gi0d&2bajl7wxCrec856sztM z)+fFJgsZ3&;;IQyB@$4}5viG6XC;vx<&asO@(xjOm_x=~JnG_6H|6aZ*pb~6K+ZA3 z%tfFs0_{aAB4biP5D^z(6-2LV?|4Ns`*HzhVJw`Z7LHmtYT>BG+e_7p9Jg@X!iZa7 z^UbrN^7r=1MX342j$AO!G%i3cjD>UL!jTI{E*!adYve*Ln>%vh$VJbkb8Nhgo~oUo zpoZ8YsQ`>Xp{P7LLT3+<)UBR78`!FWZu#8i@;N30oaCdn@DQ7UNPq&)m`dXfC}lGR z$-)p~1TY(+?Zxy{0b3K_7&OQKTNcy1LX$kXiOaIM@8+b07*>6g$$a^AI6_S!o(*{D zu_=Aj?MRU9s z+~(?pK|K7$TY+LI4~)lNUFfADZ~xa8sFO+uVt2+nJPC$g7a`moCTwcp9tUGiXM`b6 zXf(kvP{|uOd97G{k@YBDZ!)PIyUrZ1M(-tBBJcC3-zK9!{`K3$E93j`938Yx2Rl^O zQ9`SZjt*dHLSKa1=TN(e*t>OT;sY&Iu$%}rgF;B(3Ei_@U5AjZiI!9q1OvzeM-bmW zLG1F-#(NhCQ3oJJD75OHiJp1UdaDjb-C+vhCSaV$ZB;?%ZmpUP;~flGg;5h``{Wjl zLQ%+o)HB37dPE}o+kj!rl_;poIG zrxRgg=qQS?qZ5u!y!hFa#v43{kHW^o6RS+(0VmK;YF2r}K2=K`{0$`;cuj6WDyz|Z z>}_P}Rn2t;Hd5d7B9Sib;4-;P?TYIX4{RnLkYE6N6R4yBb>E`M<}-0IeTZG)ZKl+P zsPthKyo9!Q%5+NEzA;=EW$GEqp-V*gr*1JLq4`r`L%sFO?o(l5bTF>=_eAhMix7md wL7+65Q{VP(%oYh-3+d*(hNF#}?^(Q+<@Kof0zb<#USE&?4|CyAxYdgQ0OMp;RR910 literal 0 HcmV?d00001 diff --git a/doc/manual/log.texi b/doc/manual/log.texi new file mode 100644 index 000000000..2f39efe59 --- /dev/null +++ b/doc/manual/log.texi @@ -0,0 +1,24 @@ +@node Logging +@chapter Logging +@anchor{chap:Logging} + +This chapter is the first in a series of chapters discussing things that +one can do to modify the input or output of existing ns-3 scripts. + +Examples: +@itemize @bullet +@item Enable or disable the generation of log messages, with fine granularity +@item Set default values for configuration values in the system +@item Generate a report of all configuration values used during a simulation +run (not yet implemented) +@item Set or get values of member variables on objects already instantiated +@item Customizing the tracing output of the script +@item Generate statistics on (not yet implemented) +@item Perform a large number of independent runs of the same simulation +@end itemize + +@node Logging Basics +@section Logging Basics + +@node Enabling Log Output +@section Enabling Log Output diff --git a/doc/manual/manual.css b/doc/manual/manual.css new file mode 100644 index 000000000..a7586ac83 --- /dev/null +++ b/doc/manual/manual.css @@ -0,0 +1,156 @@ +body { + font-family: "Trebuchet MS", "Bitstream Vera Sans", verdana, lucida, arial, helvetica, sans-serif; + background: white; + color: black; + font-size: 11pt; +} + +h1, h2, h3, h4, h5, h6 { +# color: #990000; + color: #009999; +} + +pre { + font-size: 10pt; + background: #e0e0e0; + color: black; +} + +a:link, a:visited { + font-weight: normal; + text-decoration: none; + color: #0047b9; +} + +a:hover { + font-weight: normal; + text-decoration: underline; + color: #0047b9; +} + +img { + border: 0px; +} + +#main th { + font-size: 12pt; + background: #b0b0b0; +} + +.odd { + font-size: 12pt; + background: white; +} + +.even { + font-size: 12pt; + background: #e0e0e0; +} + +.answer { + font-size: large; + font-weight: bold; +} + +.answer p { + font-size: 12pt; + font-weight: normal; +} + +.answer ul { + font-size: 12pt; + font-weight: normal; +} + +#container { + position: absolute; + width: 100%; + height: 100%; + top: 0px; +} + +#feedback { + color: #b0b0b0; + font-size: 9pt; + font-style: italic; +} + +#header { + position: absolute; + margin: 0px; + top: 10px; + height:96px; + left: 175px; + right: 10em; + bottom: auto; + background: white; + clear: both; +} + +#middle { + position: absolute; + left: 0; + height: auto; + width: 100%; +} + +#main { + position: absolute; + top: 50px; + left: 175px; + right: 100px; + background: white; + padding: 0em 0em 0em 0em; +} + +#navbar { + position: absolute; + top: 75px; + left: 0em; + width: 146px; + padding: 0px; + margin: 0px; + font-size: 10pt; +} + +#navbar a:link, #navbar a:visited { + font-weight: normal; + text-decoration: none; + color: #0047b9; +} + +#navbar a:hover { + font-weight: normal; + text-decoration: underline; + color: #0047b9; +} + +#navbar dl { + width: 146px; + padding: 0; + margin: 0 0 10px 0px; + background: #99ffff url(images/box_bottom2.gif) no-repeat bottom left; +} + +#navbar dt { + padding: 6px 10px; + font-size: 100%; + font-weight: bold; + background: #009999; + margin: 0px; + border-bottom: 1px solid #fff; + color: white; + background: #009999 url(images/box_top2.gif) no-repeat top left; +} + +#navbar dd { + font-size: 100%; + margin: 0 0 0 0px; + padding: 6px 10px; + color: #0047b9; +} + +dd#selected { + background: #99ffff url(images/arrow.gif) no-repeat; + background-position: 4px 10px; +} diff --git a/doc/manual/manual.texi b/doc/manual/manual.texi new file mode 100644 index 000000000..cff215fcd --- /dev/null +++ b/doc/manual/manual.texi @@ -0,0 +1,97 @@ +\input texinfo @c -*-texinfo-*- +@c %**start of header +@setfilename ns-3.info +@settitle ns-3 manual +@c @setchapternewpage odd +@c %**end of header + +@ifinfo +Primary documentation for the @command{ns-3} project is available in +three forms: +@itemize @bullet +@item @uref{http://www.nsnam.org/doxygen/index.html,,ns-3 Doxygen/Manual}: Documentation of the public APIs of the simulator +@item @uref{http://www.nsnam.org/tutorial/index.html,,ns-3 Tutorial} +@item Reference Manual (this document) +@item @uref{http://www.nsnam.org/wiki/index.php,, ns-3 wiki} +@end itemize + +This document is written in GNU Texinfo and is to be maintained in +revision control on the @command{ns-3} code server. Both PDF and HTML versions +should be available on the server. Changes to +the document should be discussed on the ns-developers@@isi.edu mailing list. +@end ifinfo + +@copying + +This is an @command{ns-3} manual. +Primary documentation for the @command{ns-3} project is available in +three forms: +@itemize @bullet +@item @uref{http://www.nsnam.org/doxygen/index.html,,ns-3 Doxygen/Manual}: Documentation of the public APIs of the simulator +@item Manual (this document) +@item @uref{http://www.nsnam.org/wiki/index.php,, ns-3 wiki} +@end itemize + +This document is written in GNU Texinfo and is to be maintained in +revision control on the @command{ns-3} code server. Both PDF and HTML +versions should be available on the server. Changes to +the document should be discussed on the ns-developers@@isi.edu mailing list. + +This software is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This software 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, see @uref{http://www.gnu.org/licenses/}. +@end copying + +@titlepage +@title ns-3 Reference Manual +@author ns-3 project +@author feedback: ns-developers@@isi.edu +@today{} + +@c @page +@vskip 0pt plus 1filll +@insertcopying +@end titlepage + +@c So the toc is printed at the start. +@anchor{Full Table of Contents} +@contents + +@ifnottex +@node Top, Overview, Full Table of Contents +@top ns-3 Manual (html version) + +For a pdf version of this manual, +see @uref{http://www.nsnam.org/docs/manual.pdf}. + +@insertcopying +@end ifnottex + +@menu +* ns-3 Packets:: +* ns-3 Callbacks:: +* Sockets APIs:: +* ns-3 routing overview:: +* Troubleshooting +@end menu + +@include packets.texi +@include callbacks.texi +@include sockets.texi +@c @include output.texi +@include routing.texi +@c @include other.texi +@include troubleshoot.texi + +@printindex cp + +@bye diff --git a/doc/manual/other.texi b/doc/manual/other.texi new file mode 100644 index 000000000..7b24e7809 --- /dev/null +++ b/doc/manual/other.texi @@ -0,0 +1,2189 @@ +@c ======================================================================== +@c Other Network Topologies +@c ======================================================================== + +@node Other-network-topologies +@chapter Other Network Topologies +@cindex topology +@cindex Channel +@cindex NetDevice +@cindex topology!bus +@cindex topology!point-to-point +@cindex PointToPointChannel +@cindex PointToPointNetDevice + +@emph{Network topology} is the study of the arrangement of of the elements +(in @command{ns-3} represented by the classes @code{Channel} and @code{Node}) +of a network. Two fundamental types of physical topologies are the +@emph{point-to-point} and @emph{bus} topologies. We have already been exposed +to the @command{ns-3} channel specialization named @code{CsmaChannel}. This is +a simulation of a bus network. We also provide a simulation of a +point-to-point channel with associated net devices. As described previously, +the associated C++ classes specialize the @command{ns-3} base classes +@code{NetDevice} and @code{Channel} and are called @code{PointToPointNetDevice} +and @code{PointToPointChannel} respectively. + +We will use combinations of these bus and point-to-point topology elements +to show how to create several commonly seen network topologies. + +@section A Point-to-Point Network +We're going to take what might be seen as a step backward and look at a simple +point-to-point network. We will be building the simplest network you can +imagine. A serial link (point to point) between two computers. When you +see this point-to-point network, you can think of an RS-422 (or RS-232 for +you old-timers) cable. This topology is shown below. + +@sp 1 +@center @image{figures/pp,,,,png} + +@cindex CreateObject +@cindex InternetNode +We have provided a file for you in the @code{tutorial} +directory called @code{tutorial-point-to-point.cc}. You should now be +familiar enough with the system to pick out fairly easily what has been +changed. Let's focus on the following lines: + +@verbatim + Ptr n0 = CreateObject (); + Ptr n1 = CreateObject (); + + Ptr link = PointToPointTopology::AddPointToPointLink ( + n0, n1, DataRate (38400), MilliSeconds (20)); + + PointToPointTopology::AddIpv4Addresses (link, n0, "10.1.1.1", + n1, "10.1.1.2"); +@end verbatim + +You can see that we created two @code{InternetNode} objects in the usual way. +Then, instead of creating a @code{CsmaChannel} we create a +@code{PointToPointChannel}. This point-to-point channel, which we call +@code{link}, connects node zero (@code{n0}) and node one (@code{n1}) over a +simulated link that runs at 38400 bits per second and has a 20 millisecond +simulated speed-of-light delay. This call also creates appropriate net devices +and attaches them to nodes zero and one. + +We then add IP addresses to the net devices we just created using the topology +helper @code{AddIpv4Addresses}. Node zero gets the IP address 10.1.1.1 and +node one gets the IP address 10.1.1.2 assigned. + +The alert tutorial user may wonder what the network number or prefix is of +those IP addresses. The point-to-point topology assumes that you want a +@code{/30} subnet and assigns an appropriate net mask for you. It then then +@emph{asserts} that the network numbers of the two net devices match. So there +is an implicit network mask created down in the topology code that looks like, + +@verbatim + Ipv4Mask netmask("255.255.255.252"); +@end verbatim + +The rest of the code you should recognize and understand. We are just going +to echo one packet across the point-to-point link. You should be now be able +to build and run this example and to locate and interpret the ASCII trace +file. This is left as an exercise for you. + +The file @code{tutorial-point-to-point.cc} is reproduced here for your +convenience: + +@verbatim +/* -*- 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 + */ + +#include "ns3/log.h" +#include "ns3/ptr.h" +#include "ns3/internet-stack.h" +#include "ns3/point-to-point-channel.h" +#include "ns3/mac48-address.h" +#include "ns3/point-to-point-net-device.h" +#include "ns3/point-to-point-topology.h" +#include "ns3/udp-echo-client.h" +#include "ns3/udp-echo-server.h" +#include "ns3/simulator.h" +#include "ns3/nstime.h" +#include "ns3/ascii-trace.h" +#include "ns3/pcap-trace.h" +#include "ns3/global-route-manager.h" + +NS_LOG_COMPONENT_DEFINE ("PointToPointSimulation"); + +using namespace ns3; + +// Network topology +// +// point to point +// +--------------+ +// | | +// n0 n1 +// +int +main (int argc, char *argv[]) +{ + LogComponentEnable ("PointToPointSimulation", LOG_LEVEL_INFO); + + NS_LOG_INFO ("Point to Point Topology Simulation"); + + Ptr n0 = CreateObject (); + Ptr n1 = CreateObject (); + + Ptr link = PointToPointTopology::AddPointToPointLink ( + n0, n1, DataRate (38400), MilliSeconds (20)); + + PointToPointTopology::AddIpv4Addresses (link, n0, "10.1.1.1", + n1, "10.1.1.2"); + + uint16_t port = 7; + + Ptr client = CreateObject (n0, "10.1.1.2", + port, 1, Seconds(1.), 1024); + + Ptr server = CreateObject (n1, port); + + server->Start(Seconds(1.)); + client->Start(Seconds(2.)); + + server->Stop (Seconds(10.)); + client->Stop (Seconds(10.)); + + AsciiTrace asciitrace ("tutorial.tr"); + asciitrace.TraceAllQueues (); + asciitrace.TraceAllNetDeviceRx (); + + Simulator::Run (); + Simulator::Destroy (); +} +@end verbatim + +@section A Star Network +A point-to-point network is considered a special case of a star network. As +you might expect, the process of constructing a star network is an extension +of the very simple process used for a point-to-point link. We have provided +a file for you in the @code{tutorial} directory called @code{tutorial-star.cc} +that implements a simple star network as seen below. + +@sp 1 +@center @image{figures/star,,,,png} + +In order to create a star network, we need to be able to instantiate some +number (greater than one) of net devices on a node. In the name of simplicity +of use, the @code{PointToPointTopology} topology helper does not allow one to +do this. We provided a separate topology helper class, the +@code{PointToPointIpv4Topology} helper class that provides the slightly finer +granularity we need to accomplish a star network. In order to use this new +helper we have to load the definitions by including the appropriate file. + +@verbatim + #include "ns3/point-to-point-ipv4-topology.h" +@end verbatim + +The star that we're going to create has a node in the center (@code{n0}) with +six nodes surrounding (@code{n1} - @code{n6}). You should be able to easily +find and understand the code that creates these nodes. + +@verbatim + Ptr n0 = CreateObject (); + Ptr n1 = CreateObject (); + Ptr n2 = CreateObject (); + Ptr n3 = CreateObject (); + Ptr n4 = CreateObject (); + Ptr n5 = CreateObject (); + Ptr n6 = CreateObject (); +@end verbatim + +Next, we get into the differences between the @code{PointToPointTopology} +helper and the @code{PointToPointIpv4Topology} helper. The +@code{PointToPointIpv4Topology} helper looks and feels a little like the +@code{CsmaIpv4Topology} helper. Just like you created a CSMA channel +previously, you need to create a point-to-point channel. The following +code creates a @code{PointToPointChannel} and calls it @code{link01}. You can +interpret this name as being the channel (or @emph{link}) from node zero to +node one. + +@verbatim + Ptr link01 = + PointToPointIpv4Topology::CreateChannel (DataRate (38400), + MilliSeconds (20)); +@end verbatim + +You need to provide a data rate for the channel which we set at 38400 bits +per second. You must also provide a speed-of-light delay which we set at +20 milliseconds. + +Just as you added a net device to the nodes in the CSMA tutorial section, you +do the same here but with a point-to-point net device. The following code +illustrates how we do that: + +@verbatim + uint32_t nd01 = PointToPointIpv4Topology::AddNetDevice (n0, + link01); +@end verbatim + +We call the @code{PointToPointIpv4Topology} helper and ask it to add a net +device to node zero (@code{n0}) and connect it to the appropriate +point-to-point link (@code{link01}) which you will recall is the serial link +from node zero to node one. + +If you look at the following code, you will see the same calls are repeated +to create the remaining five point-to-point channels and connect them +to net devices on node zero. + +The next new code is found after the ``spokes'' of the star have been created. +It looks like the following: + +@verbatim + uint32_t nd1 = PointToPointIpv4Topology::AddNetDevice (n1, link01); + uint32_t nd2 = PointToPointIpv4Topology::AddNetDevice (n2, link02); + uint32_t nd3 = PointToPointIpv4Topology::AddNetDevice (n3, link03); + uint32_t nd4 = PointToPointIpv4Topology::AddNetDevice (n4, link04); + uint32_t nd5 = PointToPointIpv4Topology::AddNetDevice (n5, link05); + uint32_t nd6 = PointToPointIpv4Topology::AddNetDevice (n6, link06); +@end verbatim + +Here we are creating the net devices on the nodes surrounding the center node. +In the first call, we are adding a net device on node one (@code{n1}) and +connecting that net device to the channel named @code{link01}. Remember that +we created the channel @code{link01} as the channel connecting node zero and +node one. We previously created a net device on node zero and attached that +device to @code{link01}. Here we are connecting the other side of that link +to node one. The return value from this call is the net device index of the +created net device. + +The next section of code adds addresses to the net devices we just created. +The first call adds the IP address 10.1.1.1 to the net device going from +node zero to node one. Recall that we first created a node named @code{n0} +and a channel called @code{link01}. We added a net device to @code{n0} and +remembered the net device index as the @code{uint32_t nd01}. This meant +the net device @emph{nd} on node @emph{0} that we connected to node @emph{1}. +We call @code{AddAddress} to add an IP address (10.1.1.1) to the net device +on node zero identified by the net device index @code{nd01}. We provide a +net mask suitable for a point to point network. This is typically a /30 +address but we don't force that in this API. + +After setting up the address on node zero, we do the same for the node on +the other end of the ``spoke'' --- in this case node one, with its single +net device. Note that the network number is the same on both sides of this +network. + +@verbatim + PointToPointIpv4Topology::AddAddress (n0, nd01, "10.1.1.1", + ``255.255.255.252''); + + PointToPointIpv4Topology::AddAddress (n1, nd1, "10.1.1.2", + ``255.255.255.252''); +@end verbatim + +The following code repeats this pattern assining similar IP addresses to the +remaining net devices. Note that there are no @code{Mac48Address} address +assignments --- they are not required. + +The rest of the code you should recognize and understand. We are just going +to echo one packet across the point-to-point link. You should be now be able +to build and run this example and to locate and interpret the ASCII trace +file. This is left as an exercise for you. + +The file @code{tutorial-star.cc} is reproduced here for your convenience: + +@verbatim +/* -*- 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 + */ + +#include "ns3/log.h" +#include "ns3/ptr.h" +#include "ns3/internet-stack.h" +#include "ns3/point-to-point-channel.h" +#include "ns3/mac48-address.h" +#include "ns3/point-to-point-net-device.h" +#include "ns3/point-to-point-ipv4-topology.h" +#include "ns3/udp-echo-client.h" +#include "ns3/udp-echo-server.h" +#include "ns3/simulator.h" +#include "ns3/nstime.h" +#include "ns3/ascii-trace.h" +#include "ns3/pcap-trace.h" +#include "ns3/global-route-manager.h" + +NS_LOG_COMPONENT_DEFINE ("StarSimulation"); + +using namespace ns3; + +// Network topology +// +// n3 n2 +// | / +// | / +// n4 --- n0 --- n1 +// / | +// / | +// n5 n6 + +int +main (int argc, char *argv[]) +{ + LogComponentEnable ("StarSimulation", LOG_LEVEL_INFO); + + NS_LOG_INFO ("Star Topology Simulation"); + + Ptr n0 = CreateObject (); + Ptr n1 = CreateObject (); + Ptr n2 = CreateObject (); + Ptr n3 = CreateObject (); + Ptr n4 = CreateObject (); + Ptr n5 = CreateObject (); + Ptr n6 = CreateObject (); + + Ptr link01 = + PointToPointIpv4Topology::CreateChannel (DataRate (38400), + MilliSeconds (20)); + + uint32_t nd01 = PointToPointIpv4Topology::AddNetDevice (n0, + link01); + + Ptr link02 = + PointToPointIpv4Topology::CreateChannel (DataRate (38400), + MilliSeconds (20)); + + uint32_t nd02 = PointToPointIpv4Topology::AddNetDevice (n0, + link02); + + Ptr link03 = + PointToPointIpv4Topology::CreateChannel (DataRate (38400), + MilliSeconds (20)); + + uint32_t nd03 = PointToPointIpv4Topology::AddNetDevice (n0, + link03); + + Ptr link04 = + PointToPointIpv4Topology::CreateChannel (DataRate (38400), + MilliSeconds (20)); + + uint32_t nd04 = PointToPointIpv4Topology::AddNetDevice (n0, + link04); + + Ptr link05 = + PointToPointIpv4Topology::CreateChannel (DataRate (38400), + MilliSeconds (20)); + + uint32_t nd05 = PointToPointIpv4Topology::AddNetDevice (n0, + link05); + + Ptr link06 = + PointToPointIpv4Topology::CreateChannel (DataRate (38400), + MilliSeconds (20)); + + uint32_t nd06 = PointToPointIpv4Topology::AddNetDevice (n0, link06); + + uint32_t nd1 = PointToPointIpv4Topology::AddNetDevice (n1, link01); + uint32_t nd2 = PointToPointIpv4Topology::AddNetDevice (n2, link02); + uint32_t nd3 = PointToPointIpv4Topology::AddNetDevice (n3, link03); + uint32_t nd4 = PointToPointIpv4Topology::AddNetDevice (n4, link04); + uint32_t nd5 = PointToPointIpv4Topology::AddNetDevice (n5, link05); + uint32_t nd6 = PointToPointIpv4Topology::AddNetDevice (n6, link06); + + PointToPointIpv4Topology::AddAddress (n0, nd01, "10.1.1.1", + "255.255.255.252"); + + PointToPointIpv4Topology::AddAddress (n1, nd1, "10.1.1.2", + "255.255.255.252"); + + PointToPointIpv4Topology::AddAddress (n0, nd02, "10.1.2.1", + "255.255.255.252"); + + PointToPointIpv4Topology::AddAddress (n2, nd2, "10.1.2.2", + "255.255.255.252"); + + PointToPointIpv4Topology::AddAddress (n0, nd03, "10.1.3.1", + "255.255.255.252"); + + PointToPointIpv4Topology::AddAddress (n3, nd3, "10.1.2.2", + "255.255.255.252"); + + PointToPointIpv4Topology::AddAddress (n0, nd04, "10.1.4.1", + "255.255.255.252"); + + PointToPointIpv4Topology::AddAddress (n4, nd4, "10.1.4.2", + "255.255.255.252"); + + PointToPointIpv4Topology::AddAddress (n0, nd05, "10.1.5.1", + "255.255.255.252"); + + PointToPointIpv4Topology::AddAddress (n5, nd5, "10.1.5.2", + "255.255.255.252"); + + PointToPointIpv4Topology::AddAddress (n0, nd06, "10.1.6.1", + "255.255.255.252"); + + PointToPointIpv4Topology::AddAddress (n6, nd6, "10.1.6.2", + "255.255.255.252"); + + uint16_t port = 7; + + Ptr client = CreateObject (n0, "10.1.1.2", + port, 1, Seconds(1.), 1024); + + Ptr server = CreateObject (n1, port); + + server->Start(Seconds(1.)); + client->Start(Seconds(2.)); + + server->Stop (Seconds(10.)); + client->Stop (Seconds(10.)); + + AsciiTrace asciitrace ("tutorial.tr"); + asciitrace.TraceAllQueues (); + asciitrace.TraceAllNetDeviceRx (); + + Simulator::Run (); + Simulator::Destroy (); +} +@end verbatim + +@subsection Routing +If you are really excited about this simulator you may have already tried to +modify the scripts outside the tutorial. I know that one of the first things +that would have occurred to me when I saw the star network would have been to +start trying to add applications to echo packets from nodes other than zero. +If you tried, for example, to start the echo client on node one instead of +node zero, you would have found an empty trace file. The reason for this +is that you have now created an internetwork. This means you will need to +enable internetwork routing. + +We have provided a file for you in the @code{tutorial} directory called +@code{tutorial-star-routing.cc} to show you how this is done. This extremely +tricky and difficult change is shown below: + +@verbatim + GlobalRouteManager::PopulateRoutingTables (); +@end verbatim + +This one-line addition, located just before the simulation runs, tells the +@command{ns-3} @emph{global route manager} to walk the topology you created and +build internetwork routing tables for all of the nodes in the simulation. +We changed the client application so that it runs on node four: + +@verbatim + Ptr client = CreateObject (n4, "10.1.1.2", + port, 1, Seconds(1.), 1024); +@end verbatim + +Now if you build and run @code{tutorial-star-routing.cc} you can examine the +@code{tutorial.tr} file and see that your UDP echo packets are now correctly +routed through the topology. + +@section A Dumbbell Network +One of the most interesting simple topologies (from a phenomenological point of +view) is commonly called a dumbbell network. The name derives from a +superficial similarity in form to a piece of exercise equipment. + +The dumbbell model is typically composed of two bus or star network elements +connected via a point-to-point link. The point-to-point link is usually +configured with a lower bandwidth than the bus elements to provide a +@emph{choke point}. + +The following is a representation of the topology. + +@sp 1 +@center @image{figures/dumbbell,,,,png} + +We have provided a file that constructs this dumbbell network and creates +enough data flowing across the choke point that some packets will be dropped. +The file is called @code{tutorial-linear-dumbbell.cc} and is located in the +@code{tutorial} directory. We have already covered all of the code used to +create this network, so we will just quickly go over the main sections of the +script. + +The first section creates a CSMA lan that will become the left side of the +dumbbell network. This code should be very familiar since we used the same +process to create our first example. + +@verbatim +// +// Create the lan on the left side of the dumbbell. +// + Ptr n0 = CreateObject (); + Ptr n1 = CreateObject (); + Ptr n2 = CreateObject (); + Ptr n3 = CreateObject (); + + Ptr lan1 = + CsmaTopology::CreateCsmaChannel (DataRate (10000000), MilliSeconds (2)); + + uint32_t nd0 = CsmaIpv4Topology::AddIpv4CsmaNetDevice (n0, lan1, + "08:00:2e:00:00:00"); + + uint32_t nd1 = CsmaIpv4Topology::AddIpv4CsmaNetDevice (n1, lan1, + "08:00:2e:00:00:01"); + + uint32_t nd2 = CsmaIpv4Topology::AddIpv4CsmaNetDevice (n2, lan1, + "08:00:2e:00:00:02"); + + uint32_t nd3 = CsmaIpv4Topology::AddIpv4CsmaNetDevice (n3, lan1, + "08:00:2e:00:00:03"); + + CsmaIpv4Topology::AddIpv4Address (n0, nd0, "10.1.1.1", "255.255.255.0"); + CsmaIpv4Topology::AddIpv4Address (n1, nd1, "10.1.1.2", "255.255.255.0"); + CsmaIpv4Topology::AddIpv4Address (n2, nd2, "10.1.1.3", "255.255.255.0"); + CsmaIpv4Topology::AddIpv4Address (n3, nd3, "10.1.1.4", "255.255.255.0"); +@end verbatim + +The code to generate the CSMA lan on the right side is similar; only the names +have been changed. + +@verbatim +// +// Create the lan on the right side of the dumbbell. +// + Ptr n4 = CreateObject (); + Ptr n5 = CreateObject (); + Ptr n6 = CreateObject (); + Ptr n7 = CreateObject (); + + Ptr lan2 = + CsmaTopology::CreateCsmaChannel (DataRate (10000000), MilliSeconds (2)); + + uint32_t nd4 = CsmaIpv4Topology::AddIpv4CsmaNetDevice (n4, lan2, + "08:00:2e:00:00:04"); + + uint32_t nd5 = CsmaIpv4Topology::AddIpv4CsmaNetDevice (n5, lan2, + "08:00:2e:00:00:05"); + + uint32_t nd6 = CsmaIpv4Topology::AddIpv4CsmaNetDevice (n6, lan2, + "08:00:2e:00:00:06"); + + uint32_t nd7 = CsmaIpv4Topology::AddIpv4CsmaNetDevice (n7, lan2, + "08:00:2e:00:00:07"); + + CsmaIpv4Topology::AddIpv4Address (n4, nd4, "10.1.2.1", "255.255.255.0"); + CsmaIpv4Topology::AddIpv4Address (n5, nd5, "10.1.2.2", "255.255.255.0"); + CsmaIpv4Topology::AddIpv4Address (n6, nd6, "10.1.2.3", "255.255.255.0"); + CsmaIpv4Topology::AddIpv4Address (n7, nd7, "10.1.2.4", "255.255.255.0"); +@end verbatim + +Next, we create a point to point link to connect the two lans. We connect +the point-to-point channel between nodes three (on the left lan) and four +(on the right lan). You should recoginze this as substantially similar to +the link setup from the @code{point-to-point} example. + +@verbatim +// +// Create the point-to-point link to connect the two lans. +// + Ptr link = PointToPointTopology::AddPointToPointLink ( + n3, n4, DataRate (38400), MilliSeconds (20)); + + PointToPointTopology::AddIpv4Addresses (link, n3, "10.1.3.1", + n4, "10.1.3.2"); +@end verbatim + +Then we configure data flows. We create four echo clients that send UDP +packets from the left side lan to servers created on the right side lan. +Notice that we send 100 packets with an inter-packet gap of ten milliseconds +instead of the single packet we have previously used. This data rate is +sufficient to saturate the point-to-point link and will cause packets to be +dropped when the queue on the link net devices overflows (the default maximum +queue depth is 100 packets). Note that we stagger the start of the echo +clients to slowly bring up the data rates. + +@verbatim +// +// Create data flows across the link: +// n0 ==> n4 ==> n0 +// n1 ==> n5 ==> n1 +// n2 ==> n6 ==> n2 +// n3 ==> n7 ==> n3 +// + uint16_t port = 7; + + Ptr client0 = CreateObject (n0, "10.1.2.1", + port, 100, Seconds(.01), 1024); + Ptr client1 = CreateObject (n1, "10.1.2.2", + port, 100, Seconds(.01), 1024); + Ptr client2 = CreateObject (n2, "10.1.2.3", + port, 100, Seconds(.01), 1024); + Ptr client3 = CreateObject (n3, "10.1.2.4", + port, 100, Seconds(.01), 1024); + + Ptr server4 = CreateObject (n4, port); + Ptr server5 = CreateObject (n5, port); + Ptr server6 = CreateObject (n6, port); + Ptr server7 = CreateObject (n7, port); + + server4->Start(Seconds(1.)); + server5->Start(Seconds(1.)); + server6->Start(Seconds(1.)); + server7->Start(Seconds(1.)); + + client0->Start(Seconds(2.)); + client1->Start(Seconds(2.1)); + client2->Start(Seconds(2.2)); + client3->Start(Seconds(2.3)); + + server4->Stop (Seconds(10.)); + server5->Stop (Seconds(10.)); + server6->Stop (Seconds(10.)); + server7->Stop (Seconds(10.)); + + client0->Stop (Seconds(10.)); + client1->Stop (Seconds(10.)); + client2->Stop (Seconds(10.)); + client3->Stop (Seconds(10.)); +@end verbatim + +The remainder of the file should be quite familiar to you. Go ahead and +run @code{tutorial-linear-dumbbell}. Now take a look at the trace +(@code{tutorial.tr}) file. You will now see trace lines that begin with +@code{d}. Alternatively you can search for the string ``queue-drop'' which +is the expansion of the drop code ('d'). + +Interpretation of a dropped packet is straightforward. We have expanded +the first @code{queue-drop} trace for you below. See the section on ASCII +tracing for details. + +@verbatim + 00 d + 01 2.40938 + 02 nodeid=3 + 03 device=1 + 04 queue-drop + 05 pkt-uid=124 + 06 LLCSNAP(type 0x800) + 07 IPV4( + 08 tos 0x0 + 09 ttl 63 + 10 id 20 + 11 offset 0 + 12 flags [none] + 13 length: 1052) 10.1.1.3 > 10.1.2.3 + 14 UDP(length: 1032) + 15 49153 > 7 + 16 DATA (length 1024) +@end verbatim + +We leave it as an exercise to examine the trace files in more detail. + +@c ======================================================================== +@c Nonlinear Thinking +@c ======================================================================== + +@node Nonlinear-Thinking +@chapter Nonlinear Thinking + +One thing that all of our examples so far have in common is that they are +composed of a linear collection of calls into the @command{ns-3} system. The +programmers among the readers may have wondered why there is not as much +as a for-loop in all of the examples. The answer is that we wanted to +introduce you to @command{ns-3} scripting with a minimum of conceptual +overhead. We're going to remedy that situation shortly. + +We have written a number of @command{ns-3} scripts in C++. Although we have +been perfectly linear in our script implementations, just like any other C++ +program, an @command{ns-3} script can use any features of the language you +desire. If you will look back at the @code{tutorial-linear-dumbbell.cc} +example, you may notice that the code to create the left and right sides of +the dumbbell is operationally identical --- only the names change. An obvious +improvement of this program would be to use subroutines to create the sides. +Since we are working with C++, we should probably do this in an +object-oriented way. Since object-oriented design is somewhat of a black art +to some people, we'll take some time here and outline a simple methodology +you can follow. + +@section Object Design 101 --- Class Ipv4BusNetwork +If you are a master of object oriented design, feel free to skip or skim this +section, in which we derive a simplistic but fully operational bus network +class. + +So you want to create a BusNetwork class. Often the biggest hurdle in a +design is figuring out how to get started. One of the simplest and most +straightforward ways to do an object decomposition of a problem is to simply +write down a description of the problem and take a look at the words +you used. Let's take some time and do that, first at a very high level. + +@example +A bus network is an implementation of a particular network topology that +contains some number of nodes. Each of these nodes is attached to a single +multi-drop channel. The network itself has some attributes independent of +the topology such as a network mask, network number (prefix) and base IP +address. +@end example + +The first thing to do is to focus on the nouns and adjectives. These will +give you a starting point for required classes and member variables. + +Immediately we can notice that at the highest level we are talking about the +noun @emph{network}. This probably won't surprise you. We also have an +adjective that modifies the noun --- @emph{bus}. This should lead us to our +first class defintion. Usually class names are constructed in the same way +as an English language sentence would be spoken. For example, one would speak +of a @emph{bus network} in conversation, so we would normally create a +@code{class BusNetwork} to represent it. + +One thing to note is that we have used two words in our description quite +naturally: @emph{is} and @emph{has}. When you see these words should should +immediately think of the object-oriented concepts of @emph{ISA} (inheritance) +and @emph{HASA} (containment) respectively. We wrote that a bus network +@emph{is} an implementation of a particular network topology. Perhaps you +will agree that there is a natural base class called @code{Network} that +@emph{has} the attributes discussed above. The fact that a @code{BusNetwork} +@emph{ISA} kind of @code{Network} suggests inheritance. Let's capture that +thought right away remembering that we're focused on IP version four here: + +@verbatim + class Ipv4Network + { + public: + Ipv4Address m_network; + Ipv4Mask m_mask; + Ipv4Address m_baseAddress; + }; + + class Ipv4BusNetwork : public Ipv4Network + { + }; +@end verbatim + +Let's take a look at the @emph{HASA} relationships of the bus network. Clearly +it will @emph{have} a reference to the underlying channel that implements the +actual communications medium. We use smart pointers for those references, so +one member variable is obvious: + +@verbatim + Ptr m_channel; +@end verbatim + +A bus network will also need to contain references to all of the nodes we +eventually want to create. If you are working in C++ and see the words contain +or container, you should immediately think of the Standard Template Library +or STL. A quick search of the available containers there will probably lead +you to consider the vector class. A vector is a container that looks like an +array. This is just what we need here. Again, we want to use smart pointers +to reference our nodes, so the declaration of the vector would look like, + +@verbatim + std::vector > m_nodes; +@end verbatim + +It will save you headaches in the future if you notice that the space between +the two right brackets is required to differentiate this situation from a +right-shift operator. So we have a pretty good start already after just a +little work. Now we need to turn our attention to actions. Let's write +another little description of the things you consider doing to a Bus network. + +@example +We need to be able to create a bus network. We need to be able to delete a +bus network. We need to be able to get a handle to a node in order to add +applications. We need to be able to set the network, mask and base address +somehow, specify how many nodes to create and provide the underlying channel +its required bandwidth and delay parameters. +@end example + +We now look at the @emph{verbs} in that sentence. These will give a good +starting point for the methods of the classes. For example, the verbs +@emph{create} and @emph{delete} should suggest @emph{constructor} and +@emph{destructor}. The verb @emph{get} leads us to providing a method called +@code{GetNode}. We have to provide a number of parameters so we can either +provide @emph{setters} or we can simply pass them in as parameters to our +constructors. Since this is a simple example, we won't bother to implement +getters and setters (methods to get and set member variables to enhance data +hiding). Let's use this guidance to finish up our class declarations: + +@verbatim + class Ipv4Network + { + public: + Ipv4Network (Ipv4Address network, Ipv4Mask mask, Ipv4Address address); + virtual ~Ipv4Network (); + + Ipv4Address m_network; + Ipv4Mask m_mask; + Ipv4Address m_baseAddress; + }; + + class Ipv4BusNetwork : public Ipv4Network + { + public: + Ipv4BusNetwork ( + Ipv4Address network, + Ipv4Mask mask, + Ipv4Address startAddress, + DataRate bps, + Time delay, + uint32_t n); + + virtual ~Ipv4BusNetwork (); + + Ptr GetNode (uint32_t n); + + private: + std::vector > m_nodes; + Ptr m_channel; + }; +@end verbatim + +That's it. We have actually already walked through almost all of the code +required to construct a bus network in our @code{tutorial-csma-echo.cc} +example, so let's just jump forward and take a look at an implementation +of this thing. We provide an implementation for you in the files +@code{ipv4-bus-network.h} and @code{ipv4-bus-network.cc} located in the +@code{tutorial} directory. We also provide an example that uses the new +class in the file @code{tutorial-bus-network.cc}. + +The interesting method from our current perspective is the Ipv4BusNetwork +constructor, shown below: + +@verbatim + Ipv4BusNetwork::Ipv4BusNetwork ( + Ipv4Address network, + Ipv4Mask mask, + Ipv4Address baseAddress, + DataRate bps, + Time delay, + uint32_t n) + : + Ipv4Network (network, mask, baseAddress) + { + Ipv4AddressGenerator::SeedNetwork (mask, network); + Ipv4AddressGenerator::SeedAddress (mask, baseAddress); + + m_channel = CsmaTopology::CreateCsmaChannel (bps, delay); + + for (uint32_t i = 0; i < n; ++i) + { + Ptr node = CreateObject (); + uint32_t nd = CsmaIpv4Topology::AddIpv4CsmaNetDevice (node, m_channel, + Mac48Address::Allocate ()); + Ipv4Address address = Ipv4AddressGenerator::AllocateAddress (mask, + network); + CsmaIpv4Topology::AddIpv4Address (node, nd, address, mask); + m_nodes.push_back (node); + } + } +@end verbatim + +Notice that we do the simple and straightforward thing and pass all of our +parameters to the constructor. For those unfamiliar with C++, the line after +the colon and before the opening brace (shown below), + +@verbatim + : + Ipv4Network (network, mask, baseAddress) + { +@end verbatim + +Passes the appropriate parameters to the constructor of the base class +@code{Ipv4Network}. There are two new calls that we haven't seen immediately +after this initialization. They are: + +@verbatim + Ipv4AddressGenerator::SeedNetwork (mask, network); + Ipv4AddressGenerator::SeedAddress (mask, baseAddress); +@end verbatim + +We provide an IP address generator class to allow us to programatically +allocate IP addresses. The first call to @code{SeedNetwork} gives the +address generator a starting network number to use when generating addresses. +The second call to @code{SeedAddress} gives the address generator a starting +IP address to use. There is a starting network and starting address for each +of the 32 possible network masks. Later in the for loop, you will see a +call to @code{AllocateAddress} in which the IP address for each node created +in the loop is actually generated. + +The only unfamiliar call in the reset of the constructor will be: + +@verbatim + m_nodes.push_back (node); +@end verbatim + +This is the STL code to add the newly created node to the vector of nodes +attached to the bus. + +For your convenience, we reproduce the entire bus network implementation below: + +@verbatim + /* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */ + /* + * Copyright (c) 2007 University of Washington + * + * 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 + */ + + #include "ns3/mac48-address.h" + #include "ns3/csma-net-device.h" + #include "ns3/csma-topology.h" + #include "ns3/csma-ipv4-topology.h" + + #include "ipv4-bus-network.h" + #include "ipv4-address-generator.h" + + namespace ns3 { + + Ipv4Network::Ipv4Network ( + Ipv4Address network, + Ipv4Mask mask, + Ipv4Address address) + : + m_network (network), m_mask (mask), m_baseAddress (address) + { + } + + Ipv4Network::~Ipv4Network () + { + } + + Ipv4BusNetwork::Ipv4BusNetwork ( + Ipv4Address network, + Ipv4Mask mask, + Ipv4Address baseAddress, + DataRate bps, + Time delay, + uint32_t n) + : + Ipv4Network (network, mask, baseAddress) + { + Ipv4AddressGenerator::SeedNetwork (mask, network); + Ipv4AddressGenerator::SeedAddress (mask, baseAddress); + + m_channel = CsmaTopology::CreateCsmaChannel (bps, delay); + + for (uint32_t i = 0; i < n; ++i) + { + Ptr node = CreateObject (); + uint32_t nd = CsmaIpv4Topology::AddIpv4CsmaNetDevice (node, m_channel, + Mac48Address::Allocate ()); + Ipv4Address address = Ipv4AddressGenerator::AllocateAddress (mask, + network); + CsmaIpv4Topology::AddIpv4Address (node, nd, address, mask); + m_nodes.push_back (node); + } + } + + Ipv4BusNetwork::~Ipv4BusNetwork () + { + } + + Ptr + Ipv4BusNetwork::GetNode (uint32_t n) + { + return m_nodes[n]; + } + + }; // namespace ns3 +@end verbatim + +@section Using Ipv4BusNetwork +If all you ever want to do with a bus network can be captured in a topology +with four nodes on the bus, the preceeding section may seem like a colossal +waste of time. This is probably not the case, though. Now that we have a +relatively abstract bus class, we can create bus networks with 4, 40 or 4000 +nodes with no additional effort. + +A use of the bus network class is shown in the file +@code{bus-netowrk.cc} located in the @code{tutorial} directory. The +interesting code is, + +@verbatim + Ipv4BusNetwork bus ("10.1.0.0", "255.255.0.0", "0.0.0.3", + DataRate(10000000), MilliSeconds(20), 10); +@end verbatim + +Here we create a bus network with the network number ``10.1.0.0'' and the +network mask ``255.255.0.0'' that completes the IP network definition. You +can consider these together as ``10.1.0.0/16'' if you prefer. The next +parameter tells the bus to start numbering IP addresses of contained nodes at +``10.1.0.3'' (remember the network number will be combined). We provided a +data rate of 10 megabits per second and a latency of 20 milliseconds. +Finally, we ask the @code{Ipv4BusNetwork} object to create ten nodes in the +network. + +If you are feeling brave, go ahead and change the number of nodes to be 100, +1000, 10,000 or more to generate larger and larger networks. Before you go +too far, remember that a trace file will be generated when you run your +resulting program and ee asked the trace facility to trace all net device +receive events. This will include the reception of the broadcast ARP request +by all of the nodes in the simulation, so this can add up quickly. + +@c ======================================================================== +@c Summary +@c ======================================================================== + +@node Summary +@chapter Summary + +This concludes the first part of the tutorial. We have focused on +using the @command{ns-3} system to construct various network topologies and to +simulate sendng data across the networks; and we've shown you how to use the +trace facility to get access to simulation results. + +We now encourage you to play with the system a little. Experiment with what +we have provided. Build a hierarchical network simulation. Perhaps exercise +your object design skills and create a new @code{Ipv4DumbbellNetwork} class +to create dumbbell networks using the Ipv4BusNetwork class we just created. +Hint: An Ipv4DumbbellNetwork @emph{has} two @code{Ipv4BusNetwork} objects; +a left side and a right side. + +In the next part of the tutorial we are going to drop down a level and begin +examining the lower levels of the system in more detail. We are going to +explain how to change the behavior of the system and eventually how to write +new models and applications. This is a good time to make sure that you +thorougly understand what we've gone over so far. + +@c ======================================================================== +@c Object Model +@c ======================================================================== + +@node Object-Model +@chapter Object Model + +@cindex Object Model +There are two distinctly different meanings associated with the term Object +Model. The first speaks to the implementation of an object system --- a system +view; and the second speaks to the application programming interface (classes +or objects) one uses to access some service or system --- an application view. + +As an example of the system view sense of the term, the C++ language has an +associated object model that describes how objects are laid out in memory, +how virtual functions work, how inheritance is implemented, constructor and +destructor execution ordering, template instantiation, etc. + +@cindex API +@cindex DOM +@cindex Document Object Model +In the case of the application view, the Document Object Model is a good +example. In the words of W3C, the Document Object Model (DOM) is an +application programming interface (API) for HTML and XML documents. It defines +the logical structure of documents and the way a document is accessed and +manipulated. + +@cindex API +@cindex COM +@cindex Component Object Model +The Component Object Model (COM) from Microsoft actually spans both meanings +of the term and extends further into policy statements. From a system +perspective, COM specifies an interface definition language, the layout of +objects virtual function tables, the formats of Globally Unique Identifiers +and also specifies lifetime management mechanisms for objects via reference +counting. From the point of view of the API, COM specifies a number of +Interfaces as well as functions such as CoCreateInstance and various +threading models. The COM specification extends to policy by disallowing +implementation inheritance. + +@cindex Feynman +The @command{ns-3} object model takes the C++ language (system level) object +model as its basis, and extends that model by providing an API for software +componentry. You may find terms like Component, Interface and QueryInterface +in the following discussion, or used informally in other discussions about +@command{ns-3}. It is important to understand from the outset that this is +the @command{ns-3} object model, and not any other object model. +Richard Feynman (an American physicist) once described the behavior of matter +and light on a very small scale in the following way, + +@quotation +``They do not behave like waves, they do not behave like particles, they do +not behave like clouds, or billiard balls, or weights on springs, or like +anything that you have ever seen.'' +@end quotation + +Just as students of quantum mechanics must rid themselves of preconceptions +regarding the behavior of matter at small scales, you should rid yourself of +any preconceptions you may have about components, interfaces and APIs for +software componentry before continuing. To paraphrase Feynman, @command{ns-3} +components do not behave like COM Components, or Java Beans, or CORBA +objects, or clouds or weights on springs, or like anything that you have +ever seen --- they are @command{ns-3} components. + +@section The C++ Object Model is the Root of all Things +@command{Ns-3} is primarily a C++ system. The system is written in C++ and +one can use standard C++ mechanisms for creating and using ns-3 objects. We +do not change this at all, nor do we make any pronouncements about the +superiority of one mechanism or another. What we will do is provide +convenience functions that we think will make creating and managing simulation +objects easier. + +@cindex CreateObject +Previously, you have seen objects created using the template function +@code{CreateObject} as in the following example: + +@verbatim + Ptr n0 = CreateObject (); +@end verbatim + +This line of code, while it may be unfamiliar to some, is pure C++. If you +were to look in the header file ptr.h, you would find the following definition +of the @code{CreateObject} template. + +@verbatim + template + Ptr CreateObject (void) + { + Ptr p = Ptr (new T (), false); + p->SetTypeId (T::GetTypeId ()); + return p; + } +@end verbatim + +@cindex template +As you can see, this template creates objects of type @code{T} using the +operator @code{new}. Its a little harder to find the corresponding delete --- +it's in the file @code{object.cc} inside the method @code{Object::MaybeDelete}, +but when that @code{Ptr} which you see above goes out of scope it will call +@code{Unref} and ultimately the C++ @code{delete} operator will be called. + +@cindex new +@cindex delete +The ns-3 system uses the C++ @code{new} and @code{delete} operators, so there +is really no reason that you as a user of the ns-3 system are forbidden from +using these or any other C++ mechanism. If you so desire, you can take on +the responsibility for managing object lifetime (i.e., do not use the +@code{Ptr} smart pointer), work directly with the @code{new} and @code{delete} +operators and call methods like any C++ object as in the following example: + +@verbatim + MyClass *obj = new MyClass (); + obj->Method(); + delete obj; +@end verbatim + +@cindex model +You, as a competent model author, are encouraged to use whatever methods you +think are appropriate in your private code. Remember, however, that the +public ns-3 APIs do use smart pointers to pass objects around in an effort to +reduce the burden of object lifetime management. If you do intend to export +an API publicly, you should use the same object lifetime management approaches +as those found in the ns-3 public API if only for consistency. + +These APIs are there for convenience and consistency, but do not change the +fact that in ns-3 all of the objects are really just C++ objects, ultimately +created using the C++ new operator with C++ constructor semantics and are +ultimately deleted using the C++ delete operator, following C++ destructor +semantics. Although it may sometimes appear so, there is really no system- +level magic going on in ns-3. Ns-3 components and interfaces are C++ objects +just like any other object and our object model is simply a collection of APIs +built on the normal C++ object model. + +@cindex Interface +@cindex Abstract Data Type +@cindex ADT +@cindex Abstract Base Class +@cindex ABC +@section Interface +There are many different ideas floating around of what exactly the term +@emph{interface} means. Originally an interface just meant a communication +boundary between two entities. As the concepts of object oriented programming +(OOP) were surfacing in the 1980s, the term interface was applied to the +collection of access methods for the modular entities that were being defined. + +@cindex OOP +@cindex Object Oriented Programming +Two distinct approaches developed regarding specifying access mechanisms for +objects. The OOP purists were very concerned about object reuse and were led +to Abstract Data Types (ADT). These were eventually implemented in the case +of C++, as pure virtual methods in Abstract Base Classes (ABC). Another group +of folks was more interested in simply specifying object access methods in one +place and using inheritance as the primary reuse mechanism. + +Bjarne Stroustroup, the creator of C++, embraced both approaches. He makes +the following interesting observation: + +@quotation +``Many classes [@dots{}] are useful both as themselves and also as bases for +derived classes. [@dots{}] Some classes, such as class @strong{Shape}, +represent abstract concepts for which objects cannot exist.'' +@end quotation + +@cindex PIMPL +@command{Ns-3} does not pick and enforce a particular approach. In +@command{ns-3} an interface is determined completely by a class declaration +just as any C++ object interface is declared. If you think of an object as +an abstract concept that should be implemented by derived classes, by all +means, use the Abstract Base Class approach to interface declaration. If you +think that an object should be completely concrete and you foresee no need +to ever modify its behavior, feel free to avoid declaring any methods virtual. +If you think that an object could be useful as a base class, feel free to +declare its methods virtual. If you like to use the PIMPL idiom, again, feel +free. If you want to use any combination of these techniques, feel free. +We make no restrictions. + +@cindex API +When we speak of an ns-3 interface, we do not worry about interface definition +languages, or pure virtual classes, or registries we just think about C++ +object declarations and their associated methods. We tend to think of +interfaces to objects as simply a private or public API. When we instantiate +an @command{ns-3} interface, it is the C++ object model that dictates how that +object is brought into existence. When a method is called on an @command{ns-3} +Interface, it is the C++ object model that dictates how that method is +dispatched. + +We do, however, provide a base class that endows vanilla C++ objects with +capabilities that can be seen as conceptually similar to those provided by +Microsoft Component Model @emph{Interfaces}. + +@section The Ns-3 Object and GetObject +@cindex Component Object Model +One thing that Microsoft arguably got right in the Component Object Model was +the idea of Interface aggregation and discovery via QueryInterface. We have +embraced these ideas in @command{ns-3}. This was done primarily to address a +common problem in large software systems. A good example of this problem +happens in the @command{ns-3} Node class. + +@cindex OOP +@cindex weak base class +@cindex base class bloat +@cindex Swiss Army Knife class +@cindex Node +If one were to take the standard OOP view of specializing a @code{Node} into +an internet host, for example, one would typically inherit from the @code{Node} +base class and include functionality to implement such things as internet +routing and a TCP/IP protocol stack. Other types of @code{Node}s might +inherit from the node class and specialize in different ways, or further +specialize the internet host class, treating it as a base class. This can +result in a complicated inheritance tree in which some specializations are +simply not available to other branches of the tree which can make reuse +difficult or impossible. This is known as the @emph{weak base class} problem +and creates pressure to drive functionality up the inheritance tree into the +base classes. This, in turn, results in @emph{base class bloat} and the +resulting @emph{swiss army knife} base classes which end up trying to do +everything in one place. + +Even if one successfully avoided these swiss army knife base classes, one +would also want to be able to treat new specializations of @code{Node} +generically in the system. This means one would pass references to the base +class (@code{Node}) across public APIs. This introduces @emph{upcasts} prior +to passing across public APIs and corresponding @emph{downcasts} on the other +side in order to gain access to required specialized functions. As the +inheritance tree becomes more complicated, this approach can cause another +related problem known as the @emph{fragile base class} problem. This happens +when changes to the base class cause unexpected problems in the various and +sundry subclasses. + +These effects seem always to result in a positive feedback loop driving +everything into the base class and destroying much of the encapsulation which +is a hallmark of the object oriented approach. + +@subsection Interface Composition +@cindex Node +There is a completely different way to address the Node specialization +problem. Instead of approaching the situation using inheritance, one can +look at the problem as one of composition. We can look at the @code{Node} +class as a container of sorts that holds other objects. In this case, the +objects would be instances of the classes implementing the internetwork +routing code, or the TCP/IP protocol stack described above. This approach +preserves the encapsulation and solves the weak base class, base class bloat +and fragile base class problems; but the question of method dispatch +immediately comes to mind. + +@cindex delegation +In many systems, @emph{delegation} is used. The base class, @code{Node}, +in this approach would provide methods that simply forward to the objects +implementing the desired functionality. This situation clearly does not +address the base class bloat problem since dispatch methods must be added +to the base class. The situation is mitigated somewhat by pushing the +implementation of the dispatch methods to contained objects, but the +fundamental problems are still present. What is really needed is a way +to compose objects but at the same time keep the interfaces to those +objects separated. + +@cindex aggregation +Composition, usually called @emph{aggregation}, along with runtime Interface +discovery is the solution that Microsoft originally championed and that +@command{ns-3} has adopted --- albeit with many simplifications and a few name +changes. + +@subsection Objects and Interfaces +@cindex COM +@cindex QueryInterface +Now that we have mentioned Microsoft COM and are almost obligated to mention +the terms Interface and QueryInterface. For those familiar with COM, loosely +speaking, QueryInterface is to COM as GetObject is to @command{ns-3}. +The analogy, while good conceptually, is superficial from an implementation +point of view. + +@cindex Node +Addressing our current example of a @code{Node}, generically speaking, each +node needs to aggregate an object that will implement internetwork routing +and TCP/IP. The system will need to provide a mechanism for locating the +aggregated objects and allow a client to discover them. + +@cindex aggregation +@cindex Object +These aggregated objects have interfaces in the C++ sense of collections of +method signatures. In @command{ns-3}, when objects are capable of +participating in this aggregation process, they are called @command{ns-3} +@code{Objects}. @code{Objects} receive the functionality required for this + participation by inheriting from the @command{ns-3} base class @code{Object}. + +Note well that when we write the word @code{Object} (note the uppercase 'O' in +the spelling and the change of font) we are referring to a kind of C++ object +that has inherited the capability of participating in an aggregation. The +@command{ns-3}-specific word @code{Object} can have a significantly different +meaning than that of a vanilla C++ object outside the aforementioned +inheritance tree, and the difference is only readily apparent via context. +In this tutorial we will always write the @command{ns-3}-specific kind of +@code{Object} in a fixed font; and will write the vanilla C++ term object in +normal font. In conversation, you will need to be careful to understand which +term is meant: object or @code{Object}. + +Once an object has inherited from class @code{Object} it has the ability to +@emph{host} an aggregation. This means that it has the ability to add other +@code{Objects} to its aggregation via the method @code{AggregateObject}. It +also means that it can provide a service to @emph{discover} other objects in +its aggregation via the method @code{GetObject}. + +@cindex base class +Technically, the class named @code{Object} is simply a base class that you +will inherit from if you want your @code{Objects} to support aggregation and +discovery. Many systems have a base class that implements common +functionality and these base classes are typically called somthing like +Object. The @command{ns-3} version of this base class relates primarily to +@code{Object} aggregation and discovery, although it does also provide methods +to help with intrusive reference counting and tracing as well. + +When a C++ object inherits from the ns-3 Object base class, it is conceptually +promoted to an ns-3 @code{Object} irrespective of how the object was declared +(e.g., as an abstract base class, concrete class, with virtual methods, etc.). +In ns-3, you should associate inheritance from the class named @code{Object} +with promotion of an object to the status of some locatable @code{Object} +rather than with the form of the class declaration. + +@cindex COM +@cindex CORBA +@cindex ORBit +For those of you unfamiliar with Microsoft COM, CORBA or ORBit, this might +sound obvious. For those of with such a background, the point we are making +is that there is no such thing in @command{ns-3} as a separate Interface +declaration, no such thing as an Interface Definiition Language, no such thing +as a UUID or GUID, etc. In @command{ns-3} we just work with C++ objects that +may be given some very useful abilities by inheriting from the @command{ns-3} +base class @code{Object}. @command{Ns-3} @code{Objects} are not required to +inherit from classes composed of pure virtual methods in order to define an +Interface. It's all really just ``plain old C++.'' + +To summarize, when you instantiate an object that inherits from the +@code{Object} class, you will have a C++ object that has four important +properties: + +@cindex AggregateObject +@cindex GetObject +@itemize @bullet +@item The @code{Object} has a C++ interface defined by the collection of method signatures in its inheritance tree; +@item The @code{Object} has some way to identify its underlying class uniquely; +@item The @code{Object} is a kind of container that has the ability to aggregate other @code{Objects} using the method @code{AggregateObject}; +@item The @code{Object} exports a method called @code{GetObject} that allows for discovery of other aggregated @code{Objects}. +@end itemize + +@cindex base class +@cindex Object +It is crucially important to understand what we have described here +(especially for those coming from other systems that provide similar +functionality). A given C++ class has an object access interface that is +essentially the collection of method signatures specified in its inheritance +tree. This is a C++ object model thing. Ns-3 provides a base class from +which the class in question can inherit and be promoted to the status of +@code{Object}. Once a class becomes an @code{Object} it has inherited the +ability to aggregate and search for other @code{Objects} that are added to +its aggregation. + +That last detail is important. In @command{ns-3} @code{Objects} are both +containers and specifications for a object method access. We have previously +mentioned that the @code{Node} class acts as a container. In fact, the +@code{Node} class inherits from @code{Object} and is itself an @command{ns-3} +@code{Object}. So, when the @code{Node} object is created it is really an +aggregation of one @code{Object} and you can call @code{AggregateObject} or +@code{GetObject} on the resulting @code{Node} object. Along with being an +aggregation, the @code{Node} class also describes a public interface. THis +public interface (API) is declared just as any C++ object is declared, via its +class methods as specified in the inheritance tree. For those steeped in +COM or CORBA, this is where the concept of Interface works in @command{ns-3}. +Remember that it is generally true that @code{Objects} are both aggregations +and APIs. + +@subsection Aggregations +@cindex aggregate +The figure below shows how an @code{Object} could be illustrated in detail. +The line with the circle at the top of the diagram represents the appearance +of the @code{Object} API to the external world. This circle and line are +together called a lollipop because of its superficial similarity to a kind of +childs candy. + +@sp 1 +@center @image{oneobj,,,,png} + +@cindex API +You could declare this API and associated @code{Object} quite simply using a +non-virtual class as follows, + +@verbatim + class A : public Object { + public: + static ns3::TypeId GetTypeId (void) + { + static ns3::TypeId tid = ns3::TypeId ("A") + .SetParent (Object::GetTypeId ()) + .AddConstructor (); + return tid; + } + + A () + { + } + + void MethodA (void); + }; +@end verbatim + +The methods that are then available via the API labeled @code{A} in the +figure above are the methods inherited from the @code{Object} base class +(@code{GetObject}, @code{Ref}, and @code{Unref}) and those from class +@code{A} (@code{MethodA}). + +Note that you must declare a @code{TypeId} in your @code{Object} class, and +it must be declared static to make it class-wide in scope. This @code{TypeId} +is a unifying element in the @command{ns-3} object model and uniquely +identifies @code{Objects} at run-time as being instantiated from a particular +class. We'll have much more to say about @code{TypiId} shortly. + +You can think of the arc and arrow device coming off each side of the +illustrated @code{Objects} as part of a connector. These connectors allow +@code{GetObject} to search aggregations for an instance of a class type. +The figure below shows an aggregation of three @code{Objects}: A, B and C. +The class declarations for classes @code{B} and @code{C} are substantially +similar to that of class @code{A}. + +@sp 1 +@center @image{threeobj,,,,png} + +You can visualize these @code{Objects} as being snapped together like Lego +building blocks if you like. When @code{Objects} are aggregated, a +@code{GetObject} search path is formed through the connectors. In order +to create this aggregation you will first need to create the @code{Objects}. +These are just normal, everyday C++ objects that we can create using the +@code{CreateObject} template function and manage using smart pointers. The +following code should be obvious to you by now: + +@verbatim + Ptr a = CreateObject (); + Ptr b = CreateObject (); + Ptr c = CreateObject (); +@end verbatim + +@cindex aggregation +When you create an aggregation, you pick one of the @code{Objects} of the +aggregation to think of as the container. In this case well pick @code{Object} +A. In order to aggregate an @code{Object}, you simply call the method +@code{AggregateObject} that your class has inherited from class @code{Object}. +The following code will aggregate @code{Object B} and @code{Object C} onto +the @code{Object} (and container/aggregation) @code{A}. + +@cindex AggregateObject +@cindex GetObject +@cindex Object +@verbatim + a->AggregateObject (b); + a->AggregateObject (c); +@end verbatim + +Thats all there is to it. Now that you have those connectors snapped +together, you can ask each of the @code{Objects} in the aggregation for any of +the other @code{Objects} in the aggregation. Lets look at a simple example: + +@verbatim + Ptr newB = a->GetObject (); +@end verbatim + +Now, the explanation of what this snippet does is not as simple as writing it. +The left hand side of this assignment declares a smart pointer to the class +@code{B} to help with memory management of the returned @code{Object} pointer. +You should be very familiar with smart pointers at this stage of the tutorial. + +The right hand side illustrates how @code{GetObject} is acutally used. +The method @code{GetObject} is templated. The assocated template parameter +(between the brackets) specifies the @emph{class} that is being requested. +This is important. Since it is the class type that specifies the search +criteron, there can be only one instance of a particular class present in an +aggregation. Looking back a little, although the parameter to +@code{AggregateObject} appears to be a vanilla C++ object (@code{b} or @code{c} +above), it actually represents (is an instance of) a class that has an +associated @code{TypeId} and inherits from @code{Object}. When you call +@code{GetObject} you specify the search criterion (using the template +parameter) as a class name. This referenced class must also have an +associated @code{TypeId} and must also have inherited from @code{Object}. + +This may be summarized by saying that @code{AggregateObject} takes an +@emph{instance} of an object of a particular class that inherits from +@code{Object}. GetObject looks for a @emph{class} of a particular type +(that again inherits from @code{Object}) and possibly returns an aggregated +object instance of that type. + +Now that you have those conceptual connectors snapped together, you can ask +each of the @code{Objects} in the aggregation for any of the @code{Objects} +in the aggregation. For example we could walk the @code{Objects} asking each +for the next in the aggregation. First we would ask the @code{Object} pointed +to by the smart pointer @code{a} to look for the @code{Object} @code{class B}: + +@verbatim + Ptr newB = a->GetObject (); +@end verbatim + +Next, we can ask the @code{Object} pointed to by the smart pointer @code{newB} +to look for the @code{Object} representing @code{class C}: + +@verbatim + Ptr newC = newB->GetObject (); +@end verbatim + +@cindex Object +Then, we can ask the @code{Object} pointed to by the smart pointer @code{newC} +to look for the @code{Object} representing @code{class A} and complete our +circuit of the aggregation: + +@verbatim + Ptr newA = newC->GetObject (); +@end verbatim + +@cindex GetObject +@code{GetObject} has some important properties that we need to go over. +Technically, @code{GetObject} is a @emph{symmetric}, @emph{reflexive} and +@emph{transitive} operation with respect to the set of aggregated +@code{Objects}. + +@subsubsection Symmetry +@cindex symmetry +The symmetric nature of @code{GetObject} guarantees that if one performs a +@code{GetObject} on a given @code{Object} for the class of that same +@code{Object}, that @code{GetObject} must succeed. In other words, the +fact that you accessed the aggregation via an instance of an @code{Object A} +in the aggregation implies the reachability of that @code{Object} in the +aggregation. This is usually written (by Microsoft) as, + +@center must succeed (A >> A) + +We can illustrate this property with the code snippet, + +@verbatim + Ptr symmetricA = a->GetObject (); + NS_ASSERT (symmetricA); +@end verbatim + +Here we take as given an interface (smart) pointer --- named @code{a} --- on +which we perform a @code{GetObject} looking for the class that represents that +same @code{Object}. This call must always succeed and a smart pointer to the +aggregated instance of that class is returned. + +@subsubsection Reflexivity +@cindex reflexivity +Calls to @code{GetObject} must also be reflexive. This means that if you +successfully @code{GetObject} for @code{Object B} from @code{Object A}, then +you must always be able to @code{GetObject} for @code{A} from @code{B}. This +is usually written as, + +@center must succeed (A >> B, then B >> A) + +This property can be illustrated with the code snippet, + +@verbatim + Ptr b = a->GetObject (); + Ptr reflexiveA = b->GetObject (); + NS_ASSERT (reflexiveA); +@end verbatim + +If the first @code{GetObject} on @code{Object A} looking for @code{Object B} +succeeds, then a @code{GetObject} on @code{Object B} looking @code{Object A} +must succeed. + +@subsubsection Transitivity +@cindex transitivity +@code{GetObject} must also be transitive. This means that if one can +find @code{Object B} from @code{Object A}, and @code{Object C} from +@code{Object B}, then one must also be able to find @code{Object C} from +@code{Object A}. This is usually written as, + +@center must succeed (A >> B, and B >> C, then A >> C) + +This property can be illustrated with the code snippet, + +@verbatim + Ptr b = a->GetObject (); + Ptr c = b->GetObject (); + Ptr transitiveC = a->GetObject (); + NS_ASSERT (transitiveC); +@end verbatim + +If you can get to @code{Object B} from @code{Object A}, and you can get to +@code{Object C} from @code{Object B}, then a @code{GetObject} on +@code{Object A} looking for @code{Object C} must also succeed. + +@subsection Creating the TypeId +@cindex TypeId +@cindex GetTypeId +The final piece of this puzzle is the @code{TypeId}. Recall that the +declaration our eample object above included the following code + +@verbatim + static ns3::TypeId GetTypeId (void) + { + static ns3::TypeId tid = ns3::TypeId ("A") + .SetParent (Object::GetTypeId ()) + .AddConstructor (); + return tid; + } +@end verbatim + +This is the bit of code that ties this all together. For those unfamiliar +with the idioms involved, this declaration can be rather dense. First, let's +examine the function declaration itself. The following code, + +@verbatim + static ns3::TypeId GetTypeId (void) ... +@end verbatim + +declares a function that will be associated with all of the instances of the +given class. This is a function, not a method, in that it can be accessed +without a @emph{this} pointer; but it is associated with the class in a +namespace sense. The use of this kind of declaration allows one to write, + +@verbatim + return A::GetTypeId (void); +@end verbatim + +if the @code{TypeId} is needed for our @code{class A}. More generically the +class name can be substituted in a template, as is done deep in the +@command{ns-3} object system. + +From this perspective, if you leave out the middle of the function definition, +the boundaries should make sense to you. + +@verbatim + static ns3::TypeId GetTypeId (void) + { + return tid; + } +@end verbatim + +@cindex function-local variable +You are obviously looking at a global function associated with your class +that simply returns a @code{TypeId}. Now, what about the rest. The code + +@verbatim + static ns3::TypeId tid = ns3::TypeId ("A") + .SetParent (Object::GetTypeId ()) + .AddConstructor (); +@end verbatim + +when found inside the function declaration is called a function-local variable +with associated initialization. It'll be easier to pick this statement apart +piece by piece as well. The first line, + +@verbatim + static ns3::TypeId tid = ... +@end verbatim + +is the declaration of the function-local variable tid. This is essentially +an initialized global variable, the scope of which has been reduced to within +the enclosing method. You can think of this as a kind of global variable +that can only be accessed right there where it is created. If the variable +is initialized, this amounts to the same behavior as if a global static +initializer was declared in a namespace of the same name as your class. +Global static initializers are guaranteed by the C++ language definition to +be executed before your main procedure is entered. So are function-local +variables. + +The variable that is being initialized is of type @code{ns3::TypeId}, is +named @code{A::tid} since it is inside the class declaration for +@code{class A}, and is initialized by a call to the constructor for the class +@code{TypeId}. The constructor for @code{TypeId} takes a @code{std::string} +that can be used to locate the type information for your class. We usually +privide the class name as the string. + +Hopefully, this much of the declaration is now clear: + +@verbatim + static ns3::TypeId GetTypeId (void) + { + static ns3::TypeId tid = ns3::TypeId ("A") + ... + return tid; + } +@end verbatim + +All that is left now are the lines including @code{SetParent} and +@code{AddConstructor}. + +@verbatim + static ns3::TypeId tid = ns3::TypeId ("A") + .SetParent (Object::GetTypeId ()) + .AddConstructor (); +@end verbatim + +The last bit may seem quite odd at first glance, but don't let the way the +code is broken up over several lines throw you. If you saw something like, + +@verbatim + pointer->TypeId()->SetParent()->AddConstructor(); +@end verbatim + +you probably wouldn't hesitate at all. Clearly, you would think, a method +called @code{TypeId} is called using the pointer called @code{pointer} as +shown below. + +@verbatim + pointer->TypeId() +@end verbatim + +The method @code{TypeId} must further return a pointer to an object that has +a method called @code{SetParent}. Just as clearly, @code{SetParent} must +return a pointer to an object that has a method called @code{AddConstructor}. +The same sort of thing is happening in our code snipped, except we are using +references instead of pointers. Perhaps if we rearrange this code to live on +one line it will be clearer. + +@verbatim + ns3::TypeId ("A").SetParent (Object::GetTypeId ()).AddConstructor (); +@end verbatim + +It's just a string of method calls. The remaining question is then, what do +those three methods do. + +The first, @code{ns3::TypeId ("A")}, simply allocates a new type in the system +and allows you to refer to it in the future by a string. We have mentioned +inheritance trees often in the previous discussion. The second method, +@code{SetParent} associates the class being defined with its parents in the +tree. Finally, the @code{AddConstructor} method allows you to specify a +constructor to be used when an instance of your class is created using +@code{CreateObject}. + +@verbatim + AddConstructor (); +@end verbatim + +You can interpret this as explaining to the @command{ns-3} object ssytem that +you have a constructor named @code{A::A} which takes no parameters. You are +saying that this constructor should be used when @code{CreateObject} is called +with no parameters. + +By including the structure of the inheritance tree, in @command{ns-3} we can +use implementation inheritance to easily create new @code{Objects}. You are +prevented from doing so in Microsoft COM, but this was almost universally +identified as a problem. + +So, looking at the entire @code{GetTypeId} declaration again, + +@verbatim + static ns3::TypeId GetTypeId (void) + { + static ns3::TypeId tid = ns3::TypeId ("A") + .SetParent (Object::GetTypeId ()) + .AddConstructor (); + return tid; + } +@end verbatim + +it should be clear what is happening. + +@subsection A Very Real Example +@cindex Node +@cindex AggregateObject +@cindex GetObject +@cindex Object +At this point you may be asking yourself what the point of all of this is, +since you already had those pointers laying around when you created the +objects. The typical case is that one will create and aggregate some number +of @code{Objects} in a constructor and return only a pointer to a single +@code{Object} as in our canonical example with @code{class Node}. In this +case, the @code{Node} would be created and the @code{Node} constructor might +create and call @code{AggregateObject} to aggregate the @code{Objects} for +internetwork routing and TCP/IP. From an external point of view, these +aggregated objects may be discovered at run-time using @code{GetObject}. + +Generally one tends to think of one of the @code{Objects} in the aggregation +as being the container and other @code{Objects} being aggregated to that +container. In the case of a Node, for example, it is quite natural to think +of the Node as being the container which contains protocol stacks, internet +routing, etc. So, lets start thinking about a real example by calling the +container @code{Object Node} instead of @code{A} as we have been. The +creation of this @code{Object} is found all over our example programs. For +example, you will find code like the following in +@code{samples/simple-point-to-point.cc}: + +@verbatim + Ptr n = CreateObject (); +@end verbatim + +It may appear obvious to you now that the @code{InternetNode} class name +provided to the template function @code{CreateObject} means that +@code{InternetNode} is an @command{ns-3} @code{Object} and you will be able to +call @code{GetObject} on the resulting smart pointer. Well, I'm afraid that's +not entirely true. It's slightly more complicated. + +Take a look at @code{src/internet-stack/internet-stack.h} and find the class +declaration for @code{InternetNode}. + +@verbatim + class InternetNode : public Node + { + public: + InternetNode(); + ... + }; +@end verbatim + +@cindex GetTypeId +@cindex TypeId +@cindex Object +There is no declaration of a @code{static TypeId GetTypeId (void)} in this +class. This means that the @code{InternetNode} is really not an @code{Object} +for which you can @code{GetObject}. It turns out that the @code{InternetNode} +is an @emph{implementation class} of the @code{Node Object}. + +You may recall that there can be an implicit cast in a smart pointer +assignment if the cast is to a visible, unambiguous base class. That is, in +fact, what is happening here. Now, take a look at @code{src/node/node.h} and +find the class declaration for @code{class Node}. There you will find, + +@verbatim + class Node : public Object + { + public: + static TypeId GetTypeId (void); + ... + }; +@end verbatim + +Class @code{InternetNode} inherits from class @code{Node} that, in turn, +inherits from class @code{Object}. It is @code{Node} that provides a +@code{GetTypeId} method. Therefore it is @code{Node} that is an +@command{ns-3} @code{Object}. Note well that @code{InternetNode} is not an +@code{Object} in the sense that one should call @code{GetObject} on an +aggregation looking for an @code{InternetNode} class. That is, you should not +do, + +@verbatim + Ptr i = node->GetObject (); +@end verbatim + +since there really is not InternetNode::GetTypeId. It is @code{Node} that is +the @emph{proper} @code{Object} in this case and you should view +@code{InternetNode} as an implementation of the @code{Node Object}. This may +become clearer as we look a little deeper. + +We spoke of a protocol stack that is aggregated to a @code{Node} in our +discussions above, what we see in the real @command{ns-3} code is that this +is represented by the @code{Ipv4 Object}. If you look in +@code{src/node/ipv4.h} you will find, + +@verbatim + class Ipv4 : public Object + { + public: + static TypeId GetTypeId (void); + ... + }; +@end verbatim + +Since class @code{Ipv4} inherits from class @code{Object} and has a +@code{GetTypeId}, it is an @command{ns-3} @code{Object}. If you look in +@code{src/node/ipv4.cc} you will find, + +@verbatim +TypeId +Ipv4::GetTypeId (void) +{ + static TypeId tid = TypeId ("Ipv4") + .SetParent (); + return tid; +} +@end verbatim + +After all of this reading you know that this code snippet is asking the +system to create a unique @code{TypeId} for the @code{Ipv4} class and +declares that @code{Ipv4} inherits from class @code{Object}. This is what +makes an @code{Ipv4} an @code{Object}. + +@cindex Ipv4 +It turns out that the Ipv4 class is an abstract base class (ABC). There are +a number of pure virtual methods declared in that class. This means that +an @code{Ipv4} object may not be instantiated. This is reflected by the fact +that there are no constructors registered in the @code{GetTypeId} method above. +What is instantiated in the real system is an implementation class, called +@code{Ipv4Impl}. This class inherits from @code{Ipv4} and provides the +required virtual methods. This is where understanding what is an +@code{Object} and what is not can get tricky. The @code{Object} is the +@code{Ipv4} class since that is where the @code{GetTypeId} is found. The fact +that you see @code{GetTypeId} there tells you that the @code{Ipv4} class is +the class for which you can @code{GetObject}. + +@cindex implementation class +The class @code{Ipv4Impl} provides an implementation for the pure virtual +methods in @code{Ipv4}. Since class @code{Ipv4} cannot be instantiated, one +instantiates the @code{Ipv4Impl} class to create an @code{Ipv4} @code{Object}. +You will use the @code{CreateObject} template function to create an object that +implements the methods of an @code{Object}. You can probably see how this +gets even more tricky in conversation. + +Once the @code{Ipv4Impl} object is instantiated, the resulting pointer is +immediately cast to an @code{Ipv4} pointer. Clients will then use the +methods specified in the @code{Ipv4} class to access the @code{Ipv4 Object} +methods which are, in turn, implemented in the @code{Ipv4Impl} object. + +If you now look in the file, @code{src/internet-stack/internet-stack.cc} you +will see the following code in @code{InternetNode::Construct} that creates the +@code{Ipv4} Interface and aggregates it. + +@verbatim + Ptr ipv4Impl = CreateObject (ipv4); + ... + Object::AggregateObject (ipv4Impl); +@end verbatim + +Note that the parameter @code{ipv4} passed to the @code{CreateObject} template +function is actually a pointer to an @code{Ipv4L3Protocol} which you can +ignore at this point --- it doesn't really have anything to do with the +@code{Ipv4} Interface. + +This is exactly the same thing that is happening in the case of the +@code{InternetNode}. + +@verbatim + Ptr n = CreateObject (); +@end verbatim + +@cindex implementation object +@code{CreateObject} is being called to create an implementation object, +in this case @code{InternetNode}, which implements the methods of the +@code{Node Object}. It is the resulting @code{Node Object} which you would +use as the container and it is the @code{Node} class that you would use as +the template parameter when calling @code{GetObject}. In the same way, you +would @emph{not} want to do, + +@verbatim + Ptr ipv4 = node->GetObject (); +@end verbatim + +Rather you should understand that the @emph{proper} @code{Object} is the +@code{Ipv4} not the @code{Ipv4Impl} and do the following, + +@verbatim + Ptr ipv4 = node->GetObject (); +@end verbatim + +@cindex CreateObject +This does illustrate that the fact that whether an object created by +@code{CreateObject} is or is not an @code{Object} in the usual sense can be +quite well hidden if you are casually looking at the object creation code. +The designers of the system had long and involved discussions on this issue +and in the end decided that mnemonic aids such as Hungarian notation were a +stylistic thing and you should just refer to the system documentation to +determine what objects are @command{ns-3} @code{Objects} and what the APIs +of those @code{Objects} actually are (RTFM --- as in Read the Fine Manual, +of course). + +@cindex AggregateObject +@cindex Object +In the case of @code{Ipv4Impl}, you know that the class inherits somehow +from @code{Object} since there is a call to @code{AggregateObject} that +refers to an instance of an @code{Ipv4Impl}. You will have to go to +the header file @code{src/internet-stack/ipv4-impl.h} and find that +@code{Ipv4Impl} inherits from class @code{Ipv4}. You will then have go to +the file @code{src/node/ipv4.h} and see that it inherits from @code{Object} and +defines a @code{GetTypeId}. Thus the @code{Object} for which you can +@code{GetObject} is really the @code{Ipv4 Object}. + +Returning to some real @command{ns-3} example code, lets take a look at +@code{examples/simple-point-to-point.cc}. You will find the following +code in this file: + +@verbatim + Ptr n0 = CreateObject (); + ... + Ptr ipv4; + ipv4 = n0->GetObject (); + ipv4->SetDefaultRoute (Ipv4Address (``10.1.1.2''), 1); +@end verbatim + +@cindex InternetNode +@cindex Node +@cindex Object +@cindex GetObject +The first line creates an @code{InternetNode} implementation object and casts +the resulting smart pointer to a @code{Node} as we have discussed extensively. +The next line shown declares a smart pointer to an @code{Ipv4 Object}. We +then do a @code{GetObject} on the @code{Node} looking for the +@code{Ipv4 Object}. You know since you've read every line of this tutorial +in detail exactly how that @code{Ipv4 Object} got into every @code{Node}. You +know that the @code{GetObject} will return a smart pointer to its aggregated +@code{Ipv4} Interface. Once we have the @code{Ipv4} smart pointer, we simply +use it as if it were any other C++ object. The last line shows this by +setting the default route for the node. + +@section Caveats +There are a few things that you should remember but which may not be +immediately obvious. + +@subsection Ns-3 Objects are Associated with Classes not C++ objects +@cindex Object +@cindex GetObject +@cindex iterate +@cindex aggregation +@cindex GetNDevices +Okay, you can see some of the problems with the terminology popping up again. +We are reminding you that when you do a GetObject you are providing the key +to the lookup by giving a class name and not anything that is unique to a +C++ object. + +You cannot add more than one @code{Object} of a given type (class name) to an +aggregation. If you need to contain a number of @code{Objects} of the same +type in the same aggregation, you will need to provide a separate container +over which you can iterate. For example, the @code{Node} class provides +methods, + +@verbatim + uint32_t GetNDevices (void) const; + Ptr GetDevice (uint32_t index) const; +@end verbatim + +that are used iterate over the multiple @code{NetDevice} @code{Objects} +associated with it. + +@emph{Remember: Object types do not identify objects.} + +@subsection Dont use GetObject to Check Your Own Type. +@cindex GetObject +It is tempting to use @code{GetObject} as a form of runtime type +information. Dont do it. You have no control over what @emph{other} +object may be added to your aggregation. Someone else may have +appropriated (reimplemented) your type and aggregated themselves onto the +aggregation. + +Consider a socket factory implementation. Sockets can be either UDP sockets +or TCP sockets. A socket factory will have a generic @code{SocketFactory} +Object and either a UDP specific interface for setting UDP parameters or a +similar TCP-specific interface. + +Consider what might happen if you declared your socket factory as a partially +abstract base class, and then provided separate implementations for UDP and +TCP specific methods of this factory in separate concrete classes. Now +consider what might happen if you used @code{GetObject} in your base class +to determine if you were a UDP or a TCP factory. + +If a factory, say the UDP version, were not aggregated to any other +@code{Object}, the base class could @code{GetObject} on itself for the +UDP-specific class name. If the @code{GetObject} succeeded, it could then +infer that it was a UDP implementation and would then do any UDP-specific +tasks it could. [Experienced C++ folks are cringing about how +horrible this design is, but bear with me --- its a simple illustration of +a specific and perhaps not-too-obvious problem.] + +If another factory, say the TCP version, were not aggregated to any other +Interface, the base class could @code{GetObject} on itself for the UDP-specific +interface. If this failed, it could then infer that it had a TCP +implementation and would then do any TCP-specific tasks it could. + +Now, what happens when these two working objects are aggregated together by +some innocent end-user. Since the @code{Objects} are conceptually snapped +together, the TCP implementation would suddenly begin finding the UDP +Interface from the other class factory and think it was the UPD implementation. + +@emph{Objects should not be used as run-time type information.} + +@section Connecting the Dots +@cindex Object +@cindex GetObject +@cindex AggregateObject +@cindex GetTypeId +@cindex API +This may all sound very complicated to you if this is your first exposure to +these concepts. It may be annoying if I tell you that its really not as hard +as it sounds. Rest assured that if you take some time, look at and understand +the examples and write a little test code it will all come together for you. +Grep around the system for @code{AggregateObject} and @code{GetObject} and +take a look at how we have used them. This will also give you a good idea of +what our core @code{Objects} and associated APIs are. If you grep for +@code{GetTypeId} you will find most, if not all of the @code{Object} API +interface declarations in the system. The more you see this idiom in +use, the more comfortable you will be with the idea and the more you will see +how this addresses the weak base class, swiss army knife base class, and +fragile base class problems I explained at the beginning. + +As I alluded to earlier, the developers had long discussions regarding how to +make navigating the @code{Object} environment easier. The primary issue was +how we could make it easier to convey to you, the model writer, that an object +was an @code{Object}. We originally used similar terminology as Microsoft +COM and used QueryInterface instead of @code{GetObject}. One suggestion was +to adopt the convention that classes that implemented Interfaces must begin +with the letter I. Microsoft does this, as exemplified by the class IUnknown. +We also toyed with the idea of beginning our header files with ``i-'' as in +``i-ipv4.h.'' We considered forcing some structure on Interfaces with a pure +virtual class specification, the names of which begin with an I; and +corresponding implementations, the names of which begin with a C. This all +got out of hand fairly quickly. + +In the end we decided that we were really discussing issues of programming +style, and we really could not come up with a strong reason to impose any +particular solution. No matter what direction we took, we ended up with some +form of extra confusion or extra complexity somewhere in the system. The +resulting system is extremely flexible and easy to use. It is, unfortunately, +sometimes hard to document and talk about. + +@cindex Feynman +If it helps you to think in terms of Microsoft COM and Interfaces, by all means +do so, just be aware that even though @command{ns-3} @code{Objects} descend +from COM in some sense, there are subtle differences that may get you lost or +into trouble. So to paraphrase Feynman one more time, + +@quotation +``@command{Ns-3} @code{Objects} do not behave like COM Components, or Java +Beans, or CORBA objects, or clouds or weights on springs, or like anything +that you have ever seen --- they are @command{ns-3} components.'' +@end quotation + +Just get very familiar with the @command{ns-3} object model. It is the heart +of the system and if you do not understand it you will not understand how to +write an @command{ns-3} model properly. + +@c ======================================================================== +@c Doxygen +@c ======================================================================== + +@node The-Doxygen-Documentation-System +@chapter The Doxygen Documentation System + +@node How-To-Change-Things +@chapter How to Change Things + +@node How-To-Set-Default-Values +@chapter How to Set Default Values + +@node How-To-Write-A-New-Application +@chapter How to Write a New Application + diff --git a/doc/manual/output.texi b/doc/manual/output.texi new file mode 100644 index 000000000..185608b42 --- /dev/null +++ b/doc/manual/output.texi @@ -0,0 +1,462 @@ + +@c ======================================================================== +@c Simulation Output +@c ======================================================================== + +@node Simulation Output +@chapter Simulation Output + +At this point, you should be able to execute any of the built-in +programs distributed with @command{ns-3}. Next, we will look at +how to generate and tailor the simulation output, before turning +to how to modify simulation scripts to do different things. + +@node Tracing Basics +@section Tracing Basics + +The whole point of simulation is to generate output for further +study, and the @command{ns-3} tracing system is a primary +mechanism for this. +Since @command{ns-3} is a C++ program, standard facilities for +generating output from C++ programs apply: + +@verbatim +#include +... +int main () +{ + ... + std::cout << "The value of x is " << x << std::endl; + ... +} +@end verbatim + +The goal of the @command{ns-3} tracing system is to +provide a structured way to configure the simulator to output results +in standard or modifiable formats. +@itemize @bullet +@item For basic tasks, the tracing system should allow the user to +generate standard tracing for popular tracing sources, and to customize +which objects generate the tracing. +@item Intermediate users will be able to extend the tracing system to +modify the output format generated, or to insert new tracing sources, +without modifying the core of the simulator. +@item Advanced users can modify the simulator core to add new +tracing sources and sinks. +@end itemize + +The @command{ns-3} tracing system is fundamentally built on the +concept of separating tracing sources from sinks. +@enumerate +@item Trace sources (e.g., provide access to every packet received) +@item Trace sinks (e.g., print out the packet) +@item A mechanism to tie together sources and sinks +@end enumerate +The rationale for this division is to allow users to attach new +types of sinks to existing tracing sources, without requiring +users to edit and recompile the core of the simulator. +Thus, in the example above, a user could write a new tracing sink +and attach it to an existing tracing source. What remains to +be defined is a way for users to find these hooks (tracing sources) +and attach sinks to them. A new tracing namespace is defined for +this purpose. + +We will first walk through how some pre-defined sources and sinks +are provided and may be customized with little user effort. We +return later in this chapter to advanced tracing configuration including +extending the tracing namespace and creating new tracing sources. + +@subsection ASCII tracing +@cindex ASCII +For Internet nodes, the ASCII trace wrapper is a wrapper around +the @command{ns-3} low-level +tracing system that lets you get access to underlying trace events easily. +The output of a trace of a simulation run is an ASCII file --- thus the name. +In the spririt of keeping things simple, you won't be able to control or +configure the output at this stage. + +For those familiar with @command{ns-2} output, this type of trace is +analogous to the @command{out.tr} generated by many scripts. + +@cindex tracing packets +Let's just jump right in. As usual, we need to include the definitions +related to using ASCII tracing (don't edit any files quite yet): + +@verbatim + #include "ns3/ascii-trace.h" +@end verbatim + +We then need to add the code to the script to actually enable the ASCII tracing +code. The following code must be inserted before the call to +@code{Simulator::Run ();}: + +@verbatim + AsciiTrace asciitrace ("tutorial.tr"); + asciitrace.TraceAllQueues (); + asciitrace.TraceAllNetDeviceRx (); +@end verbatim + +The first line declares an object of type @code{AsciiTrace} named +@code{asciitrace} and passes a string parameter to its constructor. This +parameter is a file name to which all of the trace information will be written. +The second line, @code{asciitrace.TraceAllQueues ();} asks the trace object to +arrange that all queue operations (enqueue, dequeue, drop) on the queues +in all of the nodes of the system be traced. On the receive side, +@code{asciitrace.TraceAlllNetDeviceRx ()} traces packets received by +a NetDevice. For those familiar with @command{ns-2}, these are equivalent +to the popular trace points that log "+", "-", "d", and "r" events. + +Try running the following program from the command line: +@verbatim + ./waf --run tutorial-csma-echo-ascii-trace +@end verbatim + +@cindex tutorial.tr +Just as you have seen previously, you will see some messages from @emph{Waf} +and then the ``Compilation finished successfully'' message. The +next message, @code{UDP Echo Simulation} is from the running program. When +it ran, the program will have created a file named @code{tutorial.tr}. +Because of the way that Waf works, the file is not created in the local +directory, it is created at the top-level directory of the repository. So, +change into the top level directory and take a look at the file +@code{tutorial.tr} in your favorite editor. + +@subsubsection Parsing Ascii Traces +@cindex parsing ascii traces + +This section parses in detail the structure of the ascii tracing +output. If you find this output format self explanatory (it +resembles tcpdump output), you may skip to the next +section on pcap tracing. + +@cindex trace event +There's a lot of information there in a pretty dense form, but the first thing +to notice is that there are a number of distinct lines in this file. It may +be difficult to see this clearly unless you widen your windows considerably. +Each line in the file corresponds to a @emph{trace event}. A trace event +happens whenever specific conditions happen in the simulation. In this case +we are tracing events on the @emph{device queue} present in every net device +on every node in the simulation. The device queue is a queue through which +every packet destined for a channel must pass --- it is the device +@emph{transmit} queue. Note that each line in the trace file begins with a +lone character (has a space after it). This character will have the following +meaning: + +@cindex enqueue +@cindex dequeue +@cindex drop +@itemize @bullet +@item @code{+}: An enqueue operation occurred on the device queue; +@item @code{-}: A dequeue operation occurred on the device queue; +@item @code{d}: A packet was dropped, typically because the queue was full. +@end itemize + +Let's take a more detailed view of the first line. I'll break it down into +sections (indented for clarity) with a two digit reference number on the +left side: + +@verbatim + 00 + + 01 2 + 02 nodeid=0 + 03 device=0 + 04 queue-enqueue + 05 pkt-uid=9 + 06 ETHERNET + 07 length/type=0x806, + 08 source=08:00:2e:00:00:00, + 09 destination=ff:ff:ff:ff:ff:ff + 10 ARP(request + 11 source mac: 08:00:2e:00:00:00 + 12 source ipv4: 10.1.1.1 + 13 dest ipv4: 10.1.1.2) + 14 ETHERNET fcs=0 +@end verbatim + +@cindex trace event +@cindex simulation time +The first line of this expanded trace event (reference number 00) is the +queue operation. We have a @code{+} character, so this corresponds to an +@emph{enqueue} operation. The second line (reference 01) is the simulation +time expressed in seconds. You may recall that we asked the +@code{UdpEchoClient} to start sending packets at two seconds. Here we see +confirmation that this is, indeed, happening. + +@cindex node number +@cindex net device number +@cindex smart pointer +The next lines of the example listing (references 02 and 03) tell us that +this trace event originated in a given node and net device. Each time a node +is created it is given an identifying number that monotonically increases from +zero. Therefore, @code{nodeid=0} means that the node in which the given trace +event originated is the first node we created. In the case of our script, +this first node is is the node pointed to by the smart pointer @code{n0}. Not +too surpsisingly, this is also the node to which we attached the +@code{UdpEchoClient}. The device number is local to each node, and so the +device given by @code{device=0} is the first net device that we added to the +node in question. In our simulation, this corresponds to the +@code{CsmaNetDevice} we added to node zero (@code{n0}). + +@cindex uid +@cindex unique ID +@cindex packet +The next line (reference 04) is a more readable form of the operation code +seen in the first line --- i.e., the character @code{+} means +@code{queue-enqueue}. Reference number 05 indicates that the @emph{unique id} +of the packet being enqueued is @code{9}. The fact that the first packet we +see has a unique ID of 9 should indicates to you that other things have +happened in the protocol stack before we got to this point. This will become +clear momentarily. + +@cindex Ethernet +@cindex MAC address +Reference items 06 and 14 indicate that this is an Ethernet packet with +a zero (not computed) checksum (note the indentation to make parsing this +trace event a little easier). Reference 08 and 09 are the source and +destination addresses of this packet. The packet is from the MAC address we +assigned to the node zero net device in the script, and is destined for the +broadcast address --- this is a broadcast packet. + +@cindex Address Resolution Protocol +@cindex ARP +@cindex ARP|request +Reference items 10 through 13 make clear what is happening. This is an ARP +(Address Resolution Protocol) request for the MAC address of the node on +which the @code{UdpEchoServer} resides. The protocol stack can't send a UDP +packet to be echoed until it knows (resolves) the MAC address; and this trace +event corresponds to an ARP request being queued for transmission to the local +network. The next line in the trace file (partially expanded), + +@verbatim + 00 - + 01 2 + 02 nodeid=0 + 03 device=0 + 04 queue-dequeue + 05 pkt-uid=9 + ... +@end verbatim + +shows the (same) ARP request packet being dequeued from the device queue by +the net device and (implicitly) being sent down the channel to the broadcast +MAC address. We are not tracing net device reception events so we don't +actually see all of the net devices receiving the broadcast packet. We do, +however see the following in the third line of the trace file: + +@verbatim + 00 + + 01 2.00207 + 02 nodeid=1 + 03 device=0 + 04 queue-enqueue + 05 pkt-uid=10 + 06 ETHERNET + 07 length/type=0x806, + 08 source=08:00:2e:00:00:01, + 09 destination=08:00:2e:00:00:00, + 10 ARP(reply + 11 source mac: 08:00:2e:00:00:01 + 12 source ipv4: 10.1.1.2 + 13 dest mac: 08:00:2e:00:00:00 + 14 dest ipv4: 10.1.1.1) + 15 ETHERNET fcs=0 +@end verbatim + +@cindex simulation time +@cindex ARP|response +Notice that this is a queue-enqueue operation (references 00 and 04) happening +on node one (reference 02) at simulation time 2.00207 seconds (reference 01). +Looking at the packet payload (references 10-14) we see that this is an ARP +reply to the request sent by node one. Note that the simulation time +(reference 01) is now 2.00207 seconds. This is direct result of the data rate +(5 mb/s) and latency (2 ms) parameters that we passed to the +@code{CsmaChannel} when we created it. Clearly the ARP request packet was +sent over the channel and received approximately 2 ms later by node one. A +corresponding ARP response packet was created and enqueued on node one's net +device. It is this enqueue trace event that has being logged. + +@cindex queue +@cindex queue|transmit +@cindex echo +Given the current state of affairs, the next thing you may expect to see is +this ARP request being received by node zero, but remember we are only looking +at trace events on the device @emph{transmit} queue. The reception of the ARP +response by node zero will not directly trigger any trace event in this case, +but it will enable the protocol stack to continue what it was originally doing +(trying to send an echo packet). Thus, the next line we see in the trace file +(@code{tutorial.tr}) is the first UDP echo packet being sent to the net device. + +@verbatim + 00 + + 01 2.00415 + 02 nodeid=0 + 03 device=0 + 04 queue-enqueue + 05 pkt-uid=7 + 06 ETHERNET + 07 length/type=0x800, + 08 source=08:00:2e:00:00:00, + 09 destination=08:00:2e:00:00:01 + 10 IPV4( + 11 tos 0x0 + 12 ttl 64 + 13 id 0 + 14 offset 0 + 15 flags [none] + 16 length: 1052) 10.1.1.1 > 10.1.1.2 + 17 UDP(length: 1032) + 18 49153 > 7 + 19 DATA (length 1024) + 20 ETHERNET fcs=0 +@end verbatim + +@cindex simulation time +@cindex echo +@cindex ARP +@cindex ARP|request +@cindex ARP|response +@cindex IP +@cindex Ipv4 +I won't go into too much detail about this packet, but I will point out a +few key items in the trace. First, the packet was enqueued at simulation time +of 2.00415 seconds. This time reflects the fact that the echo client +application started at 2. seconds and there were two ARP packets transmitted +across the network (two milliseconds + data transmission time each way). The +packet unique identifier (reference 05) is 7. Notice that this is a lower +number than the ARP request packet, which had a unique ID of 9. This tells +us that the UDP packet was actually created before the ARP request packet --- +which makes perfect sense since it was the attempt to send packet 7 that +triggered sending the ARP request packet 9. Note that this an Ethernet +packet (reference 06) like all other packets in this simulation, however this +particular packet carries an IPV4 payload and therefore has an IP version 4 +header (indicated by references 10-16). This Ipv4 in turn contains a UDP +header (references 17, 18) and finally 1024 bytes of data (reference 20). +Clearly, this is the UDP echo packet emitted by the +@code{UdpEchoClient Application}. + +The next trace event is an ARP request from node one. We can infer that node +one has received the UDP echo packet and the @code{UdpEchoServer Application} +on that node has turned the packet around. Just as node zero needed to ARP +for the MAC address of node one, now node one must ARP for the MAC address of +node zero. We see the ARP request enqueued on the transmit queue of node one; +then we see the ARP request dequeued from the tranmit queue of node one (and +implicitly transmitted to node zero). Then we see an ARP response enqueued +on the transmit queue of node zero; and finally the ARP response dequeued (and +implicitly transmitted back to node one). + +This exchange is summarized in the following trace event excerpts, + +@verbatim + + 2.00786 nodeid=1 ... ARP(request ... + - 2.00786 nodeid=1 ... ARP(request ... + + 2.00994 nodeid=0 ... ARP(reply ... + - 2.00994 nodeid=0 ... ARP(reply ... +@end verbatim + +The final two trace events in the @code{tutorial.tr} file correspond to the +echoed packet being enqueued for transmission on the net device for node one, +and that packet being dequeued (and implicitly transmitted back to node zero). + +@cindex AsciiTrace!TraceAllNetDeviceRx +@cindex ARP!request +If you look at the trace file (@code{tutorial.tr}) you will also see some +entries with an @code{r} event, indicating a +@emph{receive} trace event. Recall that the first packet sent on the network +was a broadcast ARP request. We should then see all four nodes receive a +copy of this request. This is the case, as the first four receive trace +events are, + +@verbatim + r 2.00207 nodeid=0 device=0 dev-rx pkt-uid=9 ARP(request ... + r 2.00207 nodeid=1 device=0 dev-rx pkt-uid=9 ARP(request ... + r 2.00207 nodeid=2 device=0 dev-rx pkt-uid=9 ARP(request ... + r 2.00207 nodeid=3 device=0 dev-rx pkt-uid=9 ARP(request ... +@end verbatim + +@cindex unique ID +You can see that a copy of the broadcast packet with unique ID 9 was received +by the net devices on nodes 0, 1, 2 and 3. We leave it up to you to parse the +rest of the trace file and understand the remaining reception events. + +@subsection PCAP Trace Wrapper +@cindex pcap +@cindex Wireshark +The @command{ns-3} @emph{pcap trace wrapper} is used to create trace files in +@code{.pcap} format. The acronym pcap (usually written in lower case) stands +for @emph{p}acket @emph{cap}ture, and is actually an API that includes the +definition of a @code{.pcap} file format. The most popular program that can +read and display this format is Wireshark (formerly called Ethereal). +However, there are many traffic trace analyzers that use this packet +format, including X, Y, and Z. We encourage users to exploit the +many tools available for analyzing pcap traces; below, we show how +tcpdump and Wireshark can be used.. + +@cindex tutorial-csma-echo-ascii-trace.cc +@cindex tutorial-csma-echo-pcap-trace.cc +The code used to enable pcap tracing is similar to that for ASCII tracing. +We have provided another file, @code{tutorial-csma-echo-pcap-trace.cc} that +uses the pcap trace wrapper. We have added the code to include the pcap +trace wrapper defintions: + +@verbatim + #include "ns3/pcap-trace.h" +@end verbatim + +And then added the following code below the AsciiTrace methods: + +@cindex PcapTrace +@cindex PcapTrace!TraceAllIp +@verbatim + PcapTrace pcaptrace ("tutorial.pcap"); + pcaptrace.TraceAllIp (); +@end verbatim + +The first line of the code immediately above declares an object of type +@code{PcapTrace} named @code{pcaptrace} and passes a string parameter to its +constructor. This object is used to hide the details of the actual tracing +subsystem. The parameter is a base file name from which the actual trace file +names will be built. The second line of code tells the @code{PcamTrace} +object to trace all IP activity in all of the nodes present in the simulation. + +@cindex interface index +Trace files are not created until trace activity is detected. Each file name +is composed of the base file name, followed by a @code{'-'}, a node id followed +by a @code{'-}', and an IP interface index. You will soon see a file named +@code{tutorial.pcap-0-1}, for example. This will be the trace file generated +as events are detected on node zero, interface index one. N.B. Interface +indices are different that net device indices --- interface index zero +corresponds to the loopback interface and interface index one corresponds to +the first net device you added to a node. + +You may run the new program just like all of the others so far: + +@cindex Waf +@verbatim + ./waf --run tutorial-csma-echo-pcap-trace +@end verbatim + +If you look at the top level directory of your distribution, you should now +see three log files: @code{tutorial.tr} is the ASCII trace file we have +previously examined. @code{tutorial.pcap-0-1} and @code{tutorial.pcap-1-1} +are the new pcap files we just generated. There will not be files +corresponding to nodes two and three since we have not sent any IP packets to +those nodes. + +@subsubsection Reading output with tcpdump +@cindex tcpdump + +@subsubsection Reading output with Wireshark +@cindex Wireshark +If you are unfamilar with Wireshark, there is a web site available from which +you can download programs and documentation: @uref{http://www.wireshark.org/}. + +If you have Wireshark available, you can open each of the trace files and +display the contents as if you had captured the packets using a +@emph{packet sniffer}. Note that only IP packets are traced using this +wrapper, so you will not see the ARP exchanges that were logged when using +the ASCII trace wrapper. You are encouraged to take a look at the contents +of these pcap files using your favorite pcap software (or Wireshark). + +@node Advanced Tracing +@section Advanced Tracing + diff --git a/doc/manual/packets.texi b/doc/manual/packets.texi new file mode 100644 index 000000000..cc00e0094 --- /dev/null +++ b/doc/manual/packets.texi @@ -0,0 +1,620 @@ +@node ns-3 Packets +@chapter ns-3 Packets + +The design of the Packet framework of @emph{ns} was heavily guided by a few +important use-cases: +@itemize @bullet +@item avoid changing the core of the simulator to introduce +new types of packet headers or trailers +@item maximize the ease of integration with real-world code +and systems +@item make it easy to support fragmentation, defragmentation, +and, concatenation which are important, especially in wireless systems. +@item make memory management of this object efficient +@item allow actual application data or dummy application bytes for +emulated applications +@end itemize + +@emph{ns} Packet objects contain a buffer of bytes: protocol headers and +trailers are serialized in this buffer of bytes using user-provided +serialization and deserialization routines. The content of this byte +buffer is expected to match bit-for-bit the content of a real packet on +a real network implementing the protocol of interest. + +Fragmentation and defragmentation are quite natural to implement within +this context: since we have a buffer of real bytes, we can split it in +multiple fragments and re-assemble these fragments. We expect that this +choice will make it really easy to wrap our Packet data structure within +Linux-style skb or BSD-style mbuf to integrate real-world kernel code in +the simulator. We also expect that performing a real-time plug of the +simulator to a real-world network will be easy. + +Because we understand that simulation developers often wish to store in +packet objects data which is not found in the real packets (such as +timestamps or any kind of similar in-band data), the @emph{ns} Packet class +can also store extra per-packet "Tags" which are 16 bytes blobs of data. +Any Packet can store any number of unique Tags, each of which is +uniquely identified by its C++ type. These tags make it easy to attach +per-model data to a packet without having to patch the main Packet +class or Packet facilities. + +Memory management of Packet objects is entirely automatic and extremely +efficient: memory for the application-level payload can be modelized by +a virtual buffer of zero-filled bytes for which memory is never allocated +unless explicitely requested by the user or unless the packet is fragmented. +Furthermore, copying, adding, and, removing headers or trailers to a packet +has been optimized to be virtually free through a technique known as +Copy On Write. + +Packets (messages) are fundamental objects in the simulator and +their design is important from a performance and resource management +perspective. There +are various ways to design the simulation packet, and tradeoffs +among the different approaches. In particular, there is a +tension between ease-of-use, performance, and safe interface +design. + +There are a few requirements on this object design: +@itemize @bullet +@item Creation, management, and deletion of this object +should be as simple as possible, while avoiding the +chance for memory leaks and/or heap corruption; +@item Packets should support serialization and deserialization +so that network emulation is supported; +@item Packets should support fragmentation and concatenation +(multiple packets in a data link frame), especially for wireless +support; +@item It should be natural for packets to carry actual application +data, or if there is only an emulated application and there is +no need to carry dummy bytes, smaller packets could be used with +just the headers and a record of the payload size, but not actual +application bytes, conveyed in the simulated packet. +@item Packets should facilitate BSD-like operations on mbufs, for +support of ported operating system stacks. +@item Additional side-information should be supported, such as +a tag for cross-layer information. +@end itemize + +@section Packet design overview + +Unlike @emph{ns-2}, in which Packet objects contain a buffer of C++ +structures corresponding to protocol headers, each network packet in +@emph{ns-3} contains a byte Buffer and a list of Tags: +@itemize @bullet +@item The byte buffer stores the serialized content of the chunks +added to a packet. The serialized representation of these chunks is +expected to match that of real network packets bit for bit +(although nothing forces you to do this) which means that the content +of a packet buffer is expected to be that of a real packet. +Packets can also be created with an arbitrary zero-filled payload +for which no real memory is allocated. +@item The list of tags stores an arbitrarily large set of arbitrary +user-provided data structures in the packet. Each Tag is uniquely +identified by its type; only one instance of each +type of data structure is allowed in a list of tags. These tags typically +contain per-packet cross-layer information or flow identifiers (i.e., +things that you wouldn't find in the bits on the wire). Each tag +stored in the tag list can be at most 16 bytes. +Trying to attach bigger data structures will trigger +crashes at runtime. The 16 byte limit is a modifiable compilation +constant. +@end itemize + +@float Figure,fig:packets +@caption{Implementation overview of Packet class.} +@image{figures/packet} +@end float + +Figure @ref{fig:packets} is a high-level overview of the Packet +implementation; more detail on the byte Buffer implementation +is provided later in Figure @ref{fig:buffer}. +In \nsthree, the Packet byte buffer is analogous to a Linux skbuff +or BSD mbuf; it is a serialized representation of the actual +data in the packet. The tag list is a container for extra +items useful for simulation convenience; if a Packet is converted +to an emulated packet and put over an actual network, the tags +are stripped off and the byte buffer is copied directly +into a real packet. + +The Packet class has value semantics: it can be freely copied around, +allocated on the stack, and passed to functions as arguments. Whenever +an instance is copied, the full underlying data is not copied; it +has ``copy-on-write'' (COW) semantics. Packet instances can be passed +by value to function arguments without any performance hit. + +The fundamental classes for adding to and removing from the byte +buffer are @code{class Header} and @code{class Trailer}. +Headers are more common but the below discussion also largely applies to +protocols using trailers. Every protocol header that needs to +be inserted and removed from a Packet instance should derive from +the abstract Header base class and implement the private pure +virtual methods listed below: +@itemize @bullet +@item @code{ns3::Header::SerializeTo()} +@item @code{ns3::Header::DeserializeFrom()} +@item @code{ns3::Header::GetSerializedSize()} +@item @code{ns3::Header::PrintTo()} +@end itemize +Basically, the first three functions are used to serialize and deserialize +protocol control information to/from a Buffer. For example, +one may define @code{class TCPHeader : public Header}. The +TCPHeader object will typically consist of some private data +(like a sequence number) and public interface access functions +(such as checking the bounds of an input). But the underlying +representation of the TCPHeader in a Packet Buffer is 20 serialized +bytes (plus TCP options). The TCPHeader::SerializeTo() function would +therefore be designed to write these 20 bytes properly into +the packet, in network byte order. The last function is used +to define how the Header object prints itself onto an output stream. + +Similarly, user-defined Tags can be appended to the packet. +Unlike Headers, Tags are not serialized into a contiguous buffer +but are stored in an array. By default, Tags are limited to 16 bytes in +size. Tags can be flexibly defined to be any type, but there +can only be one instance of any particular object type in +the Tags buffer at any time. The implementation makes use +of templates to generate the proper set of Add(), Remove(), +and Peek() functions for each Tag type. + +@section Packet interface + +The public member functions of a Packet object are as follows: + +@subsection Constructors +@verbatim + /** + * Create an empty packet with a new uid (as returned + * by getUid). + */ + Packet (); + /** + * Create a packet with a zero-filled payload. + * The memory necessary for the payload is not allocated: + * it will be allocated at any later point if you attempt + * to fragment this packet or to access the zero-filled + * bytes. The packet is allocated with a new uid (as + * returned by getUid). + * + * \param size the size of the zero-filled payload + */ + Packet (uint32_t size); +@end verbatim + +@subsection Adding and removing Buffer data +The below code is reproduced for Header class only; similar functions +exist for Trailers. +@verbatim + /** + * Add header to this packet. This method invokes the + * ns3::Header::serializeTo method to request the header to serialize + * itself in the packet buffer. + * + * \param header a reference to the header to add to this packet. + */ + void Add (Header const &header); + /** + * Deserialize header from this packet. This method invokes the + * ns3::Header::deserializeFrom method to request the header to deserialize + * itself from the packet buffer. This method does not remove + * the data from the buffer. It merely reads it. + * + * \param header a reference to the header to deserialize from the buffer + */ + void Peek (Header &header); + /** + * Remove a deserialized header from the internal buffer. + * This method removes the bytes read by Packet::peek from + * the packet buffer. + * + * \param header a reference to the header to remove from the internal buffer. + */ + void Remove (Header const &header); + /** + * Add trailer to this packet. This method invokes the + * ns3::Trailer::serializeTo method to request the trailer to serialize + * itself in the packet buffer. + * + * \param trailer a reference to the trailer to add to this packet. + */ +@end verbatim + +@subsection Adding and removing Tags +@verbatim + /** + * Attach a tag to this packet. The tag is fully copied + * in a packet-specific internal buffer. This operation + * is expected to be really fast. + * + * \param tag a pointer to the tag to attach to this packet. + */ + template + void AddTag (T const &tag); + /** + * Remove a tag from this packet. The data stored internally + * for this tag is copied in the input tag if an instance + * of this tag type is present in the internal buffer. If this + * tag type is not present, the input tag is not modified. + * + * This operation can be potentially slow and might trigger + * unexpectedly large memory allocations. It is thus + * usually a better idea to create a copy of this packet, + * and invoke removeAllTags on the copy to remove all + * tags rather than remove the tags one by one from a packet. + * + * \param tag a pointer to the tag to remove from this packet + * \returns true if an instance of this tag type is stored + * in this packet, false otherwise. + */ + template + bool RemoveTag (T &tag); + /** + * Copy a tag stored internally to the input tag. If no instance + * of this tag is present internally, the input tag is not modified. + * + * \param tag a pointer to the tag to read from this packet + * \returns true if an instance of this tag type is stored + * in this packet, false otherwise. + */ + template + bool PeekTag (T &tag) const; + /** + * Remove all the tags stored in this packet. This operation is + * much much faster than invoking removeTag n times. + */ + void RemoveAllTags (void); +@end verbatim + +@subsection Fragmentation +@verbatim + /** + * Create a new packet which contains a fragment of the original + * packet. The returned packet shares the same uid as this packet. + * + * \param start offset from start of packet to start of fragment to create + * \param length length of fragment to create + * \returns a fragment of the original packet + */ + Packet CreateFragment (uint32_t start, uint32_t length) const; + + /** + * Concatenate the input packet at the end of the current + * packet. This does not alter the uid of either packet. + * + * \param packet packet to concatenate + */ + void addAtEnd (Packet packet); + + /oncatenate the input packet at the end of the current + * packet. This does not alter the uid of either packet. + * + * \param packet packet to concatenate + */ + void AddAtEnd (Packet packet); + /** + * Concatenate the fragment of the input packet identified + * by the offset and size parameters at the end of the current + * packet. This does not alter the uid of either packet. + * + * \param packet to concatenate + * \param offset offset of fragment to copy from the start of the input packet + * \param size size of fragment of input packet to copy. + */ + void AddAtEnd (Packet packet, uint32_t offset, uint32_t size); + /** + * Remove size bytes from the end of the current packet + * It is safe to remove more bytes that what is present in + * the packet. + * + * \param size number of bytes from remove + */ + void RemoveAtEnd (uint32_t size); + /** + * Remove size bytes from the start of the current packet. + * It is safe to remove more bytes that what is present in + * the packet. + * + * \param size number of bytes from remove + */ + void RemoveAtStart (uint32_t size); +@end verbatim + +@subsection Miscellaneous +@verbatim + /** + * \returns the size in bytes of the packet (including the zero-filled + * initial payload) + */ + uint32_t GetSize (void) const; + /** + * If you try to change the content of the buffer + * returned by this method, you will die. + * + * \returns a pointer to the internal buffer of the packet. + */ + uint8_t const *PeekData (void) const; + /** + * A packet is allocated a new uid when it is created + * empty or with zero-filled payload. + * + * \returns an integer identifier which uniquely + * identifies this packet. + */ + uint32_t GetUid (void) const; +@end verbatim + +@section Using Headers +@emph{walk through an example of adding a UDP header} + +@section Using Tags +@emph{walk through an example of adding a flow ID} + +@section Using Fragmentation +@emph{walk through an example of link-layer fragmentation/reassembly} + +@section Sample program +The below sample program (from @code{ns3/samples/main-packet.cc}) illustrates +some use of the Packet, Header, and Tag classes. + +@verbatim +/* -*- Mode:C++; c-basic-offset:4; tab-width:4; indent-tabs-mode:nil -*- */ +#include "ns3/packet.h" +#include "ns3/header.h" +#include + +using namespace ns3; + +/* A sample Header implementation + */ +class MyHeader : public Header { +public: + MyHeader (); + virtual ~MyHeader (); + + void SetData (uint16_t data); + uint16_t GetData (void) const; +private: + virtual void PrintTo (std::ostream &os) const; + virtual void SerializeTo (Buffer::Iterator start) const; + virtual void DeserializeFrom (Buffer::Iterator start); + virtual uint32_t GetSerializedSize (void) const; + + uint16_t m_data; +}; + +MyHeader::MyHeader () +{} +MyHeader::~MyHeader () +{} +void +MyHeader::PrintTo (std::ostream &os) const +{ + os << "MyHeader data=" << m_data << std::endl; +} +uint32_t +MyHeader::GetSerializedSize (void) const +{ + return 2; +} +void +MyHeader::SerializeTo (Buffer::Iterator start) const +{ + // serialize in head of buffer + start.WriteHtonU16 (m_data); +} +void +MyHeader::DeserializeFrom (Buffer::Iterator start) +{ + // deserialize from head of buffer + m_data = start.ReadNtohU16 (); +} + +void +MyHeader::SetData (uint16_t data) +{ + m_data = data; +} +uint16_t +MyHeader::GetData (void) const +{ + return m_data; +} + +/* A sample Tag implementation + */ +struct MyTag { + uint16_t m_streamId; +}; + +static TagRegistration g_MyTagRegistration ("ns3::MyTag", 0); + + +static void +Receive (Packet p) +{ + MyHeader my; + p.Peek (my); + p.Remove (my); + std::cout << "received data=" << my.GetData () << std::endl; + struct MyTag myTag; + p.PeekTag (myTag); +} + + +int main (int argc, char *argv[]) +{ + Packet p; + MyHeader my; + my.SetData (2); + std::cout << "send data=2" << std::endl; + p.Add (my); + struct MyTag myTag; + myTag.m_streamId = 5; + p.AddTag (myTag); + Receive (p); + return 0; +} +@end verbatim + +@section Implementation details + +@subsection Private member variables + +A Packet object's interface provides access to some private +data: +@verbatim + Buffer m_buffer; + Tags m_tags; + uint32_t m_uid; + static uint32_t m_global_uid; +@end verbatim +Each Packet has a Buffer and a Tags object, and a 32-bit unique ID (m\_uid). +A static member variable keeps track of the UIDs allocated. Note +that real network packets do not have a UID; the UID is therefore an +instance of data that normally would be stored as a Tag in the packet. +However, it was felt that a UID is a special case that is so often +used in simulations that it would be more convenient to store it +in a member variable. + +@subsection Buffer implementation + +Class Buffer represents a buffer of bytes. Its size is +automatically adjusted to hold any data prepended +or appended by the user. Its implementation is optimized +to ensure that the number of buffer resizes is minimized, +by creating new Buffers of the maximum size ever used. +The correct maximum size is learned at runtime during use by +recording the maximum size of each packet. + +Authors of new Header or Trailer classes need to know the public +API of the Buffer class. (add summary here) + +The byte buffer is implemented as follows: +@verbatim + struct BufferData { + uint32_t m_count; + uint32_t m_size; + uint32_t m_initialStart; + uint32_t m_dirtyStart; + uint32_t m_dirtySize; + uint8_t m_data[1]; + }; + struct BufferData *m_data; + uint32_t m_zeroAreaSize; + uint32_t m_start; + uint32_t m_size; +@end verbatim + +@itemize @bullet +@item @code{BufferData::m_count}: reference count for BufferData structure +@item @code{BufferData::m_size}: size of data buffer stored in BufferData structure +@item @code{BufferData::m_initialStart}: offset from start of data buffer where data was first inserted +@item @code{BufferData::m_dirtyStart}: offset from start of buffer where every Buffer which holds a reference to this BufferData instance have written data so far +@item @code{BufferData::m_dirtySize}: size of area where data has been written so far +@item @code{BufferData::m_data}: pointer to data buffer +@item @code{Buffer::m_zeroAreaSize}: size of zero area which extends before @code{m_initialStart} +@item @code{Buffer::m_start}: offset from start of buffer to area used by this buffer +@item @code{Buffer::m_size}: size of area used by this Buffer in its BufferData structure +@end itemize + +@float Figure,fig:buffer +@caption{Implementation overview of a packet's byte Buffer.} +@image{figures/buffer,15cm} +@end float + +This data structure is summarized in Figure @ref{fig:buffer}. +Each Buffer holds a pointer to an instance of a BufferData. Most +Buffers should be able to share the same underlying BufferData and +thus simply increase the BufferData's reference count. If they have to +change the content of a BufferData inside the Dirty Area, and if the +reference count is not one, they first create a copy of the BufferData and +then complete their state-changing operation. + +@subsection Tags implementation +Tags are implemented by a single pointer which points to the start of a +linked list ofTagData data structures. Each TagData structure points +to the next TagData in the list (its next pointer contains zero to +indicate the end of the linked list). Each TagData contains an integer +unique id which identifies the type of the tag stored in the TagData. +@verbatim +struct TagData { + struct TagData *m_next; + uint32_t m_id; + uint32_t m_count; + uint8_t m_data[Tags::SIZE]; +}; +class Tags { + struct TagData *m_next; +}; +@end verbatim + +Adding a tag is a matter of inserting a new TagData at the head of +the linked list. Looking at a tag requires you to find the relevant +TagData in the linked list and copy its data into the user data +structure. Removing a tag and updating the content of a tag +requires a deep copy of the linked list before performing this operation. +On the other hand, copying a Packet and its tags is a matter of +copying the TagData head pointer and incrementing its reference count. + +Tags are found by the unique mapping betweent the Tag type and +its underlying id. This is why at most one instance of any Tag +can be stored in a packet. The mapping between Tag type and +underlying id is performed by a registration as follows: +@verbatim +/* A sample Tag implementation + */ +struct MyTag { + uint16_t m_streamId; +}; +@end verbatim + +@emph{add description of TagRegistration for printing} + +@subsection Memory management + +@emph{Describe free list.} + +@emph{Describe dataless vs. data-full packets.} + +@subsection Copy-on-write semantics +The current implementation of the byte buffers and tag list is based +on COW (Copy On Write). An introduction to COW can be found in Scott +Meyer's "More Effective C++", items 17 and 29). This design feature +and aspects of the public interface borrows from the packet design +of the Georgia Tech Network Simulator. +This implementation of COW uses a customized reference counting +smart pointer class. + +What COW means is that +copying packets without modifying them is very cheap (in terms of CPU +and memory usage) and modifying them can be also very cheap. What is +key for proper COW implementations is being +able to detect when a given modification of the state of a packet triggers +a full copy of the data prior to the modification: COW systems need +to detect when an operation is ``dirty'' and must therefore invoke +a true copy. + +Dirty operations: +@itemize @bullet +@item Packet::RemoveTag() +@item Packet::Add() +@item both versions of ns3::Packet::AddAtEnd() +@end itemize + +Non-dirty operations: +@itemize @bullet +@item Packet::AddTag() +@item Packet::RemoveAllTags() +@item Packet::PeekTag() +@item Packet::Peek() +@item Packet::Remove() +@item Packet::CreateFragment() +@item Packet::RemoveAtStart() +@item Packet::RemoveAtEnd() +@end itemize + +Dirty operations will always be slower than non-dirty operations, +sometimes by several orders of magnitude. However, even the +dirty operations have been optimized for common use-cases which +means that most of the time, these operations will not trigger +data copies and will thus be still very fast. + diff --git a/doc/manual/routing.texi b/doc/manual/routing.texi new file mode 100644 index 000000000..d8250ee24 --- /dev/null +++ b/doc/manual/routing.texi @@ -0,0 +1,373 @@ +@node ns-3 routing overview +@chapter ns-3 routing overview + +This chapter describes the overall design of routing in the +@code{src/internet-stack} +module, and some details about the routing approachs currently +implemented. + +@node Routing-Overview +@section Overview + +We intend to support traditional routing approaches and protocols, +ports of open source routing implementations, and facilitate research +into unorthodox routing techniques. +For simulations that are not primarily focused on routing and that +simply want correct routing tables to occur somehow, we have an +global centralized routing capability. A singleton object +(GlobalRouteManager) be instantiated, builds a network map, and +populates a forwarding table on each node at time t=0 in the +simulation. Simulation script writers can use the same node +API to manually enter routes as well. + +@node Support for multiple routing protocols +@section Support for multiple routing protocols + +Typically, multiple routing protocols are supported in user space and +coordinate to write a single forwarding table in the kernel. Presently +in @command{ns-3}, the implementation instead allows for multiple routing +protocols to build/keep their own routing state, and the IPv4 implementation +will query each one of these routing protocols (in some order determined +by the simulation author) until a route is found. + +We chose this approach because it may better +faciliate the integration of disparate routing approaches that may +be difficult to coordinate the writing to a single table, approaches +where more information than destination IP address (e.g., source +routing) is used to determine the next hop, and on-demand +routing approaches where packets must be cached. + +There are presently two routing protocols defined: +@itemize @bullet +@item class Ipv4StaticRouting (covering both unicast and multicast) +@item Optimized Link State Routing (a MANET protocol defined in +@uref{http://www.ietf.org/rfc/rfc3626.txt,,RFC 3626}) +@end itemize +but first we describe how multiple routing protocols are supported. + +@subsection class Ipv4RoutingProtocol + +@code{class Ipv4RoutingProtocol} derives from ns-3 Object which means +that it supports interface aggregation and reference counting. Routing +protocols should inherit from this class, defined in src/node/ipv4.cc. + +The main function that must be supported by these protocols is called +@code{RequestRoute}. +@verbatim + * This method is called whenever a node's IPv4 forwarding engine + * needs to lookup a route for a given packet and IP header. + * + * The routing protocol implementation may determine immediately it + * should not be handling this particular the route request. For + * instance, a routing protocol may decline to search for routes for + * certain classes of addresses, like link-local. In this case, + * RequestRoute() should return false and the routeReply callback + * must not be invoked. + * + * If the routing protocol implementations assumes it can provide + * the requested route, then it should return true, and the + * routeReply callback must be invoked, either immediately before + * returning true (synchronously), or in the future (asynchronous). + * The routing protocol may use any information available in the IP + * header and packet as routing key, although most routing protocols + * use only the destination address (as given by + * ipHeader.GetDestination ()). The routing protocol is also + * allowed to add a new header to the packet, which will appear + * immediately after the IP header, although most routing do not + * insert any extra header. + */ + virtual bool RequestRoute (uint32_t ifIndex, + const Ipv4Header &ipHeader, + Ptr packet, + RouteReplyCallback routeReply) = 0; +@end verbatim + +This class also provides a typedef (used above) for a special Callback +that will pass to the callback function the Ipv4Route that is found (see the +Doxygen documentation): +@verbatim + typedef Callback, const Ipv4Header&> RouteReplyCallback; +@end verbatim + +@subsection Ipv4::AddRoutingProtocol + +Class Ipv4 provides a pure virtual function declaration for the +method that allows one to add a routing protocol: +@verbatim + void AddRoutingProtocol (Ptr routingProtocol, + int16_t priority); +@end verbatim +This method is implemented by class Ipv4L3Protocol in the internet-stack +module. + +The priority variable above governs the priority in which the routing +protocols are inserted. Notice that it is a signed int. +When the class Ipv4L3Protocol is instantiated, a single routing +protocol (Ipv4StaticRouting, introduced below) is added at priority +zero. Internally, a list of Ipv4RoutingProtocols is stored, and +and the routing protocols are each consulted in decreasing order +of priority to see whether a match is found. Therefore, if you +want your Ipv4RoutingProtocol to have priority lower than the static +routing, insert it with priority less than 0; e.g.: +@verbatim + m_ipv4->AddRoutingProtocol (m_routingTable, -10); +@end verbatim + +@subsection Ipv4L3Protocol::Lookup + +The main function for obtaining a route is shown below: +@verbatim +Ipv4L3Protocol::Lookup ( + uint32_t ifIndex, + Ipv4Header const &ipHeader, + Ptr packet, + Ipv4RoutingProtocol::RouteReplyCallback routeReply) +@end verbatim + +This function will search the list of routing protocols, in priority order, +until a route is found. It will then invoke the RouteReplyCallback +and no further routing protocols will be searched. If the caller does +not want to constrain the possible interface, it can be wildcarded +as such: +@verbatim + Lookup (Ipv4RoutingProtocol::IF_INDEX_ANY, ipHeader, packet, routeReply); +@end verbatim + +@node Roadmap and Future work +@section Roadmap and Future work + +Some goals for future support are: + +Users should be able to trace (either debug print, or redirect to a trace +file) the routing table in a format such as used in an +Unix implementation: +@verbatim +# netstat -nr (or # route -n) +Kernel IP routing table +Destination Gateway Genmask Flags MSS Window irtt Iface +127.0.0.1 * 255.255.255.255 UH 0 0 0 lo +172.16.1.0 * 255.255.255.0 U 0 0 0 eth0 +172.16.2.0 172.16.1.1 255.255.255.0 UG 0 0 0 eth0 + +# ip route show +192.168.99.0/24 dev eth0 scope link +127.0.0.0/8 dev lo scope link +default via 192.168.99.254 dev eth0 +@end verbatim + +Global computation of multicast routing should be implemented as well. +This would ignore group membership and ensure that a copy of every +sourced multicast datagram would be delivered to each node. +This might be implemented as an RPF mechanism that functioned on-demand +by querying the forwarding table, +and perhaps optimized by a small multicast forwarding cache. It is +a bit trickier to implement over wireless links where the input +interface is the same as the output interface; other aspects of the +packet must be considered and the forwarding logic slightly changed +to allow for forwarding out the same interface. + +In the future, work on bringing XORP or quagga routing to ns, but it will +take several months to port and enable. + +There are presently no roadmap plans for IPv6. + +@node Static routing +@section Static routing + +The internet-stack module provides one routing protocol (Ipv4StaticRouting) +by default. This routing protocol allows one to add unicast or multicast +static routes to a node. + +@node Unicast routing +@section Unicast routing + +The unicast static routing API may be accessed via the functions +@verbatim +void Ipv4::AddHostRouteTo () +void Ipv4::AddNetworkRouteTo () +void Ipv4::SetDefaultRoute () +uint32_t Ipv4::GetNRoutes () +Ipv4Route Ipv4::GetRoute () +@end verbatim + +@uref{http://www.nsnam.org/doxygen/index.html,,Doxygen} documentation +provides full documentation of these methods. These methods are forwarding +functions to the actual implementation in Ipv4StaticRouting, when using +the internet-stack module. + +@node Multicast routing +@section Multicast routing + +The following function is used to add a static multicast route +to a node: +@verbatim +void +Ipv4StaticRouting::AddMulticastRoute (Ipv4Address origin, + Ipv4Address group, + uint32_t inputInterface, + std::vector outputInterfaces); +@end verbatim + +A multicast route must specify an origin IP address, a multicast group and +an input network interface index as conditions and provide a vector of +output network interface indices over which packets matching the conditions +are sent. + +Typically there are two main types of multicast routes: routes of the +first kind are used during forwarding. All of the conditions must be +exlicitly provided. The second kind of routes are used to get packets off +of a local node. The difference is in the input interface. Routes for +forwarding will always have an explicit input interface specified. Routes +off of a node will always set the input interface to a wildcard specified +by the index Ipv4RoutingProtocol::IF\_INDEX\_ANY. + +For routes off of a local node wildcards may be used in the origin and +multicast group addresses. The wildcard used for Ipv4Adresses is that +address returned by Ipv4Address::GetAny () -- typically "0.0.0.0". Usage +of a wildcard allows one to specify default behavior to varying degrees. + +For example, making the origin address a wildcard, but leaving the +multicast group specific allows one (in the case of a node with multiple +interfaces) to create different routes using different output interfaces +for each multicast group. + +If the origin and multicast addresses are made wildcards, you have created +essentially a default multicast address that can forward to multiple +interfaces. Compare this to the actual default multicast address that is +limited to specifying a single output interface for compatibility with +existing functionality in other systems. + +Another command sets the default multicast route: +@verbatim +void +Ipv4StaticRouting::SetDefaultMulticastRoute (uint32_t outputInterface); +@end verbatim + +This is the multicast equivalent of the unicast version SetDefaultRoute. +We tell the routing system what to do in the case where a specific route +to a destination multicast group is not found. The system forwards +packets out the specified interface in the hope that "something out there" +knows better how to route the packet. This method is only used in +initially sending packets off of a host. The default multicast route is +not consulted during forwarding -- exact routes must be specified using +AddMulticastRoute for that case. + +Since we're basically sending packets to some entity we think may know +better what to do, we don't pay attention to "subtleties" like origin +address, nor do we worry about forwarding out multiple interfaces. If the +default multicast route is set, it is returned as the selected route from +LookupStatic irrespective of origin or multicast group if another specific +route is not found. + +Finally, a number of additional functions are provided to fetch and +remove multicast routes: +@verbatim + uint32_t GetNMulticastRoutes (void) const; + + Ipv4MulticastRoute *GetMulticastRoute (uint32_t i) const; + + Ipv4MulticastRoute *GetDefaultMulticastRoute (void) const; + + bool RemoveMulticastRoute (Ipv4Address origin, + Ipv4Address group, + uint32_t inputInterface); + + void RemoveMulticastRoute (uint32_t index); +@end verbatim + +@node Global centralized routing +@section Global centralized routing + +Presently, global centralized IPv4 @emph{unicast} routing over both +point-to-point and shared (CSMA) links is supported. +The global centralized routing will be modified in the future to +reduce computations once profiling finds the performance bottlenecks. + +@node Global Unicast Routing API +@section Global Unicast Routing API + +The public API is very minimal. User scripts include the following: +@verbatim +#include "ns3/global-route-manager.h" +@end verbatim + +After IP addresses are configured, the following function call will +cause all of the nodes that have an Ipv4 interface to receive +forwarding tables entered automatically by the GlobalRouteManager: +@verbatim + GlobalRouteManager::PopulateRoutingTables (); +@end verbatim + +@emph{Note:} A reminder that the wifi NetDevice is not yet supported +(only CSMA and PointToPoint). + +@node Global Routing Implementation +@section Global Routing Implementation + +A singleton object (GlobalRouteManager) is responsible for populating +the static routes on each node, using the public Ipv4 API of that node. +It queries each node in the topology for a "globalRouter" interface. +If found, it uses the API of that interface to obtain a "link state +advertisement (LSA)" for the router. Link State Advertisements +are used in OSPF routing, and we follow their formatting. + +The GlobalRouteManager populates a link state database with LSAs +gathered from the entire topology. Then, for each router in the topology, +the GlobalRouteManager executes the OSPF shortest path first (SPF) +computation on the database, and populates the routing tables on each +node. + +The quagga (http://www.quagga.net) OSPF implementation was used as the +basis for the routing computation logic. +One benefit of following an existing OSPF SPF implementation is that +OSPF already has defined link state advertisements for all common +types of network links: +@itemize @bullet +@item point-to-point (serial links) +@item point-to-multipoint (Frame Relay, ad hoc wireless) +@item non-broadcast multiple access (ATM) +@item broadcast (Ethernet) +@end itemize +Therefore, we think that enabling these other link types will be more +straightforward now that the underlying OSPF SPF framework is in place. + +Presently, we can handle IPv4 point-to-point, numbered links, as well +as shared broadcast (CSMA) links, and we do not do equal-cost multipath. + +The GlobalRouteManager first walks the list of nodes and aggregates +a GlobalRouter interface to each one as follows: +@verbatim + typedef std::vector < Ptr >::iterator Iterator; + for (Iterator i = NodeList::Begin (); i != NodeList::End (); i++) + { + Ptr node = *i; + Ptr globalRouter = CreateObject (node); + node->AggregateObject (globalRouter); + } +@end verbatim + +This interface is later queried and used to generate a Link State +Advertisement for each router, and this link state database is +fed into the OSPF shortest path computation logic. The Ipv4 API +is finally used to populate the routes themselves. + +@node Optimized Link State Routing (OLSR) +@section Optimized Link State Routing (OLSR) + +This is the first dynamic routing protocol for @command{ns-3}. The implementation +is found in the src/routing/olsr directory, and an example script is in +examples/simple-point-to-point-olsr.cc. + +The following commands will enable OLSR in a simulation. + +@verbatim + olsr::EnableAllNodes (); // Start OLSR on all nodes + olsr::EnableNodes(InputIterator begin, InputIterator end); // Start on + // a list of nodes + olsr::EnableNode (Ptr node); // Start OLSR on "node" only +@end verbatim + +Once instantiated, the agent can be started with the Start() command, +and the OLSR "main interface" can be set with the SetMainInterface() +command. A number of protocol constants are defined in olsr-agent-impl.cc. + diff --git a/doc/manual/sockets.texi b/doc/manual/sockets.texi new file mode 100644 index 000000000..0c17cde02 --- /dev/null +++ b/doc/manual/sockets.texi @@ -0,0 +1,243 @@ +@node Sockets APIs +@chapter Sockets APIs + +The @uref{http://en.wikipedia.org/wiki/Berkeley_sockets,,sockets API} +is a long-standing API used by user-space applications to access +network services in the kernel. A ``socket'' is an abstraction, like +a Unix file handle, that allows applications to connect to other +Internet hosts and exchange reliable byte streams and unreliable +datagrams, among other services. + +ns-3 provides two types of sockets APIs, and it is important to +understand the differences between them. The first is a @emph{native} +ns-3 API, while the second uses the services of the native API to +provide a @uref{http://en.wikipedia.org/wiki/POSIX,,POSIX-like} +API as part of an overall application process. Both APIs strive +to be close to the typical sockets API that application writers +on Unix systems are accustomed to, but the POSIX variant is much +closer to a real system's sockets API. + +@section ns-3 sockets API + +The native sockets API for ns-3 provides an interface to various +types of transport protocols (TCP, UDP) as well as to packet sockets +and, in the future, Netlink-like sockets. However, users are cautioned +to understand that the semantics are @strong{not} the exact same as +one finds in a real system (for an API which is very much aligned +to real systems, see the next section). + +@code{class ns3::Socket} is defined in @code{src/node/socket.cc,h}. +Readers will note that many public member functions are aligned +with real sockets function calls, and all other things being equal, +we have tried to align with a Posix sockets API. However, note that: + +@itemize @bullet +@item ns-3 applications handle a smart pointer to a Socket object, not +a file descriptor; +@item there is no notion of synchronous API or a ``blocking'' API; +in fact, the model for interaction between application and socket is +one of asynchronous I/O, which is not typically found in real systems +(more on this below); +@item the C-style socket address structures are not used; +@item the API is not a complete sockets API, such as supporting +all socket options or all function variants; +@item many calls use @code{ns3::Packet} class to transfer data +between application and socket. This may seem a little funny to +people to pass ``Packets'' across a stream socket API, but think +of these packets as just fancy byte buffers at this level (more +on this also below). +@end itemize + +@subsection Basic operation and calls + +@float Figure,fig:sockets-overview +@caption{Implementation overview of native sockets API} +@image{figures/sockets-overview, 10cm} +@end float + +@subsubsection Creating sockets + +An application that wants to use sockets must first create one. +On real systems, this is accomplished by calling socket(): +@verbatim + int + socket(int domain, int type, int protocol); +@end verbatim +which creates a socket in the system and returns an integer descriptor. + +In ns-3, we have no equivalent of a system call at the lower layers, +so we adopt the following model. There are certain @emph{factory} +objects that can create sockets. Each factory is capable of creating +one type of socket, and if sockets of a particular type are able to +be created on a given node, then a factory that can create such sockets +must be aggregated to the Node. +@verbatim + static Ptr CreateSocket (Ptr node, TypeId tid); +@end verbatim +Examples of TypeIds to pass to this method are @code{TcpSocketFactory}, +@code{PacketSocketFactory}, and @code{UdpSocketFactory}. + +This method returns a smart pointer to a Socket object. Here is an +example: +@verbatim + Ptr n0; + // Do some stuff to build up the Node's internet stack + Ptr localSocket = Socket::CreateSocket (n0, TcpSocketFactory::GetTypeId ()); +@end verbatim + +In some ns-3 code, sockets will not be explicitly created by user's +main programs, if an ns-3 application does it. For instance, for +@code{class ns3::OnOffApplication}, the function @code{StartApplication()} +performs the socket creation, and the application holds the socket +pointer. + +@subsubsection Using sockets + +Below is a typical sequence of socket calls for a TCP client in a +real implementation: +@itemize @bullet +@item @code{sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);} +@item @code{bind(sock, ...);} +@item @code{connect(sock, ...);} +@item @code{send(sock, ...);} +@item @code{recv(sock, ...);} +@item @code{close(sock);} +@end itemize + +There are analogs to all of these calls in ns-3, but we will focus on +two aspects here. First, most usage of sockets in real systems +requires a way to manage I/O between the application and kernel. +These models include @emph{blocking sockets}, @emph{signal-based I/O}, +and @emph{non-blocking sockets} with polling. In ns-3, we make use +of the callback mechanisms to support a fourth mode, which is +analogous to POSIX @emph{asynchronous I/O}. + +In this model, on the sending side, if the @code{send()} call were to +fail because of insufficient buffers, the application suspends the +sending of more data until a function registered at the +@code{SetSendCallback()} callback is invoked. An application can +also ask the socket how much space is available by calling +@code{GetTxAvailable ()}. A typical sequence of events for +sending data (ignoring connection setup) might be: + +@itemize @bullet +@item @code{SetSendCallback (MakeCallback(&HandleSendCallback));} +@item @code{Send ();} +@item @code{Send ();} +@item ... +@item @code{// Send fails because buffer is full} +@item (wait until HandleSendCallback() is called) +@item (HandleSendCallback() is called by socket, since space now available) +@item @code{Send (); // Start sending again} +@end itemize + +Similarly, on the receive side, the socket user does not block on +a call to @code{recv()}. Instead, the application sets a callback +with @code{SetRecvCallback ()} in which the socket will notify the +application when (and how much) there is data to be read, and +the application then calls @code{Recv()} to read the data until +no more can be read. + +@subsection Packet vs. buffer variants + +There are two basic variants of @code{Send()} and @code{Recv()} supported: +@verbatim + virtual int Send (Ptr p) = 0; + int Send (const uint8_t* buf, uint32_t size); + + Ptr Recv (void); + int Recv (uint8_t* buf, uint32_t size); +@end verbatim + +The non-Packet variants are left for legacy API reasons. When calling +the raw buffer variant of @code{Send()}, the buffer is immediately +written into a Packet and the @code{Send (Ptr p)} is invoked. + +Users may find it semantically odd to pass a Packet to a stream socket +such as TCP. However, do not let the name bother you; think of +@code{ns3::Packet} to be a fancy byte buffer. There are a few reasons why +the Packet variants are more likely to be preferred in ns-3: + +@itemize @bullet +@item Users can use the Tags facility of packets to, for example, encode +a flow ID or other helper data. +@item Users can exploit the copy-on-write implementation to avoid +memory copies (on the receive side, the conversion back to a +@code{uint8_t* buf} may sometimes incur an additional copy). +@item Use of Packet is more aligned with the rest of the ns-3 API +@end itemize + +@subsection Sending dummy data + +Sometimes, users want the simulator to just pretend that there is an +actual data payload in the packet (e.g. to calculate transmission delay) +but do not want to actually produce or consume the data. This is +straightforward to support in ns-3; have applications call +@code{Create (size);} instead of @code{Create (buffer, size);}. +Similarly, passing in a zero to the pointer argument in the raw buffer +variants has the same effect. Note that, if some subsequent code tries +to read the Packet data buffer, the fake buffer will be converted to +a real (zero'ed) buffer on the spot, and the efficiency will be lost there. + +@subsection Socket options + +@emph{to be completed} + +@subsection Socket errno + +@emph{to be completed} + +@subsection Example programs + +@emph{to be completed} + +@section POSIX-like sockets API + +@emph{this capability is under development and is scheduled for +inclusion in August 2008 timeframe; see the repository +http://code.nsnam.org/mathieu/ns-3-simu for details} + +The below is excerpted from Mathieu's post to ns-developers list +on April 4, 2008. + +"To summarize, the goal is that the full posix/socket API is defined in +src/process/simu.h: each posix type and function is re-defined there +with a simu_ or SIMU_ prefix to avoid ugly name clashes and collisions +(feel free to come up with a better prefix). + +Each process is created with a call to ProcessManager::Create and is +attached to that ProcessManager instance. So, if the ProcessManager +(which is aggregated to a Node in src/helper/process-helper.cc) is +killed when the simulation ends, the system will automatically reclaim +all the resources of each process associated to each manager. The same +happens when an application "exits" from its main function. + +The example application defines two posix "processes": the function +ClientProgram creates a udp socket on the localhost port 2000 and the +function ServerProgram creates a udp socket on the localhost port 2000. +The code does not work right now because I did not get the details of +simu_read right yet but, I do plan to make this work at some point. + +I really think that this approach is worthwhile for many reasons, a few +of which are outlined below: +@itemize @bullet +@item makes porting real world application code _much_ easier + +@item makes write applications for new users much easier because they can +read the bsd socket api reference and documentation and write code +directly. + +@item can be used to write applications which work in both simulation and +in the real world at the same time. To do this, all you have to do is +write your application to use the simu_ API, and, then, you can chose at +compile-time which implementation of that API you want to use: you can +pick one implementation which forwards all calls to the system BSD +socket API or another one which forwards all calls to the attached +ProcessManager. Arguably, I did not implement the version which forwards +to system BSD sockets but, that should be pretty trivial. +@end itemize + +So, anyway, comments about the overall API would be welcome. Students +interested in the gsoc project for real-world code integration should +consider looking at this also." + diff --git a/doc/manual/statistics.texi b/doc/manual/statistics.texi new file mode 100644 index 000000000..094e91a4b --- /dev/null +++ b/doc/manual/statistics.texi @@ -0,0 +1,9 @@ +@node Statistics +@chapter Statistics +@anchor{chap:Statistics} + +ns-3 does not presently have support for statistics (automatically generated +statistical output). This is planned +for development later in 2008. If you are interested in contributing, +please see @uref{http://www.nsnam.org/wiki/index.php/Suggested_Projects,,our suggested projects page} or contact the ns-developers +list. diff --git a/doc/manual/troubleshoot.texi b/doc/manual/troubleshoot.texi new file mode 100644 index 000000000..6ac901d15 --- /dev/null +++ b/doc/manual/troubleshoot.texi @@ -0,0 +1,82 @@ +@node Troubleshooting +@chapter Troubleshooting + +This chapter posts some information about possibly common errors in building +or running ns-3 programs. + +Please note that the wiki (@uref{http://www.nsnam.org/wiki/index.php/Troubleshooting}) may have contributed items. + +@node Build errors +@section Build errors + +@node Run-time errors +@section Run-time errors + +Sometimes, errors can occur with a program after a successful build. These +are run-time errors, and can commonly occur when memory is corrupted or +pointer values are unexpectedly null. + +Here is an example of what might occur: + +@verbatim +ns-old:~/ns-3-nsc$ ./waf --run tcp-point-to-point +Entering directory `/home/tomh/ns-3-nsc/build' +Compilation finished successfully +Command ['/home/tomh/ns-3-nsc/build/debug/examples/tcp-point-to-point'] exited with code -11 +@end verbatim + +The error message says that the program terminated unsuccessfully, but it is +not clear from this information what might be wrong. To examine more +closely, try running it under the @uref{http://sources.redhat.com/gdb/,,gdb debugger}: + +@verbatim +ns-old:~/ns-3-nsc$ ./waf --run tcp-point-to-point --command-template="gdb %s" +Entering directory `/home/tomh/ns-3-nsc/build' +Compilation finished successfully +GNU gdb Red Hat Linux (6.3.0.0-1.134.fc5rh) +Copyright 2004 Free Software Foundation, Inc. +GDB is free software, covered by the GNU General Public License, and you are +welcome to change it and/or distribute copies of it under certain conditions. +Type "show copying" to see the conditions. +There is absolutely no warranty for GDB. Type "show warranty" for details. +This GDB was configured as "i386-redhat-linux-gnu"...Using host libthread_db library "/lib/libthread_db.so.1". + +(gdb) run +Starting program: /home/tomh/ns-3-nsc/build/debug/examples/tcp-point-to-point +Reading symbols from shared object read from target memory...done. +Loaded system supplied DSO at 0xf5c000 + +Program received signal SIGSEGV, Segmentation fault. +0x0804aa12 in main (argc=1, argv=0xbfdfefa4) + at ../examples/tcp-point-to-point.cc:136 +136 Ptr localSocket = socketFactory->CreateSocket (); +(gdb) p localSocket +$1 = {m_ptr = 0x3c5d65} +(gdb) p socketFactory +$2 = {m_ptr = 0x0} +(gdb) quit +The program is running. Exit anyway? (y or n) y +@end verbatim + +Note first the way the program was invoked-- pass the command to run as +an argument to the command template "gdb %s". + +This tells us that there was an attempt to dereference a null pointer +socketFactory. + +Let's look around line 136 of tcp-point-to-point, as gdb suggests: +@verbatim + Ptr socketFactory = n2->GetObject (Tcp::iid); + Ptr localSocket = socketFactory->CreateSocket (); + localSocket->Bind (); +@end verbatim + +The culprit here is that the return value of GetObject is not being +checked and may be null. + +Sometimes you may need to use the @uref{http://valgrind.org,,valgrind memory +checker} for more subtle errors. Again, you invoke the use of valgrind +similarly: +@verbatim +ns-old:~/ns-3-nsc$ ./waf --run tcp-point-to-point --command-template="valgrind %s" +@end verbatim From 4a73b2abd0ffadfb8a80950e6620554daa1b759e Mon Sep 17 00:00:00 2001 From: "Gustavo J. A. M. Carneiro" Date: Mon, 16 Jun 2008 14:17:27 +0100 Subject: [PATCH 012/495] [Bug 221] need a scratch directory --- scratch/multiple-sources/simple-main.cc | 9 +++ scratch/multiple-sources/simple-simulation.cc | 67 +++++++++++++++++ scratch/simple.cc | 74 +++++++++++++++++++ wscript | 15 ++++ 4 files changed, 165 insertions(+) create mode 100644 scratch/multiple-sources/simple-main.cc create mode 100644 scratch/multiple-sources/simple-simulation.cc create mode 100644 scratch/simple.cc diff --git a/scratch/multiple-sources/simple-main.cc b/scratch/multiple-sources/simple-main.cc new file mode 100644 index 000000000..31488d2d1 --- /dev/null +++ b/scratch/multiple-sources/simple-main.cc @@ -0,0 +1,9 @@ + +void RunSimulation (void); + +int main (int argc, char *argv[]) +{ + RunSimulation (); + + return 0; +} diff --git a/scratch/multiple-sources/simple-simulation.cc b/scratch/multiple-sources/simple-simulation.cc new file mode 100644 index 000000000..8650842e2 --- /dev/null +++ b/scratch/multiple-sources/simple-simulation.cc @@ -0,0 +1,67 @@ +#include + +#include "ns3/core-module.h" +#include "ns3/helper-module.h" +#include "ns3/node-module.h" +#include "ns3/simulator-module.h" + +using namespace ns3; + +static void +GenerateTraffic (Ptr socket, uint32_t size) +{ + std::cout << "at=" << Simulator::Now ().GetSeconds () << "s, tx bytes=" << size << std::endl; + socket->Send (Create (size)); + if (size > 0) + { + Simulator::Schedule (Seconds (0.5), &GenerateTraffic, socket, size - 50); + } + else + { + socket->Close (); + } +} + +static void +SocketPrinter (Ptr socket) +{ + Ptr packet; + while (packet = socket->Recv ()) + { + std::cout << "at=" << Simulator::Now ().GetSeconds () << "s, rx bytes=" << packet->GetSize () << std::endl; + } +} + +static void +PrintTraffic (Ptr socket) +{ + socket->SetRecvCallback (MakeCallback (&SocketPrinter)); +} + +void +RunSimulation (void) +{ + NodeContainer c; + c.Create (1); + + InternetStackHelper internet; + internet.Install (c); + + + TypeId tid = TypeId::LookupByName ("ns3::UdpSocketFactory"); + Ptr sink = Socket::CreateSocket (c.Get (0), tid); + InetSocketAddress local = InetSocketAddress (Ipv4Address::GetAny (), 80); + sink->Bind (local); + + Ptr source = Socket::CreateSocket (c.Get (0), tid); + InetSocketAddress remote = InetSocketAddress (Ipv4Address::GetLoopback (), 80); + source->Connect (remote); + + GenerateTraffic (source, 500); + PrintTraffic (sink); + + + Simulator::Run (); + + Simulator::Destroy (); +} diff --git a/scratch/simple.cc b/scratch/simple.cc new file mode 100644 index 000000000..92c6e5c36 --- /dev/null +++ b/scratch/simple.cc @@ -0,0 +1,74 @@ +#include + +#include "ns3/core-module.h" +#include "ns3/helper-module.h" +#include "ns3/node-module.h" +#include "ns3/simulator-module.h" + +using namespace ns3; + +static void +GenerateTraffic (Ptr socket, uint32_t size) +{ + std::cout << "at=" << Simulator::Now ().GetSeconds () << "s, tx bytes=" << size << std::endl; + socket->Send (Create (size)); + if (size > 0) + { + Simulator::Schedule (Seconds (0.5), &GenerateTraffic, socket, size - 50); + } + else + { + socket->Close (); + } +} + +static void +SocketPrinter (Ptr socket) +{ + Ptr packet; + while (packet = socket->Recv ()) + { + std::cout << "at=" << Simulator::Now ().GetSeconds () << "s, rx bytes=" << packet->GetSize () << std::endl; + } +} + +static void +PrintTraffic (Ptr socket) +{ + socket->SetRecvCallback (MakeCallback (&SocketPrinter)); +} + +void +RunSimulation (void) +{ + NodeContainer c; + c.Create (1); + + InternetStackHelper internet; + internet.Install (c); + + + TypeId tid = TypeId::LookupByName ("ns3::UdpSocketFactory"); + Ptr sink = Socket::CreateSocket (c.Get (0), tid); + InetSocketAddress local = InetSocketAddress (Ipv4Address::GetAny (), 80); + sink->Bind (local); + + Ptr source = Socket::CreateSocket (c.Get (0), tid); + InetSocketAddress remote = InetSocketAddress (Ipv4Address::GetLoopback (), 80); + source->Connect (remote); + + GenerateTraffic (source, 500); + PrintTraffic (sink); + + + Simulator::Run (); + + Simulator::Destroy (); +} + +int main (int argc, char *argv[]) +{ + RunSimulation (); + + return 0; +} diff --git a/wscript b/wscript index 745fe75e6..150868743 100644 --- a/wscript +++ b/wscript @@ -230,6 +230,19 @@ def create_ns3_program(bld, name, dependencies=('simulator',)): program.ns3_module_dependencies = ['ns3-'+dep for dep in dependencies] return program +def add_scratch_programs(bld): + all_modules = [mod[len("ns3-"):] for mod in bld.env()['NS3_MODULES']] + for filename in os.listdir("scratch"): + if os.path.isdir(os.path.join("scratch", filename)): + obj = bld.create_ns3_program(filename, all_modules) + obj.path = obj.path.find_dir('scratch') + obj.find_sources_in_dirs(filename) + obj.target = os.path.join(filename, filename) + elif filename.endswith(".cc"): + name = filename[:-len(".cc")] + obj = bld.create_ns3_program(name, all_modules) + obj.source = "scratch/%s" % filename + obj.target = "scratch/%s" % name def build(bld): if Params.g_options.no_task_lines: @@ -263,6 +276,8 @@ def build(bld): bld.add_subdirs('src') bld.add_subdirs('samples utils examples tutorial') + add_scratch_programs(bld) + ## if --enabled-modules option was given, we disable building the ## modules that were not enabled, and programs that depend on ## disabled modules. From 1b8812d558a7f5311d0b1d11c3963c708afc35c6 Mon Sep 17 00:00:00 2001 From: Craig Dowell Date: Mon, 16 Jun 2008 16:25:52 -0700 Subject: [PATCH 013/495] Changes for bug 205, unlisted FIN bug --- examples/tcp-large-transfer.cc | 5 +- src/applications/packet-sink/packet-sink.cc | 12 ++--- src/applications/packet-sink/packet-sink.h | 4 +- src/internet-stack/tcp-socket-impl.cc | 4 +- src/internet-stack/udp-socket-impl.cc | 1 - src/node/packet-socket.cc | 1 - src/node/socket.cc | 53 +-------------------- src/node/socket.h | 25 +--------- 8 files changed, 13 insertions(+), 92 deletions(-) diff --git a/examples/tcp-large-transfer.cc b/examples/tcp-large-transfer.cc index f648d50ea..2aab318a7 100644 --- a/examples/tcp-large-transfer.cc +++ b/examples/tcp-large-transfer.cc @@ -87,7 +87,7 @@ int main (int argc, char *argv[]) // Users may find it convenient to turn on explicit debugging // for selected modules; the below lines suggest how to do this // LogComponentEnable("TcpL4Protocol", LOG_LEVEL_ALL); - // LogComponentEnable("TcpSocket", LOG_LEVEL_ALL); + // LogComponentEnable("TcpSocketImpl", LOG_LEVEL_ALL); // LogComponentEnable("PacketSink", LOG_LEVEL_ALL); // LogComponentEnable("TcpLargeTransfer", LOG_LEVEL_ALL); @@ -182,8 +182,7 @@ void StartFlow(Ptr localSocket, uint32_t nBytes, // NS_LOG_LOGIC("Starting flow at time " << Simulator::Now ().GetSeconds ()); localSocket->Connect (InetSocketAddress (servAddress, servPort));//connect localSocket->SetConnectCallback (MakeCallback (&CloseConnection), - Callback > (), - Callback > ()); + Callback > ()); //we want to close as soon as the connection is established //the tcp state machine and outgoing buffer will assure that //all of the data is delivered diff --git a/src/applications/packet-sink/packet-sink.cc b/src/applications/packet-sink/packet-sink.cc index 73dfda731..406078dc7 100644 --- a/src/applications/packet-sink/packet-sink.cc +++ b/src/applications/packet-sink/packet-sink.cc @@ -67,6 +67,10 @@ PacketSink::~PacketSink() void PacketSink::DoDispose (void) { + if (m_socket != 0) + { + m_socket->Close (); + } m_socket = 0; // chain up @@ -88,8 +92,7 @@ void PacketSink::StartApplication() // Called at time specified by Start m_socket->SetRecvCallback (MakeCallback(&PacketSink::HandleRead, this)); m_socket->SetAcceptCallback ( MakeNullCallback, const Address &> (), - MakeNullCallback, const Address&> (), - MakeCallback(&PacketSink::CloseConnection, this) ); + MakeNullCallback, const Address&> ()); } void PacketSink::StopApplication() // Called at time specified by Stop @@ -117,9 +120,4 @@ void PacketSink::HandleRead (Ptr socket) } } -void PacketSink::CloseConnection (Ptr socket) -{ - socket->Close (); -} - } // Namespace ns3 diff --git a/src/applications/packet-sink/packet-sink.h b/src/applications/packet-sink/packet-sink.h index 20781a79e..440af90cd 100644 --- a/src/applications/packet-sink/packet-sink.h +++ b/src/applications/packet-sink/packet-sink.h @@ -80,9 +80,7 @@ private: virtual void StartApplication (void); // Called at time specified by Start virtual void StopApplication (void); // Called at time specified by Stop - virtual void HandleRead (Ptr socket); - - virtual void CloseConnection (Ptr socket); + void HandleRead (Ptr socket); Ptr m_socket; // Associated socket Address m_local; // Local address to bind to diff --git a/src/internet-stack/tcp-socket-impl.cc b/src/internet-stack/tcp-socket-impl.cc index 7cd0d246d..0d97c90ee 100644 --- a/src/internet-stack/tcp-socket-impl.cc +++ b/src/internet-stack/tcp-socket-impl.cc @@ -620,7 +620,6 @@ Actions_t TcpSocketImpl::ProcessEvent (Events_t e) NS_LOG_LOGIC ("TcpSocketImpl " << this << " transition to CLOSED from " << m_state << " event " << e << " closeNot " << m_closeNotified << " action " << stateAction.action); - NotifyCloseCompleted (); m_closeNotified = true; NS_LOG_LOGIC ("TcpSocketImpl " << this << " calling Closed from PE" << " origState " << saveState @@ -854,7 +853,6 @@ bool TcpSocketImpl::ProcessPacketAction (Actions_t a, Ptr p, { NS_LOG_LOGIC ("TCP " << this << " calling AppCloseRequest"); - NotifyCloseRequested(); m_closeRequestNotified = true; } NS_LOG_LOGIC ("TcpSocketImpl " << this @@ -1298,7 +1296,7 @@ void TcpSocketImpl::Retransmit () } if (!m_pendingData) { - if (m_state == FIN_WAIT_1 || m_state == FIN_WAIT_2) + if (m_state == FIN_WAIT_1) { // Must have lost FIN, re-send SendEmptyPacket (TcpHeader::FIN); } diff --git a/src/internet-stack/udp-socket-impl.cc b/src/internet-stack/udp-socket-impl.cc index 5f9872089..003478a37 100644 --- a/src/internet-stack/udp-socket-impl.cc +++ b/src/internet-stack/udp-socket-impl.cc @@ -199,7 +199,6 @@ int UdpSocketImpl::Close(void) { NS_LOG_FUNCTION_NOARGS (); - NotifyCloseCompleted (); return 0; } diff --git a/src/node/packet-socket.cc b/src/node/packet-socket.cc index 4e6bb847c..8d6e8272c 100644 --- a/src/node/packet-socket.cc +++ b/src/node/packet-socket.cc @@ -184,7 +184,6 @@ PacketSocket::Close(void) return -1; } m_state = STATE_CLOSED; - NotifyCloseCompleted (); return 0; } diff --git a/src/node/socket.cc b/src/node/socket.cc index e5409ca0b..52f691c57 100644 --- a/src/node/socket.cc +++ b/src/node/socket.cc @@ -50,35 +50,24 @@ Socket::CreateSocket (Ptr node, TypeId tid) return s; } -void -Socket::SetCloseCallback (Callback > closeCompleted) -{ - NS_LOG_FUNCTION_NOARGS (); - m_closeCompleted = closeCompleted; -} - void Socket::SetConnectCallback ( Callback > connectionSucceeded, - Callback > connectionFailed, - Callback > halfClose) + Callback > connectionFailed) { NS_LOG_FUNCTION_NOARGS (); m_connectionSucceeded = connectionSucceeded; m_connectionFailed = connectionFailed; - m_halfClose = halfClose; } void Socket::SetAcceptCallback ( Callback, const Address &> connectionRequest, - Callback, const Address&> newConnectionCreated, - Callback > closeRequested) + Callback, const Address&> newConnectionCreated) { NS_LOG_FUNCTION_NOARGS (); m_connectionRequest = connectionRequest; m_newConnectionCreated = newConnectionCreated; - m_closeRequested = closeRequested; } bool @@ -110,15 +99,6 @@ Socket::Send (Ptr p) return Send (p, 0); } -void -Socket::NotifyCloseUnblocks (void) -{ - NS_LOG_FUNCTION_NOARGS (); - if (!m_closeUnblocks.IsNull ()) - { - m_closeUnblocks (this); - } -} int Socket::Listen (uint32_t queueLimit) { @@ -199,15 +179,6 @@ Socket::RecvFrom (uint8_t* buf, uint32_t size, uint32_t flags, return p->GetSize (); } -void -Socket::NotifyCloseCompleted (void) -{ - NS_LOG_FUNCTION_NOARGS (); - if (!m_closeCompleted.IsNull ()) - { - m_closeCompleted (this); - } -} void Socket::NotifyConnectionSucceeded (void) @@ -229,16 +200,6 @@ Socket::NotifyConnectionFailed (void) } } -void -Socket::NotifyHalfClose (void) -{ - NS_LOG_FUNCTION_NOARGS (); - if (!m_halfClose.IsNull ()) - { - m_halfClose (this); - } -} - bool Socket::NotifyConnectionRequest (const Address &from) { @@ -267,16 +228,6 @@ Socket::NotifyNewConnectionCreated (Ptr socket, const Address &from) } } -void -Socket::NotifyCloseRequested (void) -{ - NS_LOG_FUNCTION_NOARGS (); - if (!m_closeRequested.IsNull ()) - { - m_closeRequested (this); - } -} - void Socket::NotifyDataSent (uint32_t size) { diff --git a/src/node/socket.h b/src/node/socket.h index a15ad0061..d90ce26bf 100644 --- a/src/node/socket.h +++ b/src/node/socket.h @@ -102,12 +102,6 @@ public: * \returns the node this socket is associated with. */ virtual Ptr GetNode (void) const = 0; - - /** - * \param closeCompleted Callback invoked when the close operation is - * completed. - */ - void SetCloseCallback (Callback > closeCompleted); /** * \param connectionSucceeded this callback is invoked when the * connection request initiated by the user is successfully @@ -117,13 +111,9 @@ public: * connection request initiated by the user is unsuccessfully * completed. The callback is passed back a pointer to the * same socket object. - * \param halfClose XXX When exactly is this callback invoked? If - * it invoked when the other side closes the connection ? - * Or when I call Close ? */ void SetConnectCallback (Callback > connectionSucceeded, - Callback > connectionFailed, - Callback > halfClose); + Callback > connectionFailed); /** * \brief Accept connection requests from remote hosts * \param connectionRequest Callback for connection request from peer. @@ -140,14 +130,11 @@ public: * back to the user through this callback. This user callback is * passed a pointer to the new socket, and the ip address and * port number of the connection originator. - * \param closeRequested Callback for connection close request from peer. - * XXX: when is this callback invoked ? */ void SetAcceptCallback (Callback, const Address &> connectionRequest, Callback, - const Address&> newConnectionCreated, - Callback > closeRequested); + const Address&> newConnectionCreated); /** * \brief Notify application when a packet has been sent from transport * protocol (non-standard socket call) @@ -509,24 +496,16 @@ public: Address &fromAddress); protected: - void NotifyCloseUnblocks (void); - void NotifyCloseCompleted (void); void NotifyConnectionSucceeded (void); void NotifyConnectionFailed (void); - void NotifyHalfClose (void); bool NotifyConnectionRequest (const Address &from); void NotifyNewConnectionCreated (Ptr socket, const Address &from); - void NotifyCloseRequested (void); void NotifyDataSent (uint32_t size); void NotifySend (uint32_t spaceAvailable); void NotifyDataRecv (void); - Callback > m_closeUnblocks; - Callback > m_closeCompleted; Callback > m_connectionSucceeded; Callback > m_connectionFailed; - Callback > m_halfClose; - Callback > m_closeRequested; Callback, const Address &> m_connectionRequest; Callback, const Address&> m_newConnectionCreated; Callback, uint32_t> m_dataSent; From 452bb57c9fd1bb77aa111fe572526140c42509ec Mon Sep 17 00:00:00 2001 From: Craig Dowell Date: Tue, 17 Jun 2008 10:36:56 -0700 Subject: [PATCH 014/495] Added tag release candidate ns-3.1-RC1 for changeset 8869a79a391f --- .hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/.hgtags b/.hgtags index 4d11c256c..fff235f85 100644 --- a/.hgtags +++ b/.hgtags @@ -13,3 +13,4 @@ b5bf2588cde2f1273b1095cc5c83a0c272e55370 release ns-3.0.10 ee5e1da76ecc52337f097cd90ebb50a3d49ec541 release-3.0.11 b17f2928291eec5bf5b1c59a4a5fd583f704ac40 release ns-3.0.12 79dba133b5f8a2d6f6f678a22e8519bc155e6a4e release ns-3.0.13 +8869a79a391f49d0c787f0558cc9329b4e7ee40e release candidate ns-3.1-RC1 From 098186e7e6ff57356b0b5349676f6c166148b454 Mon Sep 17 00:00:00 2001 From: Craig Dowell Date: Tue, 17 Jun 2008 11:53:20 -0700 Subject: [PATCH 015/495] fill in some blanks --- doc/release_steps.txt | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/doc/release_steps.txt b/doc/release_steps.txt index a31da0fba..dc959aaad 100644 --- a/doc/release_steps.txt +++ b/doc/release_steps.txt @@ -7,6 +7,7 @@ Steps in doing an ns-3 release - update and check in VERSION to the latest release number - confirm that Doxygen builds cleanly and without warnings (./waf check; ./waf --doxygen), and check in any necessary changes + - ensure no regressions (./waf --regression) 2. ./waf configure; ./waf dist - this will create a ns-3.0.x.tar.bz2 tarball - this will also create a ns-3.0.x-ref-traces.tar.bz2 tarball @@ -38,12 +39,16 @@ Steps in doing an ns-3 release directory on the www.nsnam.org server - give it 644 file permissions, and user/group = apache 10. update web pages on www.nsnam.org (source is in the www/ module) + - clone the source repo (hg clone http://code.nsnam.org/www) - add link to news.html - update getting_started.html - update documents.html - update roadmap on wiki - - build and update Doxygen directory on the server + - commit and push changes + - build and update HTML directory on the server -- ssh www.nsnam.org; sudo tcsh; su nsnam; + -- run ~/bin/update-html + - build and update Doxygen directory on the server -- edit ~/bin/update-doxygen-release file and change RELEASE variable to the right version number -- run ~/bin/update-doxygen-release From 9da2bfa832e472ffcf2ab9ef53b9ec162ac80521 Mon Sep 17 00:00:00 2001 From: Craig Dowell Date: Tue, 17 Jun 2008 11:57:27 -0700 Subject: [PATCH 016/495] bump --- RELEASE_NOTES | 15 +++++++++++++++ VERSION | 2 +- 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/RELEASE_NOTES b/RELEASE_NOTES index 572bc13d7..0441d0d04 100644 --- a/RELEASE_NOTES +++ b/RELEASE_NOTES @@ -3,6 +3,21 @@ This file contains ns-3 release notes (most recent releases first). +Release 3.1 (2008/06/30 tentatively) +======================== +First supported ns-3 release. + +- TCP bugfixes and support for packet tags +- CSMA NetDevice cleanup and documentation +- internet-node renamed to internet-stack +- Socket::RecvFrom added; "flags" argument added to Send calls +- updated doxygen +- several bugs and open issues closed out +- revised tutorial + +Note: Some API in class ns3::Ipv4 and ns3::Ipv4RoutingProtocol is +deprecated and may be removed and replaced in future releases. + Release 3.0.13 (2008/06/02) ======================== - point to point links generate ppp pcap traces diff --git a/VERSION b/VERSION index eea30e595..b70bb4894 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -3.0.13 +3.1-RC1 From a6aed94fe881671b946fce88951124c7e95cb11f Mon Sep 17 00:00:00 2001 From: Craig Dowell Date: Tue, 17 Jun 2008 12:52:46 -0700 Subject: [PATCH 017/495] plug more holes in release steps --- doc/release_steps.txt | 26 ++++++++++++++------------ wscript | 4 ++-- 2 files changed, 16 insertions(+), 14 deletions(-) diff --git a/doc/release_steps.txt b/doc/release_steps.txt index dc959aaad..cbc92bd81 100644 --- a/doc/release_steps.txt +++ b/doc/release_steps.txt @@ -8,34 +8,36 @@ Steps in doing an ns-3 release - confirm that Doxygen builds cleanly and without warnings (./waf check; ./waf --doxygen), and check in any necessary changes - ensure no regressions (./waf --regression) + - update the wscript in ns-3-dev to point REGRESSION_TRACES_TAR_NAME and + REGRESSION_TRACES_DIR_NAME to the correct places. 2. ./waf configure; ./waf dist - - this will create a ns-3.0.x.tar.bz2 tarball - - this will also create a ns-3.0.x-ref-traces.tar.bz2 tarball + - this will create a ns-3.1x.tar.bz2 tarball + - this will also create a ns-3.1x-ref-traces.tar.bz2 tarball 3. test tarball on release platforms (waf check and maybe some other scripts) 4. once you are happy with the tarball, tag ns-3-dev with "release ns-3.0.X" - - hg tag "release ns-3.0.x" + - hg tag "release ns-3.1x" - hg push 5. clone the tagged ns-3-dev and place it on the repository - ssh code.nsnam.org; sudo tcsh; su code; - - cp -r /home/code/repos/ns-3-dev /home/code/repos/ns-3.0.x - - cd /home/code/repos/ns-3.0.x/.hg and edit the hgrc appropriately: - "description = ns-3.0.x release - name = ns-3.0.x" + - cp -r /home/code/repos/ns-3-dev /home/code/repos/ns-3.1x + - cd /home/code/repos/ns-3.1x/.hg and edit the hgrc appropriately: + "description = ns-3.1x release + name = ns-3.1x" 6. Run the regression tests on the new release and update the reference traces - ./waf --regression - ./waf --valgrind --regression (for valgrind version) - There should be no regression errors at this time - - tag ns-3-dev-ref-traces with "release ns-3.0.X" - hg tag "release ns-3.0.x" + - tag ns-3-dev-ref-traces with "release ns-3.1X" + hg tag "release ns-3.1x" hg push - clone the ns-3-dev-ref-traces and place it on the repository as in step - 5 but use the name ns-3.0.x-ref-traces + 5 but use the name ns-3.1x-ref-traces 7. Create a reference traces tarball - again, run "./waf dist" -8. upload "ns-3.0.x.tar.bz2" to the /var/www/html/releases/ directory on +8. upload "ns-3.1x.tar.bz2" to the /var/www/html/releases/ directory on the www.nsnam.org server - give it 644 file permissions, and user/group = apache -9. upload "ns-3.0.x-ref-traces.tar.bz2" to the /var/www/html/releases/ +9. upload "ns-3.1x-ref-traces.tar.bz2" to the /var/www/html/releases/ directory on the www.nsnam.org server - give it 644 file permissions, and user/group = apache 10. update web pages on www.nsnam.org (source is in the www/ module) diff --git a/wscript b/wscript index 150868743..1c5699a91 100644 --- a/wscript +++ b/wscript @@ -34,7 +34,7 @@ REGRESSION_TRACES_URL = "http://www.nsnam.org/releases/" # mercurial on the system. It is expected to be created using tar -cjf and # will be extracted using tar -xjf # -REGRESSION_TRACES_TAR_NAME = "ns-3.0.12-ref-traces.tar.bz2" +REGRESSION_TRACES_TAR_NAME = "ns-3.1-RC1-ref-traces.tar.bz2" # # The path to the Mercurial repository used to find the reference traces if @@ -47,7 +47,7 @@ REGRESSION_TRACES_REPO = "http://code.nsnam.org/" # The local directory name (relative to the 'regression' dir) into # which the reference traces will go in either case (net or hg). # -REGRESSION_TRACES_DIR_NAME = "ns-3-dev-ref-traces" +REGRESSION_TRACES_DIR_NAME = "ns-3.1-RC1-ref-traces" def dist_hook(): From b5cfed2178705a79be908d54d70d3e2d526681c0 Mon Sep 17 00:00:00 2001 From: Craig Dowell Date: Tue, 17 Jun 2008 13:37:04 -0700 Subject: [PATCH 018/495] use dev traces --- wscript | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wscript b/wscript index 1c5699a91..839d57e35 100644 --- a/wscript +++ b/wscript @@ -47,7 +47,7 @@ REGRESSION_TRACES_REPO = "http://code.nsnam.org/" # The local directory name (relative to the 'regression' dir) into # which the reference traces will go in either case (net or hg). # -REGRESSION_TRACES_DIR_NAME = "ns-3.1-RC1-ref-traces" +REGRESSION_TRACES_DIR_NAME = "ns-3-dev-ref-traces" def dist_hook(): From d4a0ae2a7424898fd5702b5fedd40a5728d5e10e Mon Sep 17 00:00:00 2001 From: "Gustavo J. A. M. Carneiro" Date: Wed, 18 Jun 2008 15:21:08 +0100 Subject: [PATCH 019/495] Add a WAF workaround for the 'Input line is too long.' error in win32/mingw. --- wscript | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/wscript b/wscript index 839d57e35..59dc6d6bc 100644 --- a/wscript +++ b/wscript @@ -244,6 +244,22 @@ def add_scratch_programs(bld): obj.source = "scratch/%s" % filename obj.target = "scratch/%s" % name + +## +## This replacement spawn function increases the maximum command line length to 32k +## +def _exec_command_interact_win32(s): + if Params.g_verbose: + print s + startupinfo = subprocess.STARTUPINFO() + startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW + proc = subprocess.Popen(s, shell=False, startupinfo=startupinfo) + stat = proc.wait() + if stat & 0xff: + return stat | 0x80 + return stat >> 8 + + def build(bld): if Params.g_options.no_task_lines: import Runner @@ -251,6 +267,10 @@ def build(bld): pass Runner.printout = null_printout + if sys.platform == 'win32': + import Runner + Runner.exec_command = _exec_command_interact_win32 + Params.g_cwd_launch = Params.g_build.m_curdirnode.abspath() bld.create_ns3_program = types.MethodType(create_ns3_program, bld) variant_name = bld.env_of_name('default')['NS3_ACTIVE_VARIANT'] From 2d2675e6f8e8c932adc92bc2432542aeda68dd31 Mon Sep 17 00:00:00 2001 From: "Gustavo J. A. M. Carneiro" Date: Wed, 18 Jun 2008 18:07:48 +0100 Subject: [PATCH 020/495] Bug 223: Regression using other than mercurial traces no longer works --- wscript | 1 + 1 file changed, 1 insertion(+) diff --git a/wscript b/wscript index 59dc6d6bc..944c14f74 100644 --- a/wscript +++ b/wscript @@ -806,6 +806,7 @@ def run_regression(): Params.fatal("Synchronizing reference traces using Mercurial failed.") else: print "Synchronizing reference traces from web." + import urllib urllib.urlretrieve(REGRESSION_TRACES_URL + REGRESSION_TRACES_TAR_NAME, REGRESSION_TRACES_TAR_NAME) os.system("tar -xjf %s" % (REGRESSION_TRACES_TAR_NAME,)) From e1d52991b6ad5c51ab29afbb919bf2bef723c302 Mon Sep 17 00:00:00 2001 From: Craig Dowell Date: Wed, 18 Jun 2008 10:29:19 -0700 Subject: [PATCH 021/495] fixes for regression numbering --- VERSION | 2 +- wscript | 64 +++++++++++++++++++++++++++++++++++---------------------- 2 files changed, 41 insertions(+), 25 deletions(-) diff --git a/VERSION b/VERSION index b70bb4894..1b8ef0972 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -3.1-RC1 +3-dev diff --git a/wscript b/wscript index 59dc6d6bc..949bc79f0 100644 --- a/wscript +++ b/wscript @@ -2,6 +2,7 @@ import sys import shlex import shutil +import urllib import types import optparse import os.path @@ -14,7 +15,6 @@ import ccroot Params.g_autoconfig = 1 - # the following two variables are used by the target "waf dist" VERSION = file("VERSION").read().strip() APPNAME = 'ns' @@ -29,13 +29,6 @@ blddir = 'build' # REGRESSION_TRACES_URL = "http://www.nsnam.org/releases/" -# -# The name of the tarball to find the reference traces in if there is no -# mercurial on the system. It is expected to be created using tar -cjf and -# will be extracted using tar -xjf -# -REGRESSION_TRACES_TAR_NAME = "ns-3.1-RC1-ref-traces.tar.bz2" - # # The path to the Mercurial repository used to find the reference traces if # we find "hg" on the system. We expect that the repository will be named @@ -44,10 +37,23 @@ REGRESSION_TRACES_TAR_NAME = "ns-3.1-RC1-ref-traces.tar.bz2" REGRESSION_TRACES_REPO = "http://code.nsnam.org/" # -# The local directory name (relative to the 'regression' dir) into -# which the reference traces will go in either case (net or hg). +# Name of the local directory where the regression code lives. # -REGRESSION_TRACES_DIR_NAME = "ns-3-dev-ref-traces" +REGRESSION_DIR = "regression" + +# +# The last part of the path name to use to find the regression traces. The +# path will be APPNAME + '-' + VERSION + REGRESSION_SUFFIX, e.g., +# ns-3-dev-ref-traces +# +REGRESSION_SUFFIX = "-ref-traces" + +# +# The last part of the path name to use to find the regression traces tarball. +# path will be APPNAME + '-' + VERSION + REGRESSION_SUFFIX + TRACEBALL_SUFFIX, +# e.g., ns-3-dev-ref-traces.tar.bz2 +# +TRACEBALL_SUFFIX = ".tar.bz2" def dist_hook(): @@ -55,13 +61,17 @@ def dist_hook(): shutil.rmtree("doc/html", True) shutil.rmtree("doc/latex", True) + ## build the name of the traces subdirectory. Will be something like + ## ns-3-dev-ref-traces + traces_name = APPNAME + '-' + VERSION + REGRESSION_SUFFIX ## Create a tar.bz2 file with the traces - traces_dir = os.path.join("regression", "ns-3-dev-ref-traces") + traces_dir = os.path.join(REGRESSION_DIR, traces_name) if not os.path.isdir(traces_dir): Params.warning("Not creating traces archive: the %s directory does not exist" % traces_dir) else: - tar = tarfile.open(os.path.join("..", "ns-%s-ref-traces.tar.bz2" % VERSION), 'w:bz2') - tar.add(traces_dir, "ns-3-dev-ref-traces") + traceball = traces_name + TRACEBALL_SUFFIX + tar = tarfile.open(os.path.join("..", traceball), 'w:bz2') + tar.add(traces_dir) tar.close() ## Now remove it; we do not ship the traces with the main tarball... shutil.rmtree(traces_dir, True) @@ -790,28 +800,32 @@ def run_regression(): tests = _find_tests(testdir) print "========== Running Regression Tests ==========" + dir_name = APPNAME + '-' + VERSION + REGRESSION_SUFFIX + print "dir_name = " + dir_name - if os.system("hg version > /dev/null 2>&1") == 0: + if os.system("hg version > /dev/null 2>&1") == 1: print "Synchronizing reference traces using Mercurial." - if not os.path.exists(REGRESSION_TRACES_DIR_NAME): - os.system("hg clone " + REGRESSION_TRACES_REPO + REGRESSION_TRACES_DIR_NAME + " > /dev/null 2>&1") + if not os.path.exists(dir_name): + os.system("hg clone " + REGRESSION_TRACES_REPO + dir_name + " > /dev/null 2>&1") else: _dir = os.getcwd() - os.chdir(REGRESSION_TRACES_DIR_NAME) + os.chdir(dir_name) try: - result = os.system("hg -q pull %s && hg -q update" % (REGRESSION_TRACES_REPO + REGRESSION_TRACES_DIR_NAME)) + print "pull and update " + REGRESSION_TRACES_REPO + dir_name + result = os.system("hg -q pull %s && hg -q update" % (REGRESSION_TRACES_REPO + dir_name)) finally: os.chdir("..") if result: Params.fatal("Synchronizing reference traces using Mercurial failed.") else: - print "Synchronizing reference traces from web." - urllib.urlretrieve(REGRESSION_TRACES_URL + REGRESSION_TRACES_TAR_NAME, REGRESSION_TRACES_TAR_NAME) - os.system("tar -xjf %s" % (REGRESSION_TRACES_TAR_NAME,)) + traceball = dir_name + TRACEBALL_SUFFIX + print "Synchronizing " + traceball + " from web." + urllib.urlretrieve(REGRESSION_TRACES_URL + traceball, traceball) + os.system("tar -xjf %s" % (traceball,)) print "Done." - if not os.path.exists(REGRESSION_TRACES_DIR_NAME): + if not os.path.exists(dir_name): print "Reference traces directory does not exist" return 3 @@ -847,7 +861,9 @@ def _run_regression_test(test): else: os.mkdir("traces") + dir_name = APPNAME + '-' + VERSION + REGRESSION_SUFFIX + mod = __import__(test, globals(), locals(), []) return mod.run(verbose=(Params.g_options.verbose > 0), generate=Params.g_options.regression_generate, - refDirName=REGRESSION_TRACES_DIR_NAME) + refDirName=dir_name) From d99df782e9bcdfaf7cc733122dd669981382333b Mon Sep 17 00:00:00 2001 From: Craig Dowell Date: Wed, 18 Jun 2008 10:34:05 -0700 Subject: [PATCH 022/495] regression --- wscript | 2 -- 1 file changed, 2 deletions(-) diff --git a/wscript b/wscript index 949bc79f0..d90fa80c6 100644 --- a/wscript +++ b/wscript @@ -723,8 +723,6 @@ class Regression(object): print "creating new " + refTestDirName os.mkdir(refTestDirName) - #os.system("./waf --cwd regression/" + refTestDirName + - # " --run " + testName + " > /dev/null 2>&1") Params.g_options.cwd_launch = refTestDirName run_program(testName) From 6f2e42050f297400abdd22824643679b4c0d2e5a Mon Sep 17 00:00:00 2001 From: Craig Dowell Date: Wed, 18 Jun 2008 10:39:30 -0700 Subject: [PATCH 023/495] print out which repo is used for regression --- wscript | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/wscript b/wscript index 1441556f0..e5cd6de5b 100644 --- a/wscript +++ b/wscript @@ -799,9 +799,8 @@ def run_regression(): print "========== Running Regression Tests ==========" dir_name = APPNAME + '-' + VERSION + REGRESSION_SUFFIX - print "dir_name = " + dir_name - if os.system("hg version > /dev/null 2>&1") == 1: + if os.system("hg version > /dev/null 2>&1") == 0: print "Synchronizing reference traces using Mercurial." if not os.path.exists(dir_name): os.system("hg clone " + REGRESSION_TRACES_REPO + dir_name + " > /dev/null 2>&1") @@ -809,7 +808,7 @@ def run_regression(): _dir = os.getcwd() os.chdir(dir_name) try: - print "pull and update " + REGRESSION_TRACES_REPO + dir_name + print REGRESSION_TRACES_REPO + dir_name result = os.system("hg -q pull %s && hg -q update" % (REGRESSION_TRACES_REPO + dir_name)) finally: os.chdir("..") From 458718348943961715c9467e2f2b404e6979e663 Mon Sep 17 00:00:00 2001 From: Craig Dowell Date: Wed, 18 Jun 2008 11:04:07 -0700 Subject: [PATCH 024/495] tweak release steps --- doc/release_steps.txt | 57 ++++++++++++++++++++++++++----------------- 1 file changed, 34 insertions(+), 23 deletions(-) diff --git a/doc/release_steps.txt b/doc/release_steps.txt index cbc92bd81..276ce181f 100644 --- a/doc/release_steps.txt +++ b/doc/release_steps.txt @@ -1,46 +1,52 @@ Steps in doing an ns-3 release -0. check out a clean ns-3-dev somewhere -1. prepare the source files +1. check out a clean ns-3-dev somewhere +2. prepare the source files - revise and check in AUTHORS, if needed - revise and check in RELEASE_NOTES - - update and check in VERSION to the latest release number + - DO NOT change VERSION at this time - confirm that Doxygen builds cleanly and without warnings (./waf check; ./waf --doxygen), and check in any necessary changes - ensure no regressions (./waf --regression) - - update the wscript in ns-3-dev to point REGRESSION_TRACES_TAR_NAME and - REGRESSION_TRACES_DIR_NAME to the correct places. -2. ./waf configure; ./waf dist - - this will create a ns-3.1x.tar.bz2 tarball - - this will also create a ns-3.1x-ref-traces.tar.bz2 tarball -3. test tarball on release platforms (waf check and maybe some other scripts) -4. once you are happy with the tarball, tag ns-3-dev with "release ns-3.0.X" +3. ./waf configure; ./waf dist + - this will create an ns-3-dev.tar.bz2 tarball + - this will also create a ns-3-dev-ref-traces.tar.bz2 tarball +4. test dev tarball on release platforms (waf check and maybe some other + scripts) +5. once you are happy with the tarball, tag ns-3-dev and ns-3-dev-ref-traces - hg tag "release ns-3.1x" - hg push -5. clone the tagged ns-3-dev and place it on the repository + - cd into regression/ns-3-dev-ref-traces + - hg tag "release ns-3.1x" + - hg push +6. clone the tagged ns-3-dev and place it on the repository - ssh code.nsnam.org; sudo tcsh; su code; - cp -r /home/code/repos/ns-3-dev /home/code/repos/ns-3.1x - cd /home/code/repos/ns-3.1x/.hg and edit the hgrc appropriately: "description = ns-3.1x release name = ns-3.1x" -6. Run the regression tests on the new release and update the reference traces + - clone the ns-3-dev-ref-traces and place it on the repository as above + but use the name ns-3.1x-ref-traces +7. check out a clean version of the new release (ns-3.1x) somewhere +8. Update the VERSION for this new release + - change the string 3-dev in the VERSION file to the real version + (e.g. 3.1) This must agree with the version name you chose in the clone + for the regression tests to work. + - hg commit + - hg push +9. Run the regression tests on the new release - ./waf --regression - ./waf --valgrind --regression (for valgrind version) - There should be no regression errors at this time - - tag ns-3-dev-ref-traces with "release ns-3.1X" - hg tag "release ns-3.1x" - hg push - - clone the ns-3-dev-ref-traces and place it on the repository as in step - 5 but use the name ns-3.1x-ref-traces -7. Create a reference traces tarball - - again, run "./waf dist" -8. upload "ns-3.1x.tar.bz2" to the /var/www/html/releases/ directory on +10. Create final tarballs + - run "./waf dist" +11. upload "ns-3.1x.tar.bz2" to the /var/www/html/releases/ directory on the www.nsnam.org server - give it 644 file permissions, and user/group = apache -9. upload "ns-3.1x-ref-traces.tar.bz2" to the /var/www/html/releases/ +12. upload "ns-3.1x-ref-traces.tar.bz2" to the /var/www/html/releases/ directory on the www.nsnam.org server - give it 644 file permissions, and user/group = apache -10. update web pages on www.nsnam.org (source is in the www/ module) +13. update web pages on www.nsnam.org (source is in the www/ module) - clone the source repo (hg clone http://code.nsnam.org/www) - add link to news.html - update getting_started.html @@ -54,4 +60,9 @@ Steps in doing an ns-3 release -- edit ~/bin/update-doxygen-release file and change RELEASE variable to the right version number -- run ~/bin/update-doxygen-release -11. announce to ns-developers, with summary of release notes +14. Final checks + - download tarball from web, build and run regression tests for as many + targets as you can + - download release from mercurial, build and run regression tests for as + many targets as you can +15. announce to ns-developers, with summary of release notes From aefd3e3371ce947eaad9085ca0c33fc5a31167bf Mon Sep 17 00:00:00 2001 From: Craig Dowell Date: Wed, 18 Jun 2008 11:57:43 -0700 Subject: [PATCH 025/495] tweaks after actually doing it --- doc/release_steps.txt | 23 ++++++++++++++++------- wscript | 2 +- 2 files changed, 17 insertions(+), 8 deletions(-) diff --git a/doc/release_steps.txt b/doc/release_steps.txt index 276ce181f..4641654cd 100644 --- a/doc/release_steps.txt +++ b/doc/release_steps.txt @@ -26,7 +26,7 @@ Steps in doing an ns-3 release "description = ns-3.1x release name = ns-3.1x" - clone the ns-3-dev-ref-traces and place it on the repository as above - but use the name ns-3.1x-ref-traces + but use the name ns-3.1x-ref-traces and edit the hgrc appropriately 7. check out a clean version of the new release (ns-3.1x) somewhere 8. Update the VERSION for this new release - change the string 3-dev in the VERSION file to the real version @@ -34,12 +34,20 @@ Steps in doing an ns-3 release for the regression tests to work. - hg commit - hg push -9. Run the regression tests on the new release +9. Run the regression tests on the new release (debug and optimized) + - ./waf -d debug configure + - ./waf + - ./waf --regression + - ./waf --valgrind --regression (for valgrind version) + - ./waf -d optimized configure + - ./waf - ./waf --regression - ./waf --valgrind --regression (for valgrind version) - There should be no regression errors at this time 10. Create final tarballs - - run "./waf dist" + - ./waf configure; ./waf dist + - this will create an ns-3.1x.tar.bz2 tarball + - this will also create a ns-3.1x-ref-traces.tar.bz2 tarball 11. upload "ns-3.1x.tar.bz2" to the /var/www/html/releases/ directory on the www.nsnam.org server - give it 644 file permissions, and user/group = apache @@ -61,8 +69,9 @@ Steps in doing an ns-3 release to the right version number -- run ~/bin/update-doxygen-release 14. Final checks - - download tarball from web, build and run regression tests for as many - targets as you can - - download release from mercurial, build and run regression tests for as - many targets as you can + - download tarball from web, build and run regression tests for as many + targets as you can + - download release from mercurial, build and run regression tests for as + many targets as you can + - test and verify until you're confident the release is solid. 15. announce to ns-developers, with summary of release notes diff --git a/wscript b/wscript index e5cd6de5b..0345b9c97 100644 --- a/wscript +++ b/wscript @@ -818,7 +818,7 @@ def run_regression(): traceball = dir_name + TRACEBALL_SUFFIX print "Synchronizing " + traceball + " from web." urllib.urlretrieve(REGRESSION_TRACES_URL + traceball, traceball) - os.system("tar -xjf %s" % (traceball,)) + os.system("tar -xjf %s -C .." % (traceball)) print "Done." if not os.path.exists(dir_name): From b3578666552af34aef173e193d501e17833fe9b6 Mon Sep 17 00:00:00 2001 From: Unknown Date: Wed, 18 Jun 2008 21:17:56 -0700 Subject: [PATCH 026/495] GetNNodes() in NodeList fixes bug 225 --- src/node/node-list.cc | 5 +++++ src/node/node-list.h | 4 ++++ 2 files changed, 9 insertions(+) diff --git a/src/node/node-list.cc b/src/node/node-list.cc index e99a94b35..651be40b2 100644 --- a/src/node/node-list.cc +++ b/src/node/node-list.cc @@ -172,5 +172,10 @@ NodeList::GetNode (uint32_t n) { return NodeListPriv::Get ()->GetNode (n); } +uint32_t +NodeList::GetNNodes (void) +{ + return NodeListPriv::Get ()->GetNNodes (); +} }//namespace ns3 diff --git a/src/node/node-list.h b/src/node/node-list.h index 137363dff..2d74b67df 100644 --- a/src/node/node-list.h +++ b/src/node/node-list.h @@ -65,6 +65,10 @@ public: * \returns the Node associated to index n. */ static Ptr GetNode (uint32_t n); + /** + * \returns the number of nodes currently in the list. + */ + static uint32_t GetNNodes (void); }; }//namespace ns3 From c7e37d1a18ab287ee14d8da8658a3167aa856a4a Mon Sep 17 00:00:00 2001 From: Unknown Date: Wed, 18 Jun 2008 21:29:21 -0700 Subject: [PATCH 027/495] move m_wouldBlock assignment to fix bug 226 --- src/internet-stack/tcp-socket-impl.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/internet-stack/tcp-socket-impl.cc b/src/internet-stack/tcp-socket-impl.cc index 0d97c90ee..cd66492ad 100644 --- a/src/internet-stack/tcp-socket-impl.cc +++ b/src/internet-stack/tcp-socket-impl.cc @@ -798,8 +798,8 @@ bool TcpSocketImpl::ProcessPacketAction (Actions_t a, Ptr p, // Data freed from the send buffer; notify any blocked sender if (m_wouldBlock) { - NotifySend (GetTxAvailable ()); m_wouldBlock = false; + NotifySend (GetTxAvailable ()); } } SendPendingData (); @@ -1172,8 +1172,8 @@ void TcpSocketImpl::CommonNewAck (SequenceNumber ack, bool skipTimer) { // m_highestRxAck advancing means some data was acked, and the size // of free space in the buffer has increased - NotifySend (GetTxAvailable ()); m_wouldBlock = false; + NotifySend (GetTxAvailable ()); } if (ack > m_nextTxSequence) { From 544f9d1a81690a6ab26046311cbd36fedf58139b Mon Sep 17 00:00:00 2001 From: Unknown Date: Thu, 19 Jun 2008 14:46:27 -0700 Subject: [PATCH 028/495] Bug 181 --- src/core/random-variable.cc | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/src/core/random-variable.cc b/src/core/random-variable.cc index 778cb2e45..be06c998b 100644 --- a/src/core/random-variable.cc +++ b/src/core/random-variable.cc @@ -1033,7 +1033,8 @@ double NormalVariableImpl::GetValue() } while(1) { // See Simulation Modeling and Analysis p. 466 (Averill Law) - // for algorithm + // for algorithm; basically a Box-Muller transform: + // http://en.wikipedia.org/wiki/Box-Muller_transform double u1 = m_generator->RandU01(); double u2 = m_generator->RandU01();; double v1 = 2 * u1 - 1; @@ -1082,7 +1083,8 @@ double NormalVariableImpl::GetSingleValue(double m, double v, double b) } while(1) { // See Simulation Modeling and Analysis p. 466 (Averill Law) - // for algorithm + // for algorithm; basically a Box-Muller transform: + // http://en.wikipedia.org/wiki/Box-Muller_transform double u1 = m_static_generator->RandU01(); double u2 = m_static_generator->RandU01();; double v1 = 2 * u1 - 1; @@ -1092,11 +1094,21 @@ double NormalVariableImpl::GetSingleValue(double m, double v, double b) { // Got good pair double y = sqrt((-2 * log(w))/w); m_static_next = m + v2 * y * sqrt(v); - if (fabs(m_static_next) > b) m_static_next = b * (m_static_next)/fabs(m_static_next); - m_static_nextValid = true; + //if next is in bounds, it is valid + m_static_nextValid = fabs(m_static_next-m) <= b;; double x1 = m + v1 * y * sqrt(v); - if (fabs(x1) > b) x1 = b * (x1)/fabs(x1); - return x1; + //if x1 is in bounds, return it + if (fabs(x1-m) <= b) + { + return x1; + } + //otherwise try and return m_next if it is valid + else if (m_static_nextValid) + { + m_static_nextValid = false; + return m_static_next; + } + //otherwise, just run this loop again } } } From 7c05c10381d9fb04c9dac5007207e12f90027e16 Mon Sep 17 00:00:00 2001 From: Unknown Date: Thu, 19 Jun 2008 14:53:53 -0700 Subject: [PATCH 029/495] same messages for all versions of getting traces --- wscript | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/wscript b/wscript index 0345b9c97..84fade74a 100644 --- a/wscript +++ b/wscript @@ -803,12 +803,13 @@ def run_regression(): if os.system("hg version > /dev/null 2>&1") == 0: print "Synchronizing reference traces using Mercurial." if not os.path.exists(dir_name): + print "Cloning " + REGRESSION_TRACES_REPO + dir_name + " from repo." os.system("hg clone " + REGRESSION_TRACES_REPO + dir_name + " > /dev/null 2>&1") else: _dir = os.getcwd() os.chdir(dir_name) try: - print REGRESSION_TRACES_REPO + dir_name + print "Pulling " + REGRESSION_TRACES_REPO + dir_name + " from repo." result = os.system("hg -q pull %s && hg -q update" % (REGRESSION_TRACES_REPO + dir_name)) finally: os.chdir("..") @@ -816,7 +817,7 @@ def run_regression(): Params.fatal("Synchronizing reference traces using Mercurial failed.") else: traceball = dir_name + TRACEBALL_SUFFIX - print "Synchronizing " + traceball + " from web." + print "Retrieving " + traceball + " from web." urllib.urlretrieve(REGRESSION_TRACES_URL + traceball, traceball) os.system("tar -xjf %s -C .." % (traceball)) print "Done." From 4743c2ff7c42095a9c02dca61da8d4e005517463 Mon Sep 17 00:00:00 2001 From: Unknown Date: Thu, 19 Jun 2008 14:58:46 -0700 Subject: [PATCH 030/495] Patch addresses bug 227. --- examples/tcp-large-transfer.cc | 158 +++++++++++++++++---------------- 1 file changed, 82 insertions(+), 76 deletions(-) diff --git a/examples/tcp-large-transfer.cc b/examples/tcp-large-transfer.cc index 2aab318a7..f052b478c 100644 --- a/examples/tcp-large-transfer.cc +++ b/examples/tcp-large-transfer.cc @@ -25,12 +25,10 @@ // - Tracing of queues and packet receptions to file // "tcp-large-transfer.tr" // - pcap traces also generated in the following files -// "tcp-large-transfer.pcap-$n-$i" where n and i represent node and interface numbers respectively +// "tcp-large-transfer-$n-$i.pcap" where n and i represent node and interface +// numbers respectively // Usage (e.g.): ./waf --run tcp-large-transfer -//XXX this isn't working as described right now -//it is just blasting away for 10 seconds, with no fixed amount of data -//being sent #include #include @@ -48,37 +46,15 @@ using namespace ns3; NS_LOG_COMPONENT_DEFINE ("TcpLargeTransfer"); -void -ApplicationTraceSink (Ptr packet, - const Address &addr) -{ -// g_log is not declared in optimized builds -// should convert this to use of some other flag than the logging system -#ifdef NS3_LOG_ENABLE - if (!g_log.IsNoneEnabled ()) { - if (InetSocketAddress::IsMatchingType (addr) ) - { - InetSocketAddress address = InetSocketAddress::ConvertFrom (addr); - std::cout << "PacketSink received size " << - packet->GetSize () << " at time " << - Simulator::Now ().GetSeconds () << " from address: " << - address.GetIpv4 () << std::endl; - char buf[2000]; - memcpy(buf, packet->PeekData (), packet->GetSize ()); - for (uint32_t i=0; i < packet->GetSize (); i++) - { - std::cout << buf[i]; - if (i && i % 60 == 0) - std::cout << std::endl; - } - std::cout << std::endl << std::endl; - } - } -#endif -} +// The number of bytes to send in this simulation. +static uint32_t txBytes = 2000000; -void CloseConnection (Ptr localSocket); -void StartFlow(Ptr, uint32_t, Ipv4Address, uint16_t); +// These are for starting the writing process, and handling the sending +// socket's notification upcalls (events). These two together more or less +// implement a sending "Application", although not a proper ns3::Application +// subclass. + +void StartFlow(Ptr, Ipv4Address, uint16_t); void WriteUntilBufferFull (Ptr, uint32_t); int main (int argc, char *argv[]) @@ -101,27 +77,34 @@ int main (int argc, char *argv[]) CommandLine cmd; cmd.Parse (argc, argv); - // Here, we will explicitly create three nodes. - NodeContainer c0; - c0.Create (2); + // Here, we will explicitly create three nodes. The first container contains + // nodes 0 and 1 from the diagram above, and the second one contains nodes + // 1 and 2. This reflects the channel connectivity, and will be used to + // install the network interfaces and connect them with a channel. + NodeContainer n0n1; + n0n1.Create (2); - NodeContainer c1; - c1.Add (c0.Get (1)); - c1.Create (1); + NodeContainer n1n2; + n1n2.Add (n0n1.Get (1)); + n1n2.Create (1); // We create the channels first without any IP addressing information + // First make and configure the helper, so that it will put the appropriate + // parameters on the network interfaces and channels we are about to install. PointToPointHelper p2p; p2p.SetDeviceParameter ("DataRate", DataRateValue (DataRate(10000000))); p2p.SetChannelParameter ("Delay", TimeValue (MilliSeconds(10))); - NetDeviceContainer dev0 = p2p.Install (c0); - NetDeviceContainer dev1 = p2p.Install (c1); - // add ip/tcp stack to nodes. - NodeContainer c = NodeContainer (c0, c1.Get (1)); + // And then install devices and channels connecting our topology. + NetDeviceContainer dev0 = p2p.Install (n0n1); + NetDeviceContainer dev1 = p2p.Install (n1n2); + + // Now add ip/tcp stack to all nodes. + NodeContainer allNodes = NodeContainer (n0n1, n1n2.Get (1)); InternetStackHelper internet; - internet.Install (c); + internet.Install (allNodes); - // Later, we add IP addresses. + // Later, we add IP addresses. Ipv4AddressHelper ipv4; ipv4.SetBase ("10.1.3.0", "255.255.255.0"); ipv4.Assign (dev0); @@ -133,82 +116,105 @@ int main (int argc, char *argv[]) /////////////////////////////////////////////////////////////////////////// // Simulation 1 - // + // // Send 2000000 bytes over a connection to server port 50000 at time 0 - // Should observe SYN exchange, a lot of data segments, and FIN exchange + // Should observe SYN exchange, a lot of data segments and ACKS, and FIN + // exchange. FIN exchange isn't quite compliant with TCP spec (see release + // notes for more info) // /////////////////////////////////////////////////////////////////////////// - int nBytes = 2000000; uint16_t servPort = 50000; - // Create a packet sink to receive these packets + // Create a packet sink to receive these packets on n2... PacketSinkHelper sink ("ns3::TcpSocketFactory", InetSocketAddress (Ipv4Address::GetAny (), servPort)); - ApplicationContainer apps = sink.Install (c1.Get (1)); + ApplicationContainer apps = sink.Install (n1n2.Get (1)); apps.Start (Seconds (0.0)); - // and generate traffic to remote sink. - //TypeId tid = TypeId::LookupByName ("ns3::TcpSocketFactory"); - Ptr localSocket = Socket::CreateSocket (c0.Get (0), TcpSocketFactory::GetTypeId ()); + // Create a source to send packets from n0. Instead of a full Application + // and the helper APIs you might see in other example files, this example + // will use sockets directly and register some socket callbacks as a sending + // "Application". + + // Create and bind the socket... + Ptr localSocket = + Socket::CreateSocket (n0n1.Get (0), TcpSocketFactory::GetTypeId ()); localSocket->Bind (); - Simulator::ScheduleNow (&StartFlow, localSocket, nBytes, + + // ...and schedule the sending "Application"; This is similar to what an + // ns3::Application subclass would do internally. + Simulator::ScheduleNow (&StartFlow, localSocket, ipInterfs.GetAddress (1), servPort); - Config::ConnectWithoutContext ("/NodeList/*/ApplicationList/*/Rx", - MakeCallback (&ApplicationTraceSink)); + // One can toggle the comment for the following line on or off to see the + // effects of finite send buffer modelling. One can also change the size of + // said buffer. + //localSocket->SetAttribute("SndBufSize", UintegerValue(4096)); + + //Ask for ASCII and pcap traces of network traffic std::ofstream ascii; ascii.open ("tcp-large-transfer.tr"); PointToPointHelper::EnableAsciiAll (ascii); PointToPointHelper::EnablePcapAll ("tcp-large-transfer"); + // Finally, set up the simulator to run. The 1000 second hard limit is a + // failsafe in case some change above causes the simulation to never end Simulator::Stop (Seconds(1000)); Simulator::Run (); Simulator::Destroy (); } -void CloseConnection (Ptr localSocket) -{ - localSocket->Close (); -} -void StartFlow(Ptr localSocket, uint32_t nBytes, +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +//begin implementation of sending "Application" +void StartFlow(Ptr localSocket, Ipv4Address servAddress, uint16_t servPort) { - // NS_LOG_LOGIC("Starting flow at time " << Simulator::Now ().GetSeconds ()); + NS_LOG_LOGIC("Starting flow at time " << Simulator::Now ().GetSeconds ()); localSocket->Connect (InetSocketAddress (servAddress, servPort));//connect - localSocket->SetConnectCallback (MakeCallback (&CloseConnection), - Callback > ()); - //we want to close as soon as the connection is established - //the tcp state machine and outgoing buffer will assure that - //all of the data is delivered + + // tell the tcp implementation to call WriteUntilBufferFull again + // if we blocked and new tx buffer space becomes available localSocket->SetSendCallback (MakeCallback (&WriteUntilBufferFull)); - WriteUntilBufferFull (localSocket, nBytes); + WriteUntilBufferFull (localSocket, txBytes); } -void WriteUntilBufferFull (Ptr localSocket, uint32_t nBytes) +void WriteUntilBufferFull (Ptr localSocket, uint32_t txSpace) { // Perform series of 1040 byte writes (this is a multiple of 26 since // we want to detect data splicing in the output stream) uint32_t writeSize = 1040; uint8_t data[writeSize]; - while (nBytes > 0) { - uint32_t curSize= nBytes > writeSize ? writeSize : nBytes; + + while (txBytes > 0) { + uint32_t curSize= txBytes > writeSize ? writeSize : txBytes; + if (curSize > txSpace) + curSize = txSpace; for(uint32_t i = 0; i < curSize; ++i) { char m = toascii (97 + i % 26); data[i] = m; } - uint32_t amountSent = localSocket->Send (data, curSize, 0); - if(amountSent < curSize) + int amountSent = localSocket->Send (data, curSize, 0); + if(amountSent < 0) { - std::cout << "Socket blocking, returning" << std::endl; + // we will be called again when new tx space becomes available. + std::cout << "Socket blocking, " << txBytes << " left to write, returning" << std::endl; + return; + } + txBytes -= curSize; + if (amountSent != (int)curSize) + { + std::cout << "Short Write, returning" << std::endl; return; } - nBytes -= curSize; } + localSocket->Close (); } From da514b5edbae66ce9eee576652279d095f863355 Mon Sep 17 00:00:00 2001 From: Mathieu Lacage Date: Fri, 20 Jun 2008 15:06:23 -0700 Subject: [PATCH 031/495] bug 217: Handle gracefully the case where a packet aggregated contains nothing. --- src/common/packet-metadata.cc | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/common/packet-metadata.cc b/src/common/packet-metadata.cc index daca275b3..698e01d87 100644 --- a/src/common/packet-metadata.cc +++ b/src/common/packet-metadata.cc @@ -726,6 +726,12 @@ PacketMetadata::AddAtEnd (PacketMetadata const&o) *this = o; return; } + if (o.m_head == 0xffff) + { + NS_ASSERT (o.m_tail == 0xffff); + // we have nothing to append. + return; + } NS_ASSERT (m_head != 0xffff && m_tail != 0xffff); // We read the current tail because we are going to append From 8a78bf66ae2aa76f01a5eeefb8072eb8ec8bf2d4 Mon Sep 17 00:00:00 2001 From: Mathieu Lacage Date: Fri, 20 Jun 2008 19:20:58 -0700 Subject: [PATCH 032/495] testcase for changeset 133490cf0210 --- src/common/packet-metadata-test.cc | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/common/packet-metadata-test.cc b/src/common/packet-metadata-test.cc index 1b4704ab6..7cb1283d5 100644 --- a/src/common/packet-metadata-test.cc +++ b/src/common/packet-metadata-test.cc @@ -752,6 +752,13 @@ PacketMetadataTest::RunTests (void) p2 = p->CreateFragment(100, 100); p1->AddAtEnd (p2); + p = Create (); + ADD_HEADER (p, 10); + p1 = Create (); + ADD_HEADER (p1, 11); + REM_HEADER (p1, 11); + p->AddAtEnd (p1); + return result; } From 9008e089ae3610df5a7abb476dfe8332a410b27c Mon Sep 17 00:00:00 2001 From: Mathieu Lacage Date: Sat, 21 Jun 2008 08:05:21 -0700 Subject: [PATCH 033/495] bug 217: add failing testcase --- src/common/packet.cc | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/src/common/packet.cc b/src/common/packet.cc index b2c2fd896..358f976be 100644 --- a/src/common/packet.cc +++ b/src/common/packet.cc @@ -782,6 +782,7 @@ PacketTest::DoCheck (Ptr p, const char *file, int line, uint32_t n delete tag; j++; } + NS_TEST_ASSERT_EQUAL (j, expected.size ()); return result; } @@ -887,7 +888,18 @@ PacketTest::RunTests (void) CHECK (tmp, 1, E (20, 0, 100)); } - + + { + Ptr tmp = Create (0); + tmp->AddHeader (ATestHeader<156> ()); + tmp->AddTag (ATestTag<20> ()); + CHECK (tmp, 1, E (20, 0, 156)); + tmp->RemoveAtStart (120); + CHECK (tmp, 1, E (20, 0, 36)); + Ptr a = Create (0); + a->AddAtEnd (tmp); + CHECK (a, 1, E (20, 0, 36)); + } return result; } From 0c35c2b60f08a170986cf06d0d7b942329d764f6 Mon Sep 17 00:00:00 2001 From: Mathieu Lacage Date: Sat, 21 Jun 2008 08:11:10 -0700 Subject: [PATCH 034/495] bug 217: avoid unsigned/signed confusion. Used signed all the time. --- src/common/tag-list.cc | 34 ++++++++++++++++++++++------------ src/common/tag-list.h | 27 ++++++++++++++------------- 2 files changed, 36 insertions(+), 25 deletions(-) diff --git a/src/common/tag-list.cc b/src/common/tag-list.cc index 13587c21d..9ccace2e8 100644 --- a/src/common/tag-list.cc +++ b/src/common/tag-list.cc @@ -25,6 +25,7 @@ NS_LOG_COMPONENT_DEFINE ("TagList"); #define USE_FREE_LIST 1 #define FREE_LIST_SIZE 1000 +#define OFFSET_MAX (2147483647) namespace ns3 { @@ -99,7 +100,7 @@ TagList::Iterator::PrepareForNext (void) } } } -TagList::Iterator::Iterator (uint8_t *start, uint8_t *end, uint32_t offsetStart, uint32_t offsetEnd) +TagList::Iterator::Iterator (uint8_t *start, uint8_t *end, int32_t offsetStart, int32_t offsetEnd) : m_current (start), m_end (end), m_offsetStart (offsetStart), @@ -158,7 +159,7 @@ TagList::~TagList () } TagBuffer -TagList::Add (TypeId tid, uint32_t bufferSize, uint32_t start, uint32_t end) +TagList::Add (TypeId tid, uint32_t bufferSize, int32_t start, int32_t end) { NS_LOG_FUNCTION (this << tid << bufferSize << start << end); uint32_t spaceNeeded = m_used + bufferSize + 4 + 4 + 4 + 4; @@ -191,7 +192,7 @@ void TagList::Add (const TagList &o) { NS_LOG_FUNCTION (this << &o); - TagList::Iterator i = o.Begin (0, 0xffffffff); + TagList::Iterator i = o.BeginAll (); while (i.HasNext ()) { TagList::Iterator::Item item = i.Next (); @@ -210,7 +211,16 @@ TagList::RemoveAll (void) } TagList::Iterator -TagList::Begin (uint32_t offsetStart, uint32_t offsetEnd) const +TagList::BeginAll (void) const +{ + NS_LOG_FUNCTION (this); + // I am not totally sure but I might need to use + // INT32_MIN instead of zero below. + return Begin (0, OFFSET_MAX); +} + +TagList::Iterator +TagList::Begin (int32_t offsetStart, int32_t offsetEnd) const { NS_LOG_FUNCTION (this << offsetStart << offsetEnd); if (m_data == 0) @@ -224,10 +234,10 @@ TagList::Begin (uint32_t offsetStart, uint32_t offsetEnd) const } bool -TagList::IsDirtyAtEnd (uint32_t appendOffset) +TagList::IsDirtyAtEnd (int32_t appendOffset) { NS_LOG_FUNCTION (this << appendOffset); - TagList::Iterator i = Begin (0, 0xffffffff); + TagList::Iterator i = BeginAll (); while (i.HasNext ()) { TagList::Iterator::Item item = i.Next (); @@ -240,10 +250,10 @@ TagList::IsDirtyAtEnd (uint32_t appendOffset) } bool -TagList::IsDirtyAtStart (uint32_t prependOffset) +TagList::IsDirtyAtStart (int32_t prependOffset) { NS_LOG_FUNCTION (this << prependOffset); - TagList::Iterator i = Begin (0, 0xffffffff); + TagList::Iterator i = BeginAll (); while (i.HasNext ()) { TagList::Iterator::Item item = i.Next (); @@ -256,7 +266,7 @@ TagList::IsDirtyAtStart (uint32_t prependOffset) } void -TagList::AddAtEnd (int32_t adjustment, uint32_t appendOffset) +TagList::AddAtEnd (int32_t adjustment, int32_t appendOffset) { NS_LOG_FUNCTION (this << adjustment << appendOffset); if (adjustment == 0 && !IsDirtyAtEnd (appendOffset)) @@ -264,7 +274,7 @@ TagList::AddAtEnd (int32_t adjustment, uint32_t appendOffset) return; } TagList list; - TagList::Iterator i = Begin (0, 0xffffffff); + TagList::Iterator i = BeginAll (); while (i.HasNext ()) { TagList::Iterator::Item item = i.Next (); @@ -290,7 +300,7 @@ TagList::AddAtEnd (int32_t adjustment, uint32_t appendOffset) } void -TagList::AddAtStart (int32_t adjustment, uint32_t prependOffset) +TagList::AddAtStart (int32_t adjustment, int32_t prependOffset) { NS_LOG_FUNCTION (this << adjustment << prependOffset); if (adjustment == 0 && !IsDirtyAtStart (prependOffset)) @@ -298,7 +308,7 @@ TagList::AddAtStart (int32_t adjustment, uint32_t prependOffset) return; } TagList list; - TagList::Iterator i = Begin (0, 0xffffffff); + TagList::Iterator i = BeginAll (); while (i.HasNext ()) { TagList::Iterator::Item item = i.Next (); diff --git a/src/common/tag-list.h b/src/common/tag-list.h index 76a659e91..c21e515c6 100644 --- a/src/common/tag-list.h +++ b/src/common/tag-list.h @@ -76,8 +76,8 @@ public: { TypeId tid; uint32_t size; - uint32_t start; - uint32_t end; + int32_t start; + int32_t end; TagBuffer buf; Item (TagBuffer buf); private: @@ -89,16 +89,16 @@ public: uint32_t GetOffsetStart (void) const; private: friend class TagList; - Iterator (uint8_t *start, uint8_t *end, uint32_t offsetStart, uint32_t offsetEnd); + Iterator (uint8_t *start, uint8_t *end, int32_t offsetStart, int32_t offsetEnd); void PrepareForNext (void); uint8_t *m_current; uint8_t *m_end; - uint32_t m_offsetStart; - uint32_t m_offsetEnd; + int32_t m_offsetStart; + int32_t m_offsetEnd; uint32_t m_nextTid; uint32_t m_nextSize; - uint32_t m_nextStart; - uint32_t m_nextEnd; + int32_t m_nextStart; + int32_t m_nextEnd; }; TagList (); @@ -116,7 +116,7 @@ public: * * */ - TagBuffer Add (TypeId tid, uint32_t bufferSize, uint32_t start, uint32_t end); + TagBuffer Add (TypeId tid, uint32_t bufferSize, int32_t start, int32_t end); /** * \param o the other list of tags to aggregate. @@ -138,24 +138,25 @@ public: * in this list: the boundaries of each tag as reported by their start and * end offsets will be included within the input offsetStart and offsetEnd. */ - TagList::Iterator Begin (uint32_t offsetStart, uint32_t offsetEnd) const; + TagList::Iterator Begin (int32_t offsetStart, int32_t offsetEnd) const; /** * Adjust the offsets stored internally by the adjustment delta and * make sure that all offsets are smaller than appendOffset which represents * the location where new bytes have been added to the byte buffer. */ - void AddAtEnd (int32_t adjustment, uint32_t appendOffset); + void AddAtEnd (int32_t adjustment, int32_t appendOffset); /** * Adjust the offsets stored internally by the adjustment delta and * make sure that all offsets are bigger than prependOffset which represents * the location where new bytes have been added to the byte buffer. */ - void AddAtStart (int32_t adjustment, uint32_t prependOffset); + void AddAtStart (int32_t adjustment, int32_t prependOffset); private: - bool IsDirtyAtEnd (uint32_t appendOffset); - bool IsDirtyAtStart (uint32_t prependOffset); + bool IsDirtyAtEnd (int32_t appendOffset); + bool IsDirtyAtStart (int32_t prependOffset); + TagList::Iterator BeginAll (void) const; struct TagListData *Allocate (uint32_t size); void Deallocate (struct TagListData *data); From c3fb9059ac0833e3c63778cfdc3d1d02b4f60361 Mon Sep 17 00:00:00 2001 From: Mathieu Lacage Date: Sat, 21 Jun 2008 08:55:04 -0700 Subject: [PATCH 035/495] another testcase for bug 217. Make sure we do not report tags outside of the current range --- examples/wscript | 4 ++++ src/common/packet.cc | 15 ++++++++++----- src/common/tag-list.cc | 2 +- 3 files changed, 15 insertions(+), 6 deletions(-) diff --git a/examples/wscript b/examples/wscript index eb668e130..1398f099f 100644 --- a/examples/wscript +++ b/examples/wscript @@ -58,3 +58,7 @@ def build(bld): ['core', 'simulator', 'mobility', 'wifi']) obj.source = 'wifi-ap.cc' + obj = bld.create_ns3_program('tcp-2way', + ['core', 'simulator', 'mobility', 'wifi']) + obj.source = 'tcp-2way.cc' + diff --git a/src/common/packet.cc b/src/common/packet.cc index 358f976be..303a3c6bc 100644 --- a/src/common/packet.cc +++ b/src/common/packet.cc @@ -727,10 +727,7 @@ struct Expected #define E(a,b,c) a,b,c #define CHECK(p, n, ...) \ - if (!DoCheck (p, __FILE__, __LINE__, n, __VA_ARGS__)) \ - { \ - result = false; \ - } + NS_TEST_ASSERT (DoCheck (p, __FILE__, __LINE__, n, __VA_ARGS__)) namespace ns3 { @@ -782,6 +779,7 @@ PacketTest::DoCheck (Ptr p, const char *file, int line, uint32_t n delete tag; j++; } + NS_TEST_ASSERT (!i.HasNext ()); NS_TEST_ASSERT_EQUAL (j, expected.size ()); return result; } @@ -899,7 +897,14 @@ PacketTest::RunTests (void) Ptr a = Create (0); a->AddAtEnd (tmp); CHECK (a, 1, E (20, 0, 36)); - } + } + + { + Ptr tmp = Create (0); + tmp->AddTag (ATestTag<20> ()); + CHECK (tmp, 0, E (20, 0, 0)); + } + return result; } diff --git a/src/common/tag-list.cc b/src/common/tag-list.cc index 9ccace2e8..4572d630d 100644 --- a/src/common/tag-list.cc +++ b/src/common/tag-list.cc @@ -90,7 +90,7 @@ TagList::Iterator::PrepareForNext (void) m_nextSize = buf.ReadU32 (); m_nextStart = buf.ReadU32 (); m_nextEnd = buf.ReadU32 (); - if (m_nextStart > m_offsetEnd || m_nextEnd < m_offsetStart) + if (m_nextStart >= m_offsetEnd || m_nextEnd <= m_offsetStart) { m_current += 4 + 4 + 4 + 4 + m_nextSize; } From 6d739bf2b58cac3bb6bdbdb46bf534a17bae3e9b Mon Sep 17 00:00:00 2001 From: Mathieu Lacage Date: Sat, 21 Jun 2008 10:30:47 -0700 Subject: [PATCH 036/495] bug 217: yet another testcase: make sure we handle degenerate testcases with tags which refer to non-existant data. --- src/common/packet.cc | 12 ++++++++++++ src/common/tag-list.cc | 4 ++-- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/src/common/packet.cc b/src/common/packet.cc index 303a3c6bc..7301f1198 100644 --- a/src/common/packet.cc +++ b/src/common/packet.cc @@ -904,6 +904,18 @@ PacketTest::RunTests (void) tmp->AddTag (ATestTag<20> ()); CHECK (tmp, 0, E (20, 0, 0)); } + { + Ptr tmp = Create (1000); + tmp->AddTag (ATestTag<20> ()); + CHECK (tmp, 1, E (20, 0, 1000)); + tmp->RemoveAtStart (1000); + CHECK (tmp, 0, E (0,0,0)); + Ptr a = Create (10); + a->AddTag (ATestTag<10> ()); + CHECK (a, 1, E (10, 0, 10)); + tmp->AddAtEnd (a); + CHECK (tmp, 1, E (10, 0, 10)); + } return result; diff --git a/src/common/tag-list.cc b/src/common/tag-list.cc index 4572d630d..6af8ec7a9 100644 --- a/src/common/tag-list.cc +++ b/src/common/tag-list.cc @@ -281,7 +281,7 @@ TagList::AddAtEnd (int32_t adjustment, int32_t appendOffset) item.start += adjustment; item.end += adjustment; - if (item.start > appendOffset) + if (item.start >= appendOffset) { continue; } @@ -315,7 +315,7 @@ TagList::AddAtStart (int32_t adjustment, int32_t prependOffset) item.start += adjustment; item.end += adjustment; - if (item.end < prependOffset) + if (item.end <= prependOffset) { continue; } From 1fe76d94f1ee32b7e07de29710f5e01114ffc992 Mon Sep 17 00:00:00 2001 From: Mathieu Lacage Date: Sat, 21 Jun 2008 13:22:39 -0700 Subject: [PATCH 037/495] remove tcp-2way from examples. mistake from changeset c8011a2a0c60 --- examples/wscript | 3 --- 1 file changed, 3 deletions(-) diff --git a/examples/wscript b/examples/wscript index 1398f099f..c3170a597 100644 --- a/examples/wscript +++ b/examples/wscript @@ -58,7 +58,4 @@ def build(bld): ['core', 'simulator', 'mobility', 'wifi']) obj.source = 'wifi-ap.cc' - obj = bld.create_ns3_program('tcp-2way', - ['core', 'simulator', 'mobility', 'wifi']) - obj.source = 'tcp-2way.cc' From 6746cc48eb68cb9d12bfb53e5e2228fe36d514d0 Mon Sep 17 00:00:00 2001 From: Mathieu Lacage Date: Sat, 21 Jun 2008 21:07:45 -0700 Subject: [PATCH 038/495] bug 217: another testcase. --- src/common/packet-metadata-test.cc | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/common/packet-metadata-test.cc b/src/common/packet-metadata-test.cc index 7cb1283d5..ee217757a 100644 --- a/src/common/packet-metadata-test.cc +++ b/src/common/packet-metadata-test.cc @@ -759,6 +759,16 @@ PacketMetadataTest::RunTests (void) REM_HEADER (p1, 11); p->AddAtEnd (p1); + p = Create (500); + CHECK_HISTORY (p, 1, 500); + ADD_HEADER (p, 10); + CHECK_HISTORY (p, 2, 10, 500); + REM_HEADER (p, 10); + CHECK_HISTORY (p, 1, 500); + p->RemoveAtEnd (10); + CHECK_HISTORY (p, 1, 490); + + return result; } From c4ea047cb9a46eefc17279a9d7957e98b2dc4b05 Mon Sep 17 00:00:00 2001 From: Mathieu Lacage Date: Sat, 21 Jun 2008 21:08:16 -0700 Subject: [PATCH 039/495] add documentation comment. --- src/common/packet-metadata.h | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/common/packet-metadata.h b/src/common/packet-metadata.h index 6358cb7de..569546727 100644 --- a/src/common/packet-metadata.h +++ b/src/common/packet-metadata.h @@ -137,6 +137,13 @@ public: void AddTrailer (Trailer const &trailer, uint32_t size); void RemoveTrailer (Trailer const &trailer, uint32_t size); + /** + * \param start the amount of stuff to remove from the start + * \param end the amount of stuff to remove from the end + * + * Calling this method is equivalent to calling RemoveAtStart (start) + * and then, RemoveAtEnd (end). + */ PacketMetadata CreateFragment (uint32_t start, uint32_t end) const; void AddAtEnd (PacketMetadata const&o); void AddPaddingAtEnd (uint32_t end); From 14c3cac1d1aae7f24131fe1c14e746e47c1f701e Mon Sep 17 00:00:00 2001 From: Mathieu Lacage Date: Sat, 21 Jun 2008 21:14:28 -0700 Subject: [PATCH 040/495] fix testcase from changeset e367e86d7886 --- src/common/packet-metadata.cc | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/src/common/packet-metadata.cc b/src/common/packet-metadata.cc index 698e01d87..1794d3447 100644 --- a/src/common/packet-metadata.cc +++ b/src/common/packet-metadata.cc @@ -898,18 +898,13 @@ PacketMetadata::RemoveAtEnd (uint32_t end) uint16_t written = fragment.AddBig (fragment.m_head, 0xffff, &item, &extraItem); fragment.UpdateHead (written); - current = item.prev; - while (current != 0xffff) + while (current != 0xffff && current != m_head) { + current = item.prev; ReadItems (current, &item, &extraItem); written = fragment.AddBig (fragment.m_head, 0xffff, &item, &extraItem); fragment.UpdateHead (written); - if (current == m_head) - { - break; - } - current = item.prev; } *this = fragment; } From 2fb03d7aa3b58329550fc00c8a4bc30f945c91d9 Mon Sep 17 00:00:00 2001 From: Mathieu Lacage Date: Sat, 21 Jun 2008 21:20:38 -0700 Subject: [PATCH 041/495] testcase and fix, symmetric to changeset c861a47407a8 --- src/common/packet-metadata-test.cc | 9 +++++++++ src/common/packet-metadata.cc | 9 ++------- 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/src/common/packet-metadata-test.cc b/src/common/packet-metadata-test.cc index ee217757a..f8300c697 100644 --- a/src/common/packet-metadata-test.cc +++ b/src/common/packet-metadata-test.cc @@ -767,6 +767,15 @@ PacketMetadataTest::RunTests (void) CHECK_HISTORY (p, 1, 500); p->RemoveAtEnd (10); CHECK_HISTORY (p, 1, 490); + + p = Create (500); + CHECK_HISTORY (p, 1, 500); + ADD_TRAILER (p, 10); + CHECK_HISTORY (p, 2, 500, 10); + REM_TRAILER (p, 10); + CHECK_HISTORY (p, 1, 500); + p->RemoveAtStart (10); + CHECK_HISTORY (p, 1, 490); return result; diff --git a/src/common/packet-metadata.cc b/src/common/packet-metadata.cc index 1794d3447..85f86b826 100644 --- a/src/common/packet-metadata.cc +++ b/src/common/packet-metadata.cc @@ -830,18 +830,13 @@ PacketMetadata::RemoveAtStart (uint32_t start) uint16_t written = fragment.AddBig (0xffff, fragment.m_tail, &item, &extraItem); fragment.UpdateTail (written); - current = item.next; - while (current != 0xffff) + while (current != 0xffff && current != m_tail) { + current = item.next; ReadItems (current, &item, &extraItem); written = fragment.AddBig (0xffff, fragment.m_tail, &item, &extraItem); fragment.UpdateTail (written); - if (current == m_tail) - { - break; - } - current = item.next; } *this = fragment; } From 4b3b79be2fb51ff5e39935465f62464cd4f6e8d5 Mon Sep 17 00:00:00 2001 From: Mathieu Lacage Date: Mon, 23 Jun 2008 10:21:59 -0700 Subject: [PATCH 042/495] add packet header howto --- doc/howtos/howtos-packet-header.h | 119 ++++++++++++++++++++++++++++++ doc/howtos/howtos.h | 1 + 2 files changed, 120 insertions(+) create mode 100644 doc/howtos/howtos-packet-header.h diff --git a/doc/howtos/howtos-packet-header.h b/doc/howtos/howtos-packet-header.h new file mode 100644 index 000000000..cf442167e --- /dev/null +++ b/doc/howtos/howtos-packet-header.h @@ -0,0 +1,119 @@ +/*! +\page packet-header-trailer How to create a new type of protocol header or trailer +\anchor howtos-packet-header-trailer + +Question: I want to implement a new protocol X which uses a new +type of header Y. How do I implement and use this new header Y in ns-3 ? + +Answer: The key is to implement a new subclass of the ns3::Header +base class to represent your protocol header: +\code +class YHeader : public Header +{ +public: + // must be implemented to become a valid new header. + static TypeId GetTypeId (void); + virtual TypeId GetInstanceTypeId (void) const; + virtual uint32_t GetSerializedSize (void) const; + virtual void Serialize (Buffer::Iterator start) const; + virtual uint32_t Deserialize (Buffer::Iterator start); + virtual void Print (std::ostream &os) const; + + // allow protocol-specific access to the header data. + void SetData (uint32_t data); + uint32_t GetData (void) const; +private: + uint32_t m_data; +}; +\endcode + +Once this class is implemented, you can easily store your protocol +header into a packet: +\code +Ptr p = ...; +YHeader yHeader; +yHeader.SetData (0xdeadbeaf); +// copy the header into the packet +p->AddHeader (yHeader); +\endcode +and get it out of a packet: +\code +Ptr p = ...; +YHeader yHeader; +// copy the header from the packet +p->RemoveHeader (yHeader); +uint32_t data = yHeader.GetData (); +\endcode + +The implementation of the new header is very simple. First, you need +to give a TypeId to your YHeader class: +\code +TypeId +YHeader::GetTypeId (void) +{ + static TypeId tid = TypeId ("YHeader") + .SetParent
() + .AddConstructor () + ; + return tid; +} +TypeId +YHeader::GetInstanceTypeId (void) +{ + return GetTypeId (); +} +\endcode + +Then, you need to allow your header to serialize and deserialize itself +to a byte buffer in its network representation. Here, our new protocol +header contains first a 2-byte constant, and, then, the data field so, +the total size of the header is 2+4=6 bytes. +\code +uint32_t +YHeader::GetSerializedSize (void) const +{ + return 6; +} +void +YHeader::Serialize (Buffer::Iterator start) const +{ + // The 2 byte-constant + start.WriteU8 (0xfe); + start.WriteU8 (0xef); + // The data. + start.WriteHtonU32 (m_data); +} +uint32_t +YHeader::Deserialize (Buffer::Iterator start) +{ + uint8_t tmp; + tmp = start.ReadU8 (); + NS_ASSERT (tmp == 0xfe); + tmp = start.ReadU8 (); + NS_ASSERT (tmp == 0xef); + m_data = start.ReadNtohU32 (); + return 6; // the number of bytes consumed. +} +\endcode + +Finally, to make sure that Packet::Print also prints the content +of your header, just as it prints the content of the other +headers of the system, you need to provide a Print method: +\code +void +YHeader::Print (std::ostream &os) const +{ + os << "data=" << m_data; +} +\endcode + +The code will look the same if you want to implement a trailer, +that is, a protocol data structure which will be appended to the +end of the packet, not its start: you need to make sure that +you derive from the ns3::Trailer base class and that you call +Packet::AddTrailer and Packet::RemoveTrailer. Another important +detail is that you must make sure to rewind the iterator in your +Serialize and Deserialize methods writing to or reading from +the underlying buffer. + +*/ diff --git a/doc/howtos/howtos.h b/doc/howtos/howtos.h index e37546914..5065b60a9 100644 --- a/doc/howtos/howtos.h +++ b/doc/howtos/howtos.h @@ -12,6 +12,7 @@ Please consider contributing tips to either the wiki (yourself) or by submitting a patch to this maintained documentation. - \subpage callbacks +- \subpage packet-header-trailer */ From ae661f53e0483c7285f00c655dbe86b5766fa026 Mon Sep 17 00:00:00 2001 From: Mathieu Lacage Date: Mon, 23 Jun 2008 12:43:54 -0700 Subject: [PATCH 043/495] update doxygen to match the reality of the code --- src/node/node.h | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/node/node.h b/src/node/node.h index 7ffa8e0e7..8a48d1d62 100644 --- a/src/node/node.h +++ b/src/node/node.h @@ -90,9 +90,6 @@ public: * NetDevice. * * Associate this device to this node. - * This method is called automatically from NetDevice::NetDevice - * so the user has little reason to call this method himself. - * The index returned is always non-zero. */ uint32_t AddDevice (Ptr device); /** From 398ffd3d58f3600d149e9677e0b46c04318852d7 Mon Sep 17 00:00:00 2001 From: Mathieu Lacage Date: Mon, 23 Jun 2008 12:44:05 -0700 Subject: [PATCH 044/495] avoid dox warning --- src/node/socket.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/node/socket.h b/src/node/socket.h index d90ce26bf..21f060ca0 100644 --- a/src/node/socket.h +++ b/src/node/socket.h @@ -465,8 +465,6 @@ public: * Calls RecvFrom (maxSize, flags, fromAddress) with maxSize * implicitly set to maximum sized integer, and flags set to zero. * - * \param maxSize reader will accept packet up to maxSize - * \param flags Socket control flags * \param fromAddress output parameter that will return the * address of the sender of the received packet, if any. Remains * untouched if no packet is received. From f1019e402678eb50fd022701ce9c7d7b3c05fd61 Mon Sep 17 00:00:00 2001 From: Mathieu Lacage Date: Mon, 23 Jun 2008 12:44:21 -0700 Subject: [PATCH 045/495] dox missing SetNode method --- src/node/net-device.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/node/net-device.h b/src/node/net-device.h index 67fc73982..3e5af9e36 100644 --- a/src/node/net-device.h +++ b/src/node/net-device.h @@ -225,6 +225,11 @@ public: */ virtual Ptr GetNode (void) const = 0; + /** + * \param node the node associated to this netdevice. + * + * This method is called from ns3::Node::AddDevice. + */ virtual void SetNode (Ptr node) = 0; /** From daaed2d5e6497a1f908dca8bdf668d54a9c0ceca Mon Sep 17 00:00:00 2001 From: Mathieu Lacage Date: Mon, 23 Jun 2008 12:44:45 -0700 Subject: [PATCH 046/495] add small comment, fix typo, add missing copyright statement --- src/node/simple-channel.h | 27 +++++++++++++++++++++++---- 1 file changed, 23 insertions(+), 4 deletions(-) diff --git a/src/node/simple-channel.h b/src/node/simple-channel.h index 4680e54ca..b75383f80 100644 --- a/src/node/simple-channel.h +++ b/src/node/simple-channel.h @@ -1,5 +1,24 @@ -#ifndef TEST_CHANNEL_H -#define TEST_CHANNEL_H +/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ +/* + * Copyright (c) 2008 INRIA + * + * 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 + * + * Author: Mathieu Lacage + */ +#ifndef SIMPLE_CHANNEL_H +#define SIMPLE_CHANNEL_H #include "channel.h" #include "mac48-address.h" @@ -25,14 +44,14 @@ public: void Add (Ptr device); + // inherited from ns3::Channel virtual uint32_t GetNDevices (void) const; virtual Ptr GetDevice (uint32_t i) const; private: - std::vector > m_devices; }; } // namespace ns3 -#endif /* TEST_CHANNEL_H */ +#endif /* SIMPLE_CHANNEL_H */ From e10db3d576ee4e8d8bd783e9a8a72e053446b6e9 Mon Sep 17 00:00:00 2001 From: Mathieu Lacage Date: Mon, 23 Jun 2008 12:45:01 -0700 Subject: [PATCH 047/495] add missing copyright statement --- src/node/simple-channel.cc | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/src/node/simple-channel.cc b/src/node/simple-channel.cc index 642780370..d10f6a21a 100644 --- a/src/node/simple-channel.cc +++ b/src/node/simple-channel.cc @@ -1,3 +1,22 @@ +/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ +/* + * Copyright (c) 2008 INRIA + * + * 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 + * + * Author: Mathieu Lacage + */ #include "simple-channel.h" #include "simple-net-device.h" #include "ns3/packet.h" From 73f7efb2f2c01e8b5f2daa31e7cea187ba216b08 Mon Sep 17 00:00:00 2001 From: Mathieu Lacage Date: Mon, 23 Jun 2008 12:49:51 -0700 Subject: [PATCH 048/495] a very simple howto for implementing NetDevice/Channel subclasses --- doc/howtos/howtos-net-device.h | 93 ++++++++++++++++++++++++++++++++++ doc/howtos/howtos.h | 1 + 2 files changed, 94 insertions(+) create mode 100644 doc/howtos/howtos-net-device.h diff --git a/doc/howtos/howtos-net-device.h b/doc/howtos/howtos-net-device.h new file mode 100644 index 000000000..acd1568fc --- /dev/null +++ b/doc/howtos/howtos-net-device.h @@ -0,0 +1,93 @@ +/*! + \page net-device How to create a new OSI layer 1 + 2 implementation ? + \anchor howtos-net-device + + Question: How do I integrate a new OSI layer 1 + 2 implementation ? + + Answer: The OSI layers 1 and 2 are represented by the ns3::NetDevice + and ns3::Channel classes. To plug transparently in ns-3, a new layer 1+2 model + thus simply needs to provide two new subclasses of these two base classes. + + To make that subclassing process easy, two skeleton classes are provided in + the src/node directory: simple-net-device.h (ns3::SimpleNetDevice) and + simple-channel.h (ns3::SimpleChannel) implement a broadcast passthru medium + using 48bit MAC addresses without any kind of MAC access algorithm or PHY + layer modeling. + + The ns3::SimpleChannel class is really very simple: it provides + an implementation for the ns3::Channel::GetNDevices and ns3::Channel::GetDevice + methods defined in the Channel base class and, then defines the channel-specific + send and add methods: +- The Add method is used by SimpleNetDevice::SetChannel to register a new + SimpleNetDevice with its associated channel. +- The Send method is used by SimpleNetDevice::Send to send a packet over the + broadcast medium and ensure that it gets delivered to all associated devices + (except the sender). + +\code +class SimpleChannel : public Channel +{ +public: + static TypeId GetTypeId (void); + SimpleChannel (); + + void Send (Ptr p, uint16_t protocol, Mac48Address to, Mac48Address from, + Ptr sender); + + void Add (Ptr device); + + // inherited from ns3::Channel + virtual uint32_t GetNDevices (void) const; + virtual Ptr GetDevice (uint32_t i) const; + +private: + std::vector > m_devices; +}; +\endcode + +The SimpleNetDevice class is also trivial since it implements no special +MAC-layer processing: +\code +class SimpleNetDevice : public NetDevice +{ +public: + static TypeId GetTypeId (void); + SimpleNetDevice (); + + void Receive (Ptr packet, uint16_t protocol, Mac48Address to, Mac48Address from); + void SetChannel (Ptr channel); + void SetAddress (Mac48Address address); + + // inherited from NetDevice base class. + virtual void SetName(const std::string name); + ... +}; +\endcode + +The code below illustrates how the three model-specific methods defined above are +implemented: + +\code +void +SimpleNetDevice::Receive (Ptr packet, uint16_t protocol, + Mac48Address to, Mac48Address from) +{ + if (to == m_address || to == Mac48Address::GetBroadcast ()) + { + m_rxCallback (this, packet, protocol, from); + } +} +void +SimpleNetDevice::SetChannel (Ptr channel) +{ + m_channel = channel; + m_channel->Add (this); +} +void +SimpleNetDevice::SetAddress (Mac48Address address) +{ + m_address = address; +} +\endcode + +*/ diff --git a/doc/howtos/howtos.h b/doc/howtos/howtos.h index 5065b60a9..2e84cd8e6 100644 --- a/doc/howtos/howtos.h +++ b/doc/howtos/howtos.h @@ -11,6 +11,7 @@ for ns-3. This complements the following wiki pages: Please consider contributing tips to either the wiki (yourself) or by submitting a patch to this maintained documentation. +- \subpage net-device - \subpage callbacks - \subpage packet-header-trailer From 3aa9ce9efdfb044d63ae200095f233ad17c65af2 Mon Sep 17 00:00:00 2001 From: Tom Henderson Date: Mon, 23 Jun 2008 13:58:30 -0700 Subject: [PATCH 049/495] Add chapter on random numbers to manual --- doc/manual/attributes.texi | 4 +- doc/manual/callbacks.texi | 4 +- doc/manual/manual.texi | 23 +-- doc/manual/packets.texi | 4 +- doc/manual/random.texi | 304 +++++++++++++++++++++++++++++++++++++ doc/manual/routing.texi | 4 +- 6 files changed, 326 insertions(+), 17 deletions(-) create mode 100644 doc/manual/random.texi diff --git a/doc/manual/attributes.texi b/doc/manual/attributes.texi index 192d6a8fe..df25e24a4 100644 --- a/doc/manual/attributes.texi +++ b/doc/manual/attributes.texi @@ -1,5 +1,5 @@ -@node ns-3 Attributes -@chapter ns-3 Attributes +@node Attributes +@chapter Attributes @anchor{chap:Attributes} In ns-3 simulations, there are two main aspects to configuration: diff --git a/doc/manual/callbacks.texi b/doc/manual/callbacks.texi index 377689975..38a4f07a6 100644 --- a/doc/manual/callbacks.texi +++ b/doc/manual/callbacks.texi @@ -1,5 +1,5 @@ -@node ns-3 Callbacks -@chapter ns-3 Callbacks +@node Callbacks +@chapter Callbacks Some new users to @command{ns-3} are unfamiliar with an extensively used programming idiom used throughout the code: the ``ns-3 callback''. This diff --git a/doc/manual/manual.texi b/doc/manual/manual.texi index cff215fcd..cbffee08b 100644 --- a/doc/manual/manual.texi +++ b/doc/manual/manual.texi @@ -7,7 +7,7 @@ @ifinfo Primary documentation for the @command{ns-3} project is available in -three forms: +four forms: @itemize @bullet @item @uref{http://www.nsnam.org/doxygen/index.html,,ns-3 Doxygen/Manual}: Documentation of the public APIs of the simulator @item @uref{http://www.nsnam.org/tutorial/index.html,,ns-3 Tutorial} @@ -23,12 +23,13 @@ the document should be discussed on the ns-developers@@isi.edu mailing list. @copying -This is an @command{ns-3} manual. +This is an @command{ns-3} reference manual. Primary documentation for the @command{ns-3} project is available in -three forms: +four forms: @itemize @bullet -@item @uref{http://www.nsnam.org/doxygen/index.html,,ns-3 Doxygen/Manual}: Documentation of the public APIs of the simulator -@item Manual (this document) +@item @uref{http://www.nsnam.org/tutorial/index.html,,ns-3 Tutorial} +@item @uref{http://www.nsnam.org/doxygen/index.html,,ns-3 Doxygen}: Documentation of the public APIs of the simulator +@item Reference Manual (this document) @item @uref{http://www.nsnam.org/wiki/index.php,, ns-3 wiki} @end itemize @@ -77,15 +78,19 @@ see @uref{http://www.nsnam.org/docs/manual.pdf}. @end ifnottex @menu -* ns-3 Packets:: -* ns-3 Callbacks:: +* Random variables:: +* Callbacks:: +* Attributes:: +* Packets:: * Sockets APIs:: -* ns-3 routing overview:: +* Routing overview:: * Troubleshooting @end menu -@include packets.texi +@include random.texi @include callbacks.texi +@include attributes.texi +@include packets.texi @include sockets.texi @c @include output.texi @include routing.texi diff --git a/doc/manual/packets.texi b/doc/manual/packets.texi index cc00e0094..b4cc4e3b8 100644 --- a/doc/manual/packets.texi +++ b/doc/manual/packets.texi @@ -1,5 +1,5 @@ -@node ns-3 Packets -@chapter ns-3 Packets +@node Packets +@chapter Packets The design of the Packet framework of @emph{ns} was heavily guided by a few important use-cases: diff --git a/doc/manual/random.texi b/doc/manual/random.texi new file mode 100644 index 000000000..c350bdaf8 --- /dev/null +++ b/doc/manual/random.texi @@ -0,0 +1,304 @@ +@anchor{chap:rv} +@node Random variables +@chapter Random variables + +ns-3 contains a built-in pseudo-random number generator (PRNG). +It is important for serious users of the simulator to understand +the functionality, configuration, and usage of this PRNG, and +to decide whether it is sufficient for his or her research use. + +@node Quick Overview +@section Quick Overview + +ns-3 random numbers are provided via instances of @code{class RandomVariable}. +@itemize @bullet +@item @strong{by default, ns-3 simulations use a random seed}; if there is any +randomness in the simulation, each run of the program will yield different results. To use a fixed seed, users must call +@code{RandomVariable::UseGlobalSeed ()} at the beginning of the program; +see section @xref{Seeding and independent replications} +@item each RandomVariable used in ns-3 has a virtual random number +generator associated with it; all random variables use either a fixed +or random seed based on the use of the global seed (previous bullet); +@item if you intend to perform multiple runs of the same scenario, with +different random numbers, please be sure to read the section on how to +perform independent replications: @xref{Seeding and independent replications}. +@end itemize + +Read further for more explanation about the random number facility for +ns-3. + +@node Background +@section Background + +Simulations use a lot of random numbers; the study in [cite] +found that most network simulations spend as much as 50% +of the CPU generating random numbers. Simulation users need +to be concerned with the quality of the (pseudo) random numbers and +the independence between different streams of random numbers. + +Users need to be concerned with a few issues, such as: +@itemize @bullet +@item the seeding of the random number generator and whether a +simulation run is deterministic or not, +@item how to acquire different streams of random numbers that are +independent from one another, and +@item how long it takes for streams to cycle +@end itemize + +We will introduce a few terms here: a RNG provides a long sequence +of (pseudo) random numbers. +The length of this sequence is called the @emph{cycle length} +or @emph{period}, after which the RNG will repeat itself. +This sequence can +be partitioned into disjoint @emph{streams}. A stream of a +RNG is a contiguous subset or block of the RNG sequence. +For instance, if the +RNG period is of length N, and two streams are provided from this +RNG, then +the first stream might use the first N/2 values and the second +stream might produce the second N/2 values. An important property +here is that the two streams are uncorrelated. Likewise, each +stream can be partitioned disjointly to a number of +uncorrelated @emph{substreams}. The underlying RNG hopefully +produces a pseudo-random sequence of numbers with a very long +cycle length, and partitions this into streams and substreams in an +efficient manner. + +ns-3 uses the same underlying random number generator as does +ns-2: the MRG32k3a generator from Pierre L'Ecuyer. A +detailed description can be found in +@uref{http://www.iro.umontreal.ca/~lecuyer/myftp/papers/streams00.pdf,,}. +The MRG32k3a generator provides 1.8x10^19 independent +streams of random numbers, each of which consists of +2.3x10^15 substreams. Each substream has a period +(@emph{i.e.}, the number of random numbers before overlap) of +7.6x10^22. The period of the entire generator is +3.1x10^57. Figure ref-streams provides a graphical idea of +how the streams and substreams fit together. + +Class @code{ns3::RandomVariable} is the public interface to this +underlying random number generator. When users create new +RandomVariables (such as UniformVariable, ExponentialVariable, +etc.), they create an object that uses one of the distinct, independent +streams of the random number generator. Therefore, each +object of type RandomVariable has, conceptually, its own "virtual" RNG. +Furthermore, each RandomVariable can be configured to use +one of the set of substreams drawn from the main stream. + +An alternate implementation would be to allow each RandomVariable +to have its own (differently seeded) RNG. However, we cannot +guarantee as strongly that the different sequences would be +uncorrelated in such a case; hence, we prefer to use a single RNG +and streams and substreams from it. + +@anchor{chap:rv:indeprep} +@node Seeding and independent replications +@section Seeding and independent replications + +ns-3 simulations can be configured to produce deterministic or +random results. If the ns-3 simulation is configured to use +a fixed, deterministic seed with the same run number, it should give +the same output each time it is run. + +By default, ns-3 simulations use random seeds where the seeding +is drawn from @code{/dev/random} (if it is available) or else from +the time of day. A user who wants to fix the initial seeding +of the PRNG must call the following static method during simulation +configuration: +@verbatim +RandomVariable::UseGlobalSeed (uint32_t s0, s1, s2, s3, s4, s5); +@end verbatim +where the six parameters are each of type uint32_t. + +A typical use case is to run a simulation as a sequence of independent +trials, so as to compute statistics on a large number of independent +runs. The user can either change the global seed and rerun the +simulation, or can advance the substream state of the RNG. +This seeding and substream state setting must be called before any +random variables are created; e.g. + +@verbatim + RandomVariable::UseGlobalSeed(1,2,3,4,5,6); + int N = atol(argv[1]); //read in run number from command line + RandomVariable::SetRunNumber(N); + // Now, create random variables + UniformVariable x(0,10); + ExponentialVariable y(2902); + ... +@end verbatim + +Which is better, setting a new seed or advancing the substream state? +There is no guarantee that the streams +produced by two random seeds will not overlap. The only way to +guarantee that two streams do not overlap is to use the substream +capability provided by the RNG implementation. +@strong{Therefore, use the substream capability to produce +multiple independent runs of the same simulation.} +In other words, the more statistically rigorous way to configure +multiple independent replications is not to simply ignore the +seeding (and use /dev/random to seed the generator each time) but +instead to use a fixed seed and to iterate the run number. +This implementation allows for a maximum of +2.3x10^15 independent replications using the substreams. + +@node class RandomVariable +@section class RandomVariable + +All random variables should derive from @code{class RandomVariable}. +This base class provides a few static methods for globally configuring +the behavior of the random number generator. Derived classes +provide API for drawing random variates from the particular +distribution being supported. + +Each RandomVariable created in the simulation is given a generator +that is a new RNGStream from the underlying PRNG. +Used in this manner, the L'Ecuyer implementation allows for a maximum of +1.8x10^19 random variables. Each random variable in +a single replication can produce up to 7.6x10^22 random +numbers before overlapping. + +@node Base class public API +@section Base class public API + +Below are excerpted a few public methods of @code{class RandomVariable} +that deal with the global configuration and state of the RNG. +@verbatim + /** + * \brief Set seeding behavior + * + * Specify whether the POSIX device /dev/random is to + * be used for seeding. When this is used, the underlying + * generator is seeded with data from /dev/random instead of + * being seeded based upon the time of day. Defaults to true. + */ + static void UseDevRandom(bool udr = true); + + /** + * \brief Use the global seed to force precisely reproducible results. + */ + static void UseGlobalSeed(uint32_t s0, uint32_t s1, uint32_t s2, + uint32_t s3, uint32_t s4, uint32_t s5); + + /** + * \brief Set the run number of this simulation + */ + static void SetRunNumber(uint32_t n); + + /** + * \brief Get the internal state of the RNG + * + * This function is for power users who understand the inner workings + * of the underlying RngStream method used. It returns the internal + * state of the RNG via the input parameter. + * \param seed Output parameter; gets overwritten with the internal state + * of the RNG. + */ + void GetSeed(uint32_t seed[6]) const; +@end verbatim + +We have already described the seeding configuration above. + +@node Types of RandomVariables +@section Types of RandomVariables + +The following types of random variables are provided, and are documented +in the ns-3 Doxygen or by reading @code{src/core/random-variable.h}. Users +can also create their own custom random variables by deriving from +class RandomVariable. +@itemize @bullet +@item @code{class UniformVariable } +@item @code{class ConstantVariable } +@item @code{class SequentialVariable } +@item @code{class ExponentialVariable } +@item @code{class ParetoVariable } +@item @code{class WeibullVariable } +@item @code{class NormalVariable } +@item @code{class EmpiricalVariable } +@item @code{class IntEmpiricalVariable } +@item @code{class DeterministicVariable } +@item @code{class LogNormalVariable } +@item @code{class TriangularVariable } +@end itemize + +@node Semantics of RandomVariable objects +@section Semantics of RandomVariable objects + +RandomVariable objects have value semantics. This means that they +can be passed by value to functions. The can also be passed by +reference to const. RandomVariables do not derive from +@code{ns3::Object} and we do not use smart pointers to manage them; +they are either allocated on the stack or else users explicitly manage +any heap-allocated RandomVariables. + +RandomVariable objects can also be used in ns-3 attributes, which means +that values can be set for them through the ns-3 attribute system. +An example is in the propagation models for WifiNetDevice: +@verbatim +TypeId +RandomPropagationDelayModel::GetTypeId (void) +{ + static TypeId tid = TypeId ("ns3::RandomPropagationDelayModel") + .SetParent () + .AddConstructor () + .AddAttribute ("Variable", + "The random variable which generates random delays (s).", + RandomVariableValue (UniformVariable (0.0, 1.0)), + MakeRandomVariableAccessor (&RandomPropagationDelayModel::m_variable), + MakeRandomVariableChecker ()) + ; + return tid; +} +@end verbatim +Here, the ns-3 user can change the default random variable for this +delay model (which is a UniformVariable ranging from 0 to 1) through +the attribute system. + +@node Using other PRNG +@section Using other PRNG + +There is presently no support for substituting a different underlying +random number generator (e.g., the GNU Scientific Library or the Akaroa +package). Patches are welcome. + +@node More advanced usage +@section More advanced usage + +@emph{To be completed} + +@node Publishing your results +@section Publishing your results + +When you publish simulation results, a key piece of configuration +information that you should always state is how you used the +the random number generator. +@itemize @bullet +@item what seeds you used, +@item what RNG you used if not the default, +@item how were independent runs performed, +@item for large simulations, how did you check that you did not cycle. +@end itemize + +It is incumbent on the researcher publishing results to include enough +information to allow others to reproduce his or her results. It is +also incumbent on the researcher to convince oneself that the random +numbers used were statistically valid, and to state in the paper why +such confidence is assumed. + +@node Summary +@section Summary + +Let's review what things you should do when creating a simulation. + +@itemize @bullet +@item Decide whether you are running with a fixed seed or random seed; +a random seed is the default, +@item Decide how you are going to manage independent replications, if +applicable, +@item Convince yourself that you are not drawing more random values +than the cycle length, if you are running a long simulation, and +@item When you publish, follow the guidelines above about documenting your +use of the random number generator. +@end itemize + +The program @emph{samples/main-random.cc} has some examples of usage. + diff --git a/doc/manual/routing.texi b/doc/manual/routing.texi index d8250ee24..dbd054f7a 100644 --- a/doc/manual/routing.texi +++ b/doc/manual/routing.texi @@ -1,5 +1,5 @@ -@node ns-3 routing overview -@chapter ns-3 routing overview +@node Routing overview +@chapter Routing overview This chapter describes the overall design of routing in the @code{src/internet-stack} From bdf0896c2a7e272dcc79596ecfd76954aad55929 Mon Sep 17 00:00:00 2001 From: Mathieu Lacage Date: Mon, 23 Jun 2008 14:15:41 -0700 Subject: [PATCH 050/495] add helper code --- doc/howtos/howtos-net-device.h | 69 ++++++++++++++++++++++++++++++++++ 1 file changed, 69 insertions(+) diff --git a/doc/howtos/howtos-net-device.h b/doc/howtos/howtos-net-device.h index acd1568fc..00bb016e1 100644 --- a/doc/howtos/howtos-net-device.h +++ b/doc/howtos/howtos-net-device.h @@ -90,4 +90,73 @@ SimpleNetDevice::SetAddress (Mac48Address address) } \endcode +Building a topology with such a device is then a matter of +instanciating a set of SimpleNetDevice objects connected on a shared +SimpleChannel: +\code +NodeContainer nodes; +nodes.Create (10); +Ptr channel = CreateObject (); +for (uint32_t i = 0; i < nodes.GetN (); ++i) + { + CreateSimpleDevice (nodes.Get (i), channel); + } +\endcode + +With the following CreateSimpleDevice function: +\code +static Ptr +CreateSimpleDevice (Ptr node, Ptr channel) +{ + Ptr device = CreateObject (); + device->SetAddress (Mac48Address:Allocate ()); + device->SetChannel (channel); + node->AddDevice (device); + return device; +} +\endcode + +Of course, ultimately, you need to provide a helper class for this new device and channel +to save each user from having to re-implement their own CreateSimpleDevice helper +function: + +\code +class SimpleHelper +{ +public: + NetDeviceContainer Install (NodeContainer nodes, Ptr channel); + NetDeviceContainer Install (NodeContainer nodes); +}; +\endcode + +with the following straightforward implementation, inspired by the CreateSimpleDevice +function defined above: + +\code +NetDeviceContainer +SimpleHelper::Install (NodeContainer nodes, Ptr channel) +{ + NetDeviceContainer devices; + for (NodeContainer::Iterator i = nodes.Begin (); i != nodes.End (); ++i) + { + Ptr dev = CreateObject (); + dev->SetAddress (Mac48Address::Allocate ()); + dev->SetChannel (channel); + (*i)->AddDevice (dev); + devices.Add (dev); + } + return devices; +} +NetDeviceContainer +SimpleHelper::Install (NodeContainer nodes) +{ + return Install (nodes, CreateObject ()); +} +\endcode + +Of course, at some point, this device helper class should also contain a couple of +ascii and pcap tracing helper functions but, since the default SimpleNetDevice +class we used as an example here does not report any trace event, it would +be of little use. + */ From fcf9b4cf5b8aaa5c0d05995f2e6f772868d47d67 Mon Sep 17 00:00:00 2001 From: Mathieu Lacage Date: Mon, 23 Jun 2008 15:24:12 -0700 Subject: [PATCH 051/495] application howto --- doc/howtos/howtos-application.h | 203 ++++++++++++++++++++++++++++++++ doc/howtos/howtos.h | 3 +- 2 files changed, 205 insertions(+), 1 deletion(-) create mode 100644 doc/howtos/howtos-application.h diff --git a/doc/howtos/howtos-application.h b/doc/howtos/howtos-application.h new file mode 100644 index 000000000..33ba848c3 --- /dev/null +++ b/doc/howtos/howtos-application.h @@ -0,0 +1,203 @@ +/*! + \page application How to create a traffic generator ? + \anchor howtos-application + + Question: How do I create a new traffic generator ? + + Answer: It is possible to instanciate \ref ns3::Packet "Packet" + objects, schedule events, and call functions from any piece of code + in ns-3 so, technically, there is no single answer to the question of + how we can write a new traffic generator. However, the + \ref ns3::Socket "Socket" API was really designed to be the single + point of entry for traffic generators or traffic analysers and the + \ref ns3::Application "Application" class was designed to hold + together any number of sockets. + + Implementing a new traffic generator thus boils down to: +- implementing a new subclass of the \ref ns3::Application "Application" + base class +- instanciate one or many sockets within that application +- start scheduling events when \ref ns3::Application::StartApplication "StartApplication" + is called +- stop scheduling events when \ref ns3::Application::StopApplication "StopApplication" + is called +- create packets and send them over one or many sockets in each event + +The following "random" generator generates packets separated by a random +delay and with a random size. + +\code +class RandomGenerator : public Application +{ +public: + RandomGenerator (); + void SetDelay (RandomVariable delay); + void SetSize (RandomVariable size); + void SetRemote (std::string socketType, + Address remote); +private: + virtual void StartApplication (void); + virtual void StopApplication (void); + void DoGenerate (void); + + RandomVariable m_delay; + RandomVariable m_size; + Ptr m_socket; +}; +\endcode + +The socket is created in the SetRemote method: +\code +void +RandomGenerator::SetRemote (std::string socketType, + Address remote) +{ + TypeId tid = TypeId::LookupByName (socketType); + m_socket = Socket::CreateSocket (GetNode (), tid); + m_socket->Bind (); + m_socket->ShutdownRecv (); + m_socket->Connect (remote); +} +\endcode +While the the crux of the logic is located in the DoGenerate method +which is called from within StartApplication: +\code +void +RandomGenerator::DoGenerate (void) +{ + m_next = Simulator::Schedule (Seconds (m_delay.GetValue ()), + &RandomGenerator::DoGenerate, this); + Ptr p = Create (m_size.GetIntValue ()); + m_socket->Send (p); +} +\endcode + +To make that application more integrated in ns-3, it needs an associated +helper class: +\code +class RandomAppHelper +{ +public: + RandomAppHelper (std::string protocol, Address remote); + void SetPacketSize (RandomVariable packetSize); + void SetDelay (RandomVariable delay); + ApplicationContainer Install (NodeContainer nodes); +private: + std::string m_protocol; + Address m_remote; + RandomVariable m_packetSize; + RandomVariable m_delay; +}; +\endcode + +which could be trivially implemented as: +\code +ApplicationContainer +RandomAppHelper::Install (NodeContainer nodes) +{ + ApplicationContainer applications; + for (NodeContainer::Iterator i = nodes.Begin (); i != nodes.End (); ++i) + { + Ptr app = CreateObject (); + app->SetSize (m_packetSize); + app->SetDelay (m_delay); + app->SetRemote (m_protocol, m_remote); + (*i)->AddApplication (app); + applications.Add (app); + } + return applications; +} +\endcode + +Despite being functional, this API is not very consistant with the style of +the other helper classes, all of which allow you to control the parameters +of the underlying class through attributes and not explicit setters. The +following API thus replaces the pair SetPacketSize/SetDelay with a single +method SetAttribute: +\code +class RandomAppHelper +{ +public: + RandomAppHelper (std::string protocol, Address remote); + void SetAttribute (std::string name, const AttributeValue &value); + ApplicationContainer Install (NodeContainer c); +private: + std::string m_protocol; + Address m_remote; + ObjectFactory m_factory; +}; +\endcode + +And which can be used as follows: +\code +RandomAppHelper app = RandomAppHelper ("ns3::TcpSocketFactory", + InetSocketAddress (Ipv4Address ("192.168.1.10"), 10)); +app.SetAttribute ("Delay", StringValue ("Constant:2.5")); +app.SetAttribute ("Size", StringValue ("Constant:2100")); +app.Install (nodes); +\endcode + +The implementation, in this case, is not necessarily longer but its +simplicity hides a lot of behind-the-scenes complexity: + +\code +void +RandomAppHelper::SetAttribute (std::string name, const AttributeValue &value) +{ + m_factory.Set (name, value); +} +ApplicationContainer +RandomAppHelper::Install (NodeContainer nodes) +{ + ApplicationContainer applications; + for (NodeContainer::Iterator i = nodes.Begin (); i != nodes.End (); ++i) + { + Ptr app = m_factory.Create (); + app->SetRemote (m_socketType, m_remote); + (*i)->AddApplication (app); + applications.Add (app); + } + return applications; +} +\endcode + +The key difference between this implementation and the previous one +is that this helper does not handle explicitely the attributes +delay and packet size. Instead, it stores them in an +\ref ns3::ObjectFactory "ObjectFactory" object. This, of course, +does not work magically, and requires extra support from the +underlying RandomGenerator class. Specifically, it requires +that the underlying RandomGenerator defines its attributes +in its \ref ns3::TypeId "TypeId" in a new public static method: + +\code +class RandomGenerator +{ +public: + static TypeId GetTypeId (void); +}; +\endcode + +The corresponding implementation is shown below: + +\code +TypeId +RandomGenerator::GetTypeId (void) +{ + static TypeId tid = TypeId ("RandomGenerator") + .SetParent () + .AddConstructor () + .AddAttribute ("Delay", "The delay between two packets (s)", + RandomVariableValue (ConstantVariable (1.0)), + MakeRandomVariableAccessor (&RandomGenerator::m_delay), + MakeRandomVariableChecker ()) + .AddAttribute ("PacketSize", "The size of each packet (bytes)", + RandomVariableValue (ConstantVariable (2000)), + MakeRandomVariableAccessor (&RandomGenerator::m_size), + MakeRandomVariableChecker ()) + ; + return tid; +} +\endcode + +*/ diff --git a/doc/howtos/howtos.h b/doc/howtos/howtos.h index 2e84cd8e6..199b0d1b9 100644 --- a/doc/howtos/howtos.h +++ b/doc/howtos/howtos.h @@ -11,9 +11,10 @@ for ns-3. This complements the following wiki pages: Please consider contributing tips to either the wiki (yourself) or by submitting a patch to this maintained documentation. -- \subpage net-device - \subpage callbacks - \subpage packet-header-trailer +- \subpage net-device +- \subpage application */ From 77d2f50c2f54b0cba735785730e421c151860a61 Mon Sep 17 00:00:00 2001 From: Mathieu Lacage Date: Mon, 23 Jun 2008 15:45:52 -0700 Subject: [PATCH 052/495] update ignore list --- .hgignore | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/.hgignore b/.hgignore index 340172127..37ab5d22a 100644 --- a/.hgignore +++ b/.hgignore @@ -11,3 +11,18 @@ ^doc/introspected-doxygen\.h$ .*\.py[co]$ \.pcap$ +^doc/manual/manual/ +doc/manual/manual.aux +doc/manual/manual.cp +doc/manual/manual.fn +doc/manual/manual.html +doc/manual/manual.ky +doc/manual/manual.log +doc/manual/manual.pdf +doc/manual/manual.pg +doc/manual/manual.toc +doc/manual/manual.tp +doc/manual/manual.vr +^doc/manual/figures/.*eps +^doc/manual/figures/.*pdf +^doc/manual/figures/.*png From 87c68d5a5855c8f5aa5a15d09ee4efa819e6d278 Mon Sep 17 00:00:00 2001 From: Mathieu Lacage Date: Mon, 23 Jun 2008 15:46:04 -0700 Subject: [PATCH 053/495] fix lots of typos --- doc/manual/attributes.texi | 57 +++++++++++++++++++++----------------- 1 file changed, 31 insertions(+), 26 deletions(-) diff --git a/doc/manual/attributes.texi b/doc/manual/attributes.texi index df25e24a4..60eb075af 100644 --- a/doc/manual/attributes.texi +++ b/doc/manual/attributes.texi @@ -125,12 +125,13 @@ Node::GetTypeId (void) { static TypeId tid = TypeId ("ns3::Node") .SetParent () + ; return tid; } @end verbatim Finally, when users want to create Nodes, they call: @verbatim - Ptr n = CreateObject n; + Ptr n = CreateObject (); @end verbatim We next discuss how attributes (values associated with member variables @@ -208,8 +209,9 @@ TypeId DropTailQueue::GetTypeId (void) static TypeId tid = TypeId ("ns3::DropTailQueue") .SetParent () .AddConstructor () - .AddAttribute ("MaxPackets", "The maximum number of packets accepted by this DropTailQueue.", - Uinteger (100), + .AddAttribute ("MaxPackets", + "The maximum number of packets accepted by this DropTailQueue.", + UintegerValue (100), MakeUintegerAccessor (&DropTailQueue::m_maxPackets), MakeUintegerChecker ()) ; @@ -256,9 +258,9 @@ main (int argc, char *argv[]) // // Here, we set it to 80 packets. We could use one of two value types: // a string-based value or a Uinteger value - Config::SetDefault ("ns3::DropTailQueue::MaxPackets", String ("80")); + Config::SetDefault ("ns3::DropTailQueue::MaxPackets", StringValue ("80")); // The below function call is redundant - Config::SetDefault ("ns3::DropTailQueue::MaxPackets", Uinteger(80)); + Config::SetDefault ("ns3::DropTailQueue::MaxPackets", UintegerValue (80)); // Allow the user to override any of the defaults and the above // SetDefaults() at run-time, via command-line arguments @@ -306,24 +308,27 @@ First, we observe that we can get a pointer to the (base class) queue via the PointToPointNetDevice attributes, where it is called TxQueue @verbatim - Ptr txQueue = net0->GetAttribute ("TxQueue"); + PointerValue tmp; + net0->GetAttribute ("TxQueue", tmp); + Ptr txQueue = tmp.GetObject (); @end verbatim Using the GetObject function, we can perform a safe downcast to a DropTailQueue, where MaxPackets is a member @verbatim Ptr dtq = txQueue->GetObject (); - NS_ASSERT (dtq); + NS_ASSERT (dtq != 0); @end verbatim -Next, we can get the value of an attribute on this queue +Next, we can get the value of an attribute on this queue. We have introduced wrapper "Value" classes for the underlying data types, similar to Java wrappers around these types, since the attribute system stores values and not disparate types. -Here, the attribute value is assigned to a Uinteger, and +Here, the attribute value is assigned to a UintegerValue, and the Get() method on this value produces the (unwrapped) uint32_t. @verbatim - Uinteger limit = dtq->GetAttribute ("MaxPackets"); + UintegerValue limit; + dtq->GetAttribute ("MaxPackets", limit); NS_LOG_INFO ("1. dtq limit: " << limit.Get () << " packets"); @end verbatim @@ -331,14 +336,14 @@ Note that the above downcast is not really needed; we could have done the same using the Ptr even though the attribute is a member of the subclass @verbatim - limit = txQueue->GetAttribute ("MaxPackets"); + txQueue->GetAttribute ("MaxPackets", limit); NS_LOG_INFO ("2. txQueue limit: " << limit.Get () << " packets"); @end verbatim Now, let's set it to another value (60 packets) @verbatim - txQueue->SetAttribute("MaxPackets", Uinteger (60)); - limit = txQueue->GetAttribute ("MaxPackets"); + txQueue->SetAttribute("MaxPackets", UintegerValue (60)); + txQueue->GetAttribute ("MaxPackets", limit); NS_LOG_INFO ("3. txQueue limit changed: " << limit.Get () << " packets"); @end verbatim @@ -350,8 +355,8 @@ namespace; this approach is useful if one doesn't have access to the underlying pointers and would like to configure a specific attribute with a single statement. @verbatim - Config::Set ("/NodeList/0/DeviceList/0/TxQueue/MaxPackets", Uinteger (25)); - limit = txQueue->GetAttribute ("MaxPackets"); + Config::Set ("/NodeList/0/DeviceList/0/TxQueue/MaxPackets", UintegerValue (25)); + txQueue->GetAttribute ("MaxPackets", limit); NS_LOG_INFO ("4. txQueue limit changed through namespace: " << limit.Get () << " packets"); @end verbatim @@ -360,8 +365,8 @@ We could have also used wildcards to set this value for all nodes and all net devices (which in this simple example has the same effect as the previous Set()) @verbatim - Config::Set ("/NodeList/*/DeviceList/*/TxQueue/MaxPackets", Uinteger (15)); - limit = txQueue->GetAttribute ("MaxPackets"); + Config::Set ("/NodeList/*/DeviceList/*/TxQueue/MaxPackets", UintegerValue (15)); + txQueue->GetAttribute ("MaxPackets", limit); NS_LOG_INFO ("5. txQueue limit changed through wildcarded namespace: " << limit.Get () << " packets"); @end verbatim @@ -377,12 +382,12 @@ Ptr p = CreateObject ("n1", v1, "n2", v2, ...); or from the higher-level helper APIs, such as: @verbatim mobility.SetPositionAllocator ("GridPositionAllocator", - "MinX", FpValue (-100.0), - "MinY", FpValue (-100.0), - "DeltaX", FpValue (5.0), - "DeltaY", FpValue (20.0), - "GridWidth", UintValue (20), - "LayoutType", "RowFirst"); + "MinX", DoubleValue (-100.0), + "MinY", DoubleValue (-100.0), + "DeltaX", DoubleValue (5.0), + "DeltaY", DoubleValue (20.0), + "GridWidth", UintegerValue (20), + "LayoutType", StringValue ("RowFirst")); @end verbatim @node Value classes @@ -391,13 +396,13 @@ Readers will note the new Value classes. These can be thought of as an intermediate class that can be used to convert from raw types to the Values that are used by the system. Recall that this database is holding objects of many types with a single generic type. Conversions to this -type can either be done using an intermediate class (IntValue, FpValue for +type can either be done using an intermediate class (IntegerValue, DoubleValue for "floating point") or via strings. Direct implicit conversion of types to Value is not really practical. So in the above, users have a choice of using strings or values: @verbatim -p->Set ("cwnd", "100"); // string-based setter -p->Set ("cwnd", IntValue(100)); // value-based setter +p->Set ("cwnd", StringValue ("100")); // string-based setter +p->Set ("cwnd", IntegerValue (100)); // integer-based setter @end verbatim The system provides some macros that help users declare and define From b9aeaf365031c02a10842a272f2114aef108fdd7 Mon Sep 17 00:00:00 2001 From: Mathieu Lacage Date: Mon, 23 Jun 2008 16:03:08 -0700 Subject: [PATCH 054/495] more typos. --- doc/manual/attributes.texi | 75 ++++++++++++++++++++++++-------------- 1 file changed, 47 insertions(+), 28 deletions(-) diff --git a/doc/manual/attributes.texi b/doc/manual/attributes.texi index 60eb075af..feb20ad78 100644 --- a/doc/manual/attributes.texi +++ b/doc/manual/attributes.texi @@ -271,7 +271,7 @@ main (int argc, char *argv[]) The main thing to notice in the above are the two calls to @code{Config::SetDefault}. This is how we set the default value for all subsequently instantiated DropTailQueues. We illustrate -that two types of Value classes, a String and a Uinteger class, +that two types of Value classes, a StringValue and a UintegerValue class, can be used to assign the value to the attribute named by "ns3::DropTailQueue::MaxPackets". @@ -392,9 +392,10 @@ or from the higher-level helper APIs, such as: @node Value classes @subsection Value classes -Readers will note the new Value classes. These can be thought of as +Readers will note the new FooValue classes which are subclasses of the +AttributeValue base class. These can be thought of as an intermediate class that can be used to convert from raw types to the -Values that are used by the system. Recall that this database is holding +Values that are used by the attribute system. Recall that this database is holding objects of many types with a single generic type. Conversions to this type can either be done using an intermediate class (IntegerValue, DoubleValue for "floating point") or via strings. Direct implicit conversion of types @@ -406,8 +407,12 @@ p->Set ("cwnd", IntegerValue (100)); // integer-based setter @end verbatim The system provides some macros that help users declare and define -new Value subclasses for new types that they want to introduce into -the attribute system. +new AttributeValue subclasses for new types that they want to introduce into +the attribute system: +@itemize @bullet +@item ATTRIBUTE_HELPER_HEADER +@item ATTRIBUTE_HELPER_CPP +@end itemize @node Extending attributes @section Extending attributes @@ -418,8 +423,6 @@ to pick up ones we have missed, or to add their own classes to this. @subsection Adding an existing internal variable to the metadata system -// XXX revise me - Consider this variable in class TcpSocket: @verbatim uint32_t m_cWnd; // Congestion window @@ -432,7 +435,9 @@ in the metadata system (to the TypeId declaration for TcpSocket): @verbatim .AddParameter ("Congestion window", "Tcp congestion window (bytes)", - MakeUIntParamSpec (&TcpSocket::m_cWnd, 1)); + Uinteger (1), + MakeUintegerAccessor (&TcpSocket::m_cWnd), + MakeUintegerChecker ()); @end verbatim @@ -451,21 +456,25 @@ We've already introduced what a TypeId definition looks like: @verbatim TypeId RandomWalk2dMobilityModel::GetTypeId (void) -{ - static TypeId tid = TypeId ("RandomWalkMobilityModel") - .SetParent () - .SetGroupName ("Mobility") +{ + static TypeId tid = TypeId ("ns3::RandomWalk2dMobilityModel") + .SetParent () + .SetGroupName ("Mobility") .AddConstructor () - // followed by a number of Parameters - .AddParameter ("bounds", - "Bounds of the area to cruise.", - MakeRectangleParamSpec (&RandomWalk2dMobilityModel::m_bounds, Rectangle (0.0, 0.0, 100.0, 100.0))) - .AddParameter ("time", - "Change current direction and speed after moving for this delay.", - MakeTimeParamSpec (&RandomWalk2dMobilityModel::m_modeTime, - Seconds (1.0))) - + .AddAttribute ("Bounds", + "Bounds of the area to cruise.", + RectangleValue (Rectangle (0.0, 0.0, 100.0, 100.0)), + MakeRectangleAccessor (&RandomWalk2dMobilityModel::m_bounds), + MakeRectangleChecker ()) + .AddAttribute ("Time", + "Change current direction and speed after moving for this delay.", + TimeValue (Seconds (1.0)), + MakeTimeAccessor (&RandomWalk2dMobilityModel::m_modeTime), + MakeTimeChecker ()) // etc (more parameters). + ; + return tid; +} @end verbatim The declaration for this in the class declaration is one-line public @@ -475,12 +484,24 @@ member method: static TypeId GetTypeId (void); @end verbatim -@section Adding new class type to the Value system +Typical mistakes here involve: +@itemize @bullet +@item Not calling the SetParent method or calling it with the wrong type +@item Not calling the AddConstructor method of calling it with the wrong type +@item Introducing a typographical error in the name of the TypeId in its constructor +@item Not using the fully-qualified c++ typename of the enclosing c++ class as the +name of the TypeId +@end itemize +None of these mistakes can be detected by the ns-3 codebase so, users +are advised to check carefully multiple times that they got these right. + + +@section Adding new class type to the attribute system From the perspective of the user who writes a new class in the system and wants to hook it in to the attribute system, there is mainly the matter of writing -the conversions to/from strings and Values. Most of this can be +the conversions to/from strings and attribute values. Most of this can be copy/pasted with macro-ized code. For instance, consider class Rectangle in the @code{src/mobility/} directory: @@ -493,24 +514,22 @@ class Rectangle { ... - VALUE_HELPER_HEADER_1 (Rectangle); }; @end verbatim -One templatized declaration, and two operators, are added below the -class declaration: +One macro call and two operators, are added below the class declaration: @verbatim std::ostream &operator << (std::ostream &os, const Rectangle &rectangle); std::istream &operator >> (std::istream &is, Rectangle &rectangle); -VALUE_HELPER_HEADER_2 (Rectangle); +ATTRIBUTE_HELPER_HEADER (Rectangle); @end verbatim In the class definition, the code looks like this: @verbatim -VALUE_HELPER_CPP (Rectangle); +ATTRIBUTE_HELPER_CPP (Rectangle); std::ostream & operator << (std::ostream &os, const Rectangle &rectangle) From 8c7759dc6bf77c2493f9a282acedfff8bbc9cba5 Mon Sep 17 00:00:00 2001 From: Craig Dowell Date: Tue, 24 Jun 2008 09:21:02 -0700 Subject: [PATCH 055/495] bug 233 --- .../point-to-point-net-device.cc | 25 +++++++++++++------ 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/src/devices/point-to-point/point-to-point-net-device.cc b/src/devices/point-to-point/point-to-point-net-device.cc index 25abe19af..6e3ea3f5a 100644 --- a/src/devices/point-to-point/point-to-point-net-device.cc +++ b/src/devices/point-to-point/point-to-point-net-device.cc @@ -40,29 +40,37 @@ PointToPointNetDevice::GetTypeId (void) static TypeId tid = TypeId ("ns3::PointToPointNetDevice") .SetParent () .AddConstructor () - .AddAttribute ("Address", "The address of this device.", + .AddAttribute ("Address", + "The MAC address of this device.", Mac48AddressValue (Mac48Address ("ff:ff:ff:ff:ff:ff")), MakeMac48AddressAccessor (&PointToPointNetDevice::m_address), MakeMac48AddressChecker ()) - .AddAttribute ("DataRate", "The default data rate for point to point links", + .AddAttribute ("DataRate", + "The default data rate for point to point links", DataRateValue (DataRate ("32768b/s")), MakeDataRateAccessor (&PointToPointNetDevice::m_bps), MakeDataRateChecker ()) - .AddAttribute ("ReceiveErrorModel", "XXX", + .AddAttribute ("ReceiveErrorModel", + "The receiver error model used to simulate packet loss", PointerValue (), MakePointerAccessor (&PointToPointNetDevice::m_receiveErrorModel), MakePointerChecker ()) - .AddAttribute ("TxQueue", "XXX", + .AddAttribute ("TxQueue", + "A queue to use as the transmit queue in the device.", PointerValue (), MakePointerAccessor (&PointToPointNetDevice::m_queue), MakePointerChecker ()) - .AddAttribute ("InterframeGap", "XXX", + .AddAttribute ("InterframeGap", + "The time to wait between packet (frame) transmissions", TimeValue (Seconds (0.0)), MakeTimeAccessor (&PointToPointNetDevice::m_tInterframeGap), MakeTimeChecker ()) - .AddTraceSource ("Rx", "Receive MAC packet.", + .AddTraceSource ("Rx", + "Trace source to fire on reception of a MAC packet.", MakeTraceSourceAccessor (&PointToPointNetDevice::m_rxTrace)) - .AddTraceSource ("Drop", "Drop MAC packet.", + .AddTraceSource ("Drop", + "Trace source to fire on when a MAC packet is dropped.", + MakeTraceSourceAccessor (&PointToPointNetDevice::m_dropTrace)) ; @@ -207,7 +215,7 @@ PointToPointNetDevice::SetQueue (Ptr q) void PointToPointNetDevice::SetReceiveErrorModel (Ptr em) { - NS_LOG_FUNCTION ("(" << em << ")"); + NS_LOG_FUNCTION (this << em); m_receiveErrorModel = em; } @@ -350,6 +358,7 @@ PointToPointNetDevice::GetBroadcast (void) const // // We don't deal with multicast here. It doesn't make sense to include some // of the one destinations on the network but exclude some of the others. +// bool PointToPointNetDevice::IsMulticast (void) const { From 92c9208ea6b0876921710c3308e663f7245917b6 Mon Sep 17 00:00:00 2001 From: Craig Dowell Date: Tue, 24 Jun 2008 15:40:24 -0700 Subject: [PATCH 056/495] Apply Patch for Bug 235 --- src/applications/packet-sink/packet-sink.cc | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/applications/packet-sink/packet-sink.cc b/src/applications/packet-sink/packet-sink.cc index 406078dc7..3fdcce8c3 100644 --- a/src/applications/packet-sink/packet-sink.cc +++ b/src/applications/packet-sink/packet-sink.cc @@ -67,10 +67,6 @@ PacketSink::~PacketSink() void PacketSink::DoDispose (void) { - if (m_socket != 0) - { - m_socket->Close (); - } m_socket = 0; // chain up From cb19bb1404414755786cea4408c4457a36b39f04 Mon Sep 17 00:00:00 2001 From: Craig Dowell Date: Tue, 24 Jun 2008 15:47:04 -0700 Subject: [PATCH 057/495] Added tag release ns-3.1-RC2 for changeset 951296e9a277 --- .hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/.hgtags b/.hgtags index fff235f85..cca250bb4 100644 --- a/.hgtags +++ b/.hgtags @@ -14,3 +14,4 @@ ee5e1da76ecc52337f097cd90ebb50a3d49ec541 release-3.0.11 b17f2928291eec5bf5b1c59a4a5fd583f704ac40 release ns-3.0.12 79dba133b5f8a2d6f6f678a22e8519bc155e6a4e release ns-3.0.13 8869a79a391f49d0c787f0558cc9329b4e7ee40e release candidate ns-3.1-RC1 +951296e9a277e14113a0d3ba86a9688b222569ae release ns-3.1-RC2 From 2b1bc243218471fc50bc2ced7c79c1ad91e5b8ab Mon Sep 17 00:00:00 2001 From: Craig Dowell Date: Tue, 24 Jun 2008 19:09:49 -0700 Subject: [PATCH 058/495] Apply patch for bug 231 --- src/applications/udp-echo/udp-echo-server.cc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/applications/udp-echo/udp-echo-server.cc b/src/applications/udp-echo/udp-echo-server.cc index 502673519..af7747c0a 100644 --- a/src/applications/udp-echo/udp-echo-server.cc +++ b/src/applications/udp-echo/udp-echo-server.cc @@ -104,6 +104,8 @@ UdpEchoServer::HandleRead (Ptr socket) NS_LOG_INFO ("Received " << packet->GetSize() << " bytes from " << address.GetIpv4()); + packet->RemoveAllTags (); + NS_LOG_LOGIC ("Echoing packet"); socket->SendTo (packet, 0, from); } From 89e20b56c9de68a8571bc17bc9a63f4bf1504be3 Mon Sep 17 00:00:00 2001 From: Craig Dowell Date: Fri, 27 Jun 2008 09:32:34 -0700 Subject: [PATCH 059/495] Patch for bug 240 --- src/core/random-variable.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/random-variable.cc b/src/core/random-variable.cc index be06c998b..6a08378b2 100644 --- a/src/core/random-variable.cc +++ b/src/core/random-variable.cc @@ -1012,7 +1012,7 @@ NormalVariableImpl::NormalVariableImpl(double m, double v, double b/*=INFINITE_V NormalVariableImpl::NormalVariableImpl(const NormalVariableImpl& c) : RandomVariableBase(c), m_mean(c.m_mean), m_variance(c.m_variance), - m_bound(c.m_bound) { } + m_bound(c.m_bound), m_nextValid(false) { } double NormalVariableImpl::GetValue() { From 62c2e46c37d981798c36014d211b4b5d7b2a48e2 Mon Sep 17 00:00:00 2001 From: Craig Dowell Date: Fri, 27 Jun 2008 14:38:08 -0700 Subject: [PATCH 060/495] reposition trace hook in csma to address bug 241. --- src/devices/csma/csma-net-device.cc | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/devices/csma/csma-net-device.cc b/src/devices/csma/csma-net-device.cc index faaddc7d6..09734519b 100644 --- a/src/devices/csma/csma-net-device.cc +++ b/src/devices/csma/csma-net-device.cc @@ -467,14 +467,19 @@ CsmaNetDevice::Receive (Ptr packet) return; } - m_rxTrace (packet); - if (m_encapMode == RAW) { + m_rxTrace (packet); m_rxCallback (this, packet, 0, GetBroadcast ()); return; } +// +// Trace sinks will expect complete packets, not packets without some of the +// headers. +// + Ptr originalPacket = packet->Copy (); + EthernetTrailer trailer; packet->RemoveTrailer (trailer); trailer.CheckFcs (packet); @@ -492,7 +497,7 @@ CsmaNetDevice::Receive (Ptr packet) // if (header.GetSource () == GetAddress ()) { - NS_LOG_LOGIC ("Dropping packet sourced by this device"); + NS_LOG_LOGIC ("Ignoring packet sourced by this device"); return; } @@ -556,6 +561,7 @@ CsmaNetDevice::Receive (Ptr packet) NS_ASSERT (false); break; } + m_rxTrace (originalPacket); m_rxCallback (this, packet, protocol, header.GetSource ()); } } From 8869dc96302a7748d18c35ca6874fd94ddc784a8 Mon Sep 17 00:00:00 2001 From: Craig Dowell Date: Fri, 27 Jun 2008 14:56:18 -0700 Subject: [PATCH 061/495] Apply Patch for Bug 237 --- src/internet-stack/tcp-socket-impl.cc | 13 +++---------- src/internet-stack/tcp-socket-impl.h | 2 -- 2 files changed, 3 insertions(+), 12 deletions(-) diff --git a/src/internet-stack/tcp-socket-impl.cc b/src/internet-stack/tcp-socket-impl.cc index cd66492ad..fc0cf1b8b 100644 --- a/src/internet-stack/tcp-socket-impl.cc +++ b/src/internet-stack/tcp-socket-impl.cc @@ -80,8 +80,7 @@ TcpSocketImpl::GetTypeId () m_pendingData (0), m_rtt (0), m_lastMeasuredRtt (Seconds(0.0)), - m_rxAvailable (0), - m_wouldBlock (false) + m_rxAvailable (0) { NS_LOG_FUNCTION (this); } @@ -126,7 +125,6 @@ TcpSocketImpl::TcpSocketImpl(const TcpSocketImpl& sock) m_cnTimeout (sock.m_cnTimeout), m_cnCount (sock.m_cnCount), m_rxAvailable (0), - m_wouldBlock (false), m_sndBufSize (sock.m_sndBufSize), m_rcvBufSize(sock.m_rcvBufSize) { @@ -356,7 +354,6 @@ TcpSocketImpl::Send (Ptr p, uint32_t flags) { if (p->GetSize() > GetTxAvailable ()) { - m_wouldBlock = true; m_errno = ERROR_MSGSIZE; return -1; } @@ -796,9 +793,8 @@ bool TcpSocketImpl::ProcessPacketAction (Actions_t a, Ptr p, { m_highestRxAck = tcpHeader.GetAckNumber (); // Data freed from the send buffer; notify any blocked sender - if (m_wouldBlock) + if (GetTxAvailable () > 0) { - m_wouldBlock = false; NotifySend (GetTxAvailable ()); } } @@ -1168,11 +1164,8 @@ void TcpSocketImpl::CommonNewAck (SequenceNumber ack, bool skipTimer) NS_LOG_LOGIC ("TCP " << this << " NewAck " << ack << " numberAck " << (ack - m_highestRxAck)); // Number bytes ack'ed m_highestRxAck = ack; // Note the highest recieved Ack - if (m_wouldBlock) + if (GetTxAvailable () > 0) { - // m_highestRxAck advancing means some data was acked, and the size - // of free space in the buffer has increased - m_wouldBlock = false; NotifySend (GetTxAvailable ()); } if (ack > m_nextTxSequence) diff --git a/src/internet-stack/tcp-socket-impl.h b/src/internet-stack/tcp-socket-impl.h index 311f0832d..bc65706a0 100644 --- a/src/internet-stack/tcp-socket-impl.h +++ b/src/internet-stack/tcp-socket-impl.h @@ -216,8 +216,6 @@ private: // Temporary queue for delivering data to application uint32_t m_rxAvailable; - bool m_wouldBlock; // set to true whenever socket would block on send() - // Attributes uint32_t m_sndBufSize; // buffer limit for the outgoing queue uint32_t m_rcvBufSize; // maximum receive socket buffer size From 31fc5329131d7bbefc3e98a4dbace4235d5a4fe7 Mon Sep 17 00:00:00 2001 From: Craig Dowell Date: Fri, 27 Jun 2008 15:07:04 -0700 Subject: [PATCH 062/495] Added tag release ns-3.1-RC3 for changeset ea16c44eb90d --- .hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/.hgtags b/.hgtags index cca250bb4..d84baa13b 100644 --- a/.hgtags +++ b/.hgtags @@ -15,3 +15,4 @@ b17f2928291eec5bf5b1c59a4a5fd583f704ac40 release ns-3.0.12 79dba133b5f8a2d6f6f678a22e8519bc155e6a4e release ns-3.0.13 8869a79a391f49d0c787f0558cc9329b4e7ee40e release candidate ns-3.1-RC1 951296e9a277e14113a0d3ba86a9688b222569ae release ns-3.1-RC2 +ea16c44eb90db579c83d3434fc8a960be506a7f5 release ns-3.1-RC3 From 500b5c1fd4583c7534f432eb498f960798c757c5 Mon Sep 17 00:00:00 2001 From: Mathieu Lacage Date: Fri, 27 Jun 2008 15:29:11 -0700 Subject: [PATCH 063/495] cleanup tag names --- .hgtags | 34 ++++++++++++++++------------------ 1 file changed, 16 insertions(+), 18 deletions(-) diff --git a/.hgtags b/.hgtags index d84baa13b..6e3254eeb 100644 --- a/.hgtags +++ b/.hgtags @@ -1,18 +1,16 @@ -56928998e05c9c11f5f3aefe79be8d2843e0db88 release ns-3.0.1 -7ac5a4b0969b255c4824c926c2b37ef450136ce9 release ns-3.0.2 -0dc81e76166c56aaae64da48b673b62155943aad packet-history-working -38099dd26e9467b8f49f8632f22789858149a6e7 release ns-3.0.3 -5701e60bf01a8ac1308945e69001e0cc07948faf release ns-3.0.4 -08046b6aef37932507696a2f2f427b42d693781e release ns-3.0.5 -267e2ebc28e4e4ae2f579e1cfc29902acade0c34 buffer-working-before-breaking -606df29888e7573b825fc891a002f0757166b616 release ns-3.0.6 -36472385a1cc7c44d34fb7a5951b930010f4e8d2 release ns-3.0.7 -560a5091e0e6ded47d269e2f2dee780f13950a63 release ns-3.0.8 -4db981a0d9eb135e3e1c07765cff8d66f7a55cca release ns-3.0.9 -b5bf2588cde2f1273b1095cc5c83a0c272e55370 release ns-3.0.10 -ee5e1da76ecc52337f097cd90ebb50a3d49ec541 release-3.0.11 -b17f2928291eec5bf5b1c59a4a5fd583f704ac40 release ns-3.0.12 -79dba133b5f8a2d6f6f678a22e8519bc155e6a4e release ns-3.0.13 -8869a79a391f49d0c787f0558cc9329b4e7ee40e release candidate ns-3.1-RC1 -951296e9a277e14113a0d3ba86a9688b222569ae release ns-3.1-RC2 -ea16c44eb90db579c83d3434fc8a960be506a7f5 release ns-3.1-RC3 +56928998e05c9c11f5f3aefe79be8d2843e0db88 ns-3.0.1 +7ac5a4b0969b255c4824c926c2b37ef450136ce9 ns-3.0.2 +38099dd26e9467b8f49f8632f22789858149a6e7 ns-3.0.3 +5701e60bf01a8ac1308945e69001e0cc07948faf ns-3.0.4 +08046b6aef37932507696a2f2f427b42d693781e ns-3.0.5 +606df29888e7573b825fc891a002f0757166b616 ns-3.0.6 +36472385a1cc7c44d34fb7a5951b930010f4e8d2 ns-3.0.7 +560a5091e0e6ded47d269e2f2dee780f13950a63 ns-3.0.8 +4db981a0d9eb135e3e1c07765cff8d66f7a55cca ns-3.0.9 +b5bf2588cde2f1273b1095cc5c83a0c272e55370 ns-3.0.10 +ee5e1da76ecc52337f097cd90ebb50a3d49ec541 ns-3.0.11 +b17f2928291eec5bf5b1c59a4a5fd583f704ac40 ns-3.0.12 +79dba133b5f8a2d6f6f678a22e8519bc155e6a4e ns-3.0.13 +8869a79a391f49d0c787f0558cc9329b4e7ee40e ns-3.1-RC1 +951296e9a277e14113a0d3ba86a9688b222569ae ns-3.1-RC2 +ea16c44eb90db579c83d3434fc8a960be506a7f5 ns-3.1-RC3 From 246b544cb37821b6ea578d20ceb98903978d44b7 Mon Sep 17 00:00:00 2001 From: Craig Dowell Date: Sat, 28 Jun 2008 19:29:54 -0700 Subject: [PATCH 064/495] remove tutorial directory --- tutorial/hello-simulator.cc | 30 ----- tutorial/testipv4.cc | 59 -------- tutorial/tutorial-bus-network.cc | 75 ----------- tutorial/tutorial-csma-echo-ascii-trace.cc | 72 ---------- tutorial/tutorial-csma-echo-pcap-trace.cc | 68 ---------- tutorial/tutorial-csma-echo.cc | 66 --------- tutorial/tutorial-linear-dumbbell.cc | 148 --------------------- tutorial/tutorial-point-to-point.cc | 78 ----------- tutorial/tutorial-star-routing.cc | 108 --------------- tutorial/tutorial-star.cc | 105 --------------- tutorial/waf | 1 - tutorial/wscript | 32 ----- 12 files changed, 842 deletions(-) delete mode 100644 tutorial/hello-simulator.cc delete mode 100644 tutorial/testipv4.cc delete mode 100644 tutorial/tutorial-bus-network.cc delete mode 100644 tutorial/tutorial-csma-echo-ascii-trace.cc delete mode 100644 tutorial/tutorial-csma-echo-pcap-trace.cc delete mode 100644 tutorial/tutorial-csma-echo.cc delete mode 100644 tutorial/tutorial-linear-dumbbell.cc delete mode 100644 tutorial/tutorial-point-to-point.cc delete mode 100644 tutorial/tutorial-star-routing.cc delete mode 100644 tutorial/tutorial-star.cc delete mode 100755 tutorial/waf delete mode 100644 tutorial/wscript diff --git a/tutorial/hello-simulator.cc b/tutorial/hello-simulator.cc deleted file mode 100644 index 691098071..000000000 --- a/tutorial/hello-simulator.cc +++ /dev/null @@ -1,30 +0,0 @@ -/* -*- 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 - */ - -#include "ns3/core-module.h" - -NS_LOG_COMPONENT_DEFINE ("HelloSimulator"); - -using namespace ns3; - -int -main (int argc, char *argv[]) -{ - // LogComponentEnable ("HelloSimulator", - // LogLevel (LOG_LEVEL_INFO | LOG_PREFIX_ALL)); - - NS_LOG_INFO ("Hello Simulator"); -} diff --git a/tutorial/testipv4.cc b/tutorial/testipv4.cc deleted file mode 100644 index ef98b3a77..000000000 --- a/tutorial/testipv4.cc +++ /dev/null @@ -1,59 +0,0 @@ -/* -*- 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 - */ - -#include "ns3/log.h" -#include "ns3/ipv4-address-generator.h" - -NS_LOG_COMPONENT_DEFINE ("TestIpv4"); - -using namespace ns3; - -int -main (int argc, char *argv[]) -{ - LogComponentEnable ("TestIpv4", LOG_LEVEL_ALL); - - NS_LOG_INFO ("Test Ipv4"); - - Ipv4Mask mask1 ("255.0.0.0"); - - for (uint32_t i = 0; i < 10; ++i) - { - Ipv4Address network = Ipv4AddressGenerator::NextNetwork (mask1); - Ipv4Address address = Ipv4AddressGenerator::NextAddress (mask1); - NS_LOG_INFO ("address = " << address); - } - - Ipv4Mask mask2 ("255.255.0.0"); - Ipv4AddressGenerator::Init (Ipv4Address ("192.168.0.0"), mask2); - Ipv4AddressGenerator::InitAddress (Ipv4Address ("0.0.0.3"), mask2); - - Ipv4Address network1 = Ipv4AddressGenerator::NextNetwork (mask2); - for (uint32_t i = 0; i < 10; ++i) - { - Ipv4Address address = Ipv4AddressGenerator::NextAddress (mask2); - NS_LOG_INFO ("address = " << address); - } - - Ipv4Mask mask3 ("255.255.255.0"); - - for (uint32_t i = 0; i < 10; ++i) - { - Ipv4Address network = Ipv4AddressGenerator::NextNetwork (mask3); - Ipv4Address address = Ipv4AddressGenerator::NextAddress (mask3); - NS_LOG_INFO ("address = " << address); - } -} diff --git a/tutorial/tutorial-bus-network.cc b/tutorial/tutorial-bus-network.cc deleted file mode 100644 index a4016a4dc..000000000 --- a/tutorial/tutorial-bus-network.cc +++ /dev/null @@ -1,75 +0,0 @@ - -/* - * 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 - */ - -#include - -#include "ns3/core-module.h" -#include "ns3/node-module.h" -#include "ns3/helper-module.h" -#include "ns3/simulator-module.h" -#include "ns3/global-route-manager.h" - -NS_LOG_COMPONENT_DEFINE ("BusNetworkSimulation"); - -using namespace ns3; - -int -main (int argc, char *argv[]) -{ - LogComponentEnable ("BusNetworkSimulation", LOG_LEVEL_ALL); - - NS_LOG_INFO ("Bus Network Simulation"); - - NodeContainer n; - n.Create (10); - - InternetStackHelper internet; - internet.Install (n); - - CsmaHelper csma; - csma.SetChannelParameter ("DataRate", StringValue ("10Mbps")); - csma.SetChannelParameter ("Delay", StringValue ("10ms")); - NetDeviceContainer nd = csma.Install (n); - - Ipv4AddressHelper ipv4; - ipv4.SetBase ("10.1.0.0", "255.255.0.0", "0.0.0.3"); - Ipv4InterfaceContainer i = ipv4.Assign (nd); - - uint32_t port = 7; - UdpEchoClientHelper client; - client.SetRemote (i.GetAddress (1), port); - client.SetAppAttribute ("MaxPackets", UintegerValue (1)); - client.SetAppAttribute ("Interval", StringValue ("1s")); - client.SetAppAttribute ("PacketSize", UintegerValue (1024)); - ApplicationContainer apps = client.Install (n.Get (0)); - apps.Start (Seconds (2.0)); - apps.Stop (Seconds (10.0)); - - UdpEchoServerHelper server; - server.SetPort (port); - apps = server.Install (n.Get (1)); - apps.Start (Seconds (1.0)); - apps.Stop (Seconds (10.0)); - - GlobalRouteManager::PopulateRoutingTables (); - - std::ofstream ascii; - ascii.open ("tutorial.tr"); - CsmaHelper::EnableAsciiAll (ascii); - - Simulator::Run (); - Simulator::Destroy (); -} diff --git a/tutorial/tutorial-csma-echo-ascii-trace.cc b/tutorial/tutorial-csma-echo-ascii-trace.cc deleted file mode 100644 index 8fef98c97..000000000 --- a/tutorial/tutorial-csma-echo-ascii-trace.cc +++ /dev/null @@ -1,72 +0,0 @@ -/* -*- 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 - */ - -#include - -#include "ns3/core-module.h" -#include "ns3/simulator-module.h" -#include "ns3/helper-module.h" - -NS_LOG_COMPONENT_DEFINE ("UdpEchoSimulation"); - -using namespace ns3; - -int -main (int argc, char *argv[]) -{ - LogComponentEnable ("UdpEchoSimulation", LOG_LEVEL_INFO); - - NS_LOG_INFO ("UDP Echo Simulation"); - - NodeContainer n; - n.Create (4); - - InternetStackHelper internet; - internet.Install (n); - - CsmaHelper csma; - csma.SetChannelParameter ("DataRate", StringValue ("5Mpbs")); - csma.SetChannelParameter ("Delay", StringValue ("2ms")); - NetDeviceContainer nd = csma.Install (n); - - Ipv4AddressHelper ipv4; - ipv4.SetBase ("10.1.1.0", "255.255.255.0"); - Ipv4InterfaceContainer i = ipv4.Assign (nd); - - uint16_t port = 7; - - UdpEchoClientHelper client; - client.SetRemote (i.GetAddress (1), port); - client.SetAppAttribute ("MaxPackets", UintegerValue (1)); - client.SetAppAttribute ("Interval", StringValue ("1s")); - client.SetAppAttribute ("PacketSize", UintegerValue (1024)); - ApplicationContainer apps = client.Install (n.Get (0)); - apps.Start (Seconds (2.0)); - apps.Stop (Seconds (10.0)); - - UdpEchoServerHelper server; - server.SetPort (port); - apps = server.Install (n.Get (1)); - apps.Start (Seconds (1.0)); - apps.Stop (Seconds (10.0)); - - std::ofstream os; - os.open ("tutorial.tr"); - CsmaHelper::EnableAsciiAll (os); - - Simulator::Run (); - Simulator::Destroy (); -} diff --git a/tutorial/tutorial-csma-echo-pcap-trace.cc b/tutorial/tutorial-csma-echo-pcap-trace.cc deleted file mode 100644 index 090fb1b65..000000000 --- a/tutorial/tutorial-csma-echo-pcap-trace.cc +++ /dev/null @@ -1,68 +0,0 @@ -/* -*- 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 - */ - -#include "ns3/core-module.h" -#include "ns3/simulator-module.h" -#include "ns3/helper-module.h" - -NS_LOG_COMPONENT_DEFINE ("UdpEchoSimulation"); - -using namespace ns3; - -int -main (int argc, char *argv[]) -{ - LogComponentEnable ("UdpEchoSimulation", LOG_LEVEL_INFO); - - NS_LOG_INFO ("UDP Echo Simulation"); - - NodeContainer n; - n.Create (4); - - InternetStackHelper internet; - internet.Install (n); - - CsmaHelper csma; - csma.SetChannelParameter ("DataRate", StringValue ("5Mbps")); - csma.SetChannelParameter ("Delay", StringValue ("2ms")); - NetDeviceContainer nd = csma.Install (n); - - Ipv4AddressHelper ipv4; - ipv4.SetBase ("10.1.1.0", "255.255.255.0"); - Ipv4InterfaceContainer i = ipv4.Assign (nd); - - uint16_t port = 7; - - UdpEchoClientHelper client; - client.SetRemote (i.GetAddress (1), port); - client.SetAppAttribute ("MaxPackets", UintegerValue (1)); - client.SetAppAttribute ("Interval", StringValue ("2s")); - client.SetAppAttribute ("PacketSize", UintegerValue (1024)); - ApplicationContainer apps = client.Install (n.Get (0)); - apps.Start (Seconds (2.0)); - apps.Stop (Seconds (10.0)); - - UdpEchoServerHelper server; - server.SetPort (port); - apps = server.Install (n.Get (1)); - apps.Start (Seconds (1.0)); - apps.Stop (Seconds (10.0)); - - CsmaHelper::EnablePcapAll ("tutorial"); - - Simulator::Run (); - Simulator::Destroy (); -} diff --git a/tutorial/tutorial-csma-echo.cc b/tutorial/tutorial-csma-echo.cc deleted file mode 100644 index e4472d4a9..000000000 --- a/tutorial/tutorial-csma-echo.cc +++ /dev/null @@ -1,66 +0,0 @@ -/* -*- 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 - */ - -#include "ns3/core-module.h" -#include "ns3/simulator-module.h" -#include "ns3/helper-module.h" - -NS_LOG_COMPONENT_DEFINE ("UdpEchoSimulation"); - -using namespace ns3; - -int -main (int argc, char *argv[]) -{ - LogComponentEnable ("UdpEchoSimulation", LOG_LEVEL_INFO); - - NS_LOG_INFO ("UDP Echo Simulation"); - - NodeContainer n; - n.Create (4); - - InternetStackHelper internet; - internet.Install (n); - - CsmaHelper csma; - csma.SetChannelParameter ("DataRate", StringValue ("5Mbps")); - csma.SetChannelParameter ("Delay", StringValue ("2ms")); - NetDeviceContainer nd = csma.Install (n); - - Ipv4AddressHelper ipv4; - ipv4.SetBase ("10.1.1.0", "255.255.255.0"); - Ipv4InterfaceContainer i = ipv4.Assign (nd); - - uint16_t port = 7; - - UdpEchoClientHelper client; - client.SetRemote (i.GetAddress (1), port); - client.SetAppAttribute ("MaxPackets", UintegerValue (1)); - client.SetAppAttribute ("Interval", StringValue ("1s")); - client.SetAppAttribute ("PacketSize", UintegerValue (1024)); - ApplicationContainer apps = client.Install (n.Get (0)); - apps.Start (Seconds (2.0)); - apps.Stop (Seconds (10.0)); - - UdpEchoServerHelper server; - server.SetPort (port); - apps = server.Install (n.Get (1)); - apps.Start (Seconds (1.0)); - apps.Stop (Seconds (10.0)); - - Simulator::Run (); - Simulator::Destroy (); -} diff --git a/tutorial/tutorial-linear-dumbbell.cc b/tutorial/tutorial-linear-dumbbell.cc deleted file mode 100644 index 6b85a7b08..000000000 --- a/tutorial/tutorial-linear-dumbbell.cc +++ /dev/null @@ -1,148 +0,0 @@ -/* -*- 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 - */ - -#include - -#include "ns3/core-module.h" -#include "ns3/node-module.h" -#include "ns3/helper-module.h" -#include "ns3/simulator-module.h" -#include "ns3/global-route-manager.h" - - -NS_LOG_COMPONENT_DEFINE ("DumbbellSimulation"); - -using namespace ns3; - -// Network topology -// -// point to point -// +--------------+ -// | | -// n0 n1 n2 n3 n4 n5 n6 n7 -// | | | | | | | | -// ================ ================ -// lan1 lan2 -// -int -main (int argc, char *argv[]) -{ - LogComponentEnable ("DumbbellSimulation", LOG_LEVEL_INFO); - - NS_LOG_INFO ("Dumbbell Topology Simulation"); -// -// Create the lan on the left side of the dumbbell. -// - NodeContainer lan1; - lan1.Create (4); - - InternetStackHelper internet; - internet.Install (lan1); - - CsmaHelper csma; - csma.SetChannelParameter ("DataRate", StringValue ("10Mbps")); - csma.SetChannelParameter ("Delay", StringValue ("2ms")); - NetDeviceContainer dev1 = csma.Install (lan1); - Ipv4AddressHelper ipv4; - ipv4.SetBase ("10.1.1.0", "255.255.255.0"); - Ipv4InterfaceContainer i1 = ipv4.Assign (dev1); - - -// -// Create the lan on the right side of the dumbbell. -// - NodeContainer lan2; - lan2.Create (4); - internet.Install (lan2); - - NetDeviceContainer dev2 = csma.Install (lan2); - ipv4.SetBase ("10.1.2.0", "255.255.255.0"); - Ipv4InterfaceContainer i2 = ipv4.Assign (dev2); - - -// -// Create the point-to-point link to connect the two lans. -// - NodeContainer backbone = NodeContainer (lan1.Get (3), lan2.Get (0)); - PointToPointHelper p2p; - p2p.SetChannelParameter ("DataRate", StringValue ("38400bps")); - p2p.SetChannelParameter ("Delay", StringValue ("20ms")); - NetDeviceContainer dev3 = p2p.Install (backbone); - ipv4.SetBase ("10.1.3.0", "255.255.255.0"); - ipv4.Assign (dev3); - -// -// Create data flows across the link: -// n0 ==> n4 ==> n0 -// n1 ==> n5 ==> n1 -// n2 ==> n6 ==> n2 -// n3 ==> n7 ==> n3 -// - uint16_t port = 7; - - UdpEchoClientHelper client; - client.SetRemote (i2.GetAddress (0), port); - client.SetAppAttribute ("MaxPackets", UintegerValue (100)); - client.SetAppAttribute ("Interval", StringValue ("10ms")); - client.SetAppAttribute ("PacketSize", UintegerValue (1024)); - ApplicationContainer apps = client.Install (lan1.Get (0)); - apps.Start (Seconds(2.)); - apps.Stop (Seconds (10.0)); - - client.SetRemote (i2.GetAddress (1), port); - apps = client.Install (lan1.Get (1)); - apps.Start (Seconds(2.1)); - apps.Stop (Seconds (10.0)); - - client.SetRemote (i2.GetAddress (2), port); - apps = client.Install (lan1.Get (2)); - apps.Start (Seconds(2.2)); - apps.Stop (Seconds (10.0)); - - client.SetRemote (i2.GetAddress (3), port); - apps = client.Install (lan1.Get (3)); - apps.Start (Seconds(2.3)); - apps.Stop (Seconds (10.0)); - - - UdpEchoServerHelper server; - server.SetPort (port); - apps = server.Install (lan2.Get (0)); - apps.Start (Seconds (1.0)); - apps.Stop (Seconds (10.0)); - apps = server.Install (lan2.Get (1)); - apps.Start (Seconds (1.0)); - apps.Stop (Seconds (10.0)); - apps = server.Install (lan2.Get (2)); - apps.Start (Seconds (1.0)); - apps.Stop (Seconds (10.0)); - apps = server.Install (lan2.Get (3)); - apps.Start (Seconds (1.0)); - apps.Stop (Seconds (10.0)); - - GlobalRouteManager::PopulateRoutingTables (); - - std::ofstream os; - os.open ("tutorial.tr"); - PointToPointHelper::EnableAsciiAll (os); - CsmaHelper::EnableAsciiAll (os); - - PointToPointHelper::EnablePcapAll ("tutorial"); - CsmaHelper::EnablePcapAll ("tutorial"); - - Simulator::Run (); - Simulator::Destroy (); -} diff --git a/tutorial/tutorial-point-to-point.cc b/tutorial/tutorial-point-to-point.cc deleted file mode 100644 index 030920007..000000000 --- a/tutorial/tutorial-point-to-point.cc +++ /dev/null @@ -1,78 +0,0 @@ -/* -*- 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 - */ - -#include - -#include "ns3/core-module.h" -#include "ns3/simulator-module.h" -#include "ns3/helper-module.h" - -NS_LOG_COMPONENT_DEFINE ("PointToPointSimulation"); - -using namespace ns3; - -// Network topology -// -// point to point -// +--------------+ -// | | -// n0 n1 -// -int -main (int argc, char *argv[]) -{ - LogComponentEnable ("PointToPointSimulation", LOG_LEVEL_INFO); - - NS_LOG_INFO ("Point to Point Topology Simulation"); - - NodeContainer n; - n.Create (2); - - InternetStackHelper internet; - internet.Install (n); - - PointToPointHelper p2p; - p2p.SetDeviceParameter ("DataRate", StringValue ("38400bps")); - p2p.SetChannelParameter ("Delay", StringValue ("20ms")); - NetDeviceContainer nd = p2p.Install (n); - - Ipv4AddressHelper ipv4; - ipv4.SetBase ("10.1.1.0", "255.255.255.252"); - Ipv4InterfaceContainer i = ipv4.Assign (nd); - - uint16_t port = 7; - UdpEchoClientHelper client; - client.SetRemote (i.GetAddress (1), port); - client.SetAppAttribute ("MaxPackets", UintegerValue (1)); - client.SetAppAttribute ("Interval", StringValue ("1s")); - client.SetAppAttribute ("PacketSize", UintegerValue (1024)); - ApplicationContainer apps = client.Install (n.Get (0)); - apps.Start (Seconds (2.0)); - apps.Stop (Seconds (10.0)); - - UdpEchoServerHelper server; - server.SetPort (port); - apps = server.Install (n.Get (1)); - apps.Start (Seconds (1.0)); - apps.Stop (Seconds (10.0)); - - std::ofstream ascii; - ascii.open ("tutorial.tr"); - PointToPointHelper::EnableAsciiAll (ascii); - - Simulator::Run (); - Simulator::Destroy (); -} diff --git a/tutorial/tutorial-star-routing.cc b/tutorial/tutorial-star-routing.cc deleted file mode 100644 index 1abacf9a4..000000000 --- a/tutorial/tutorial-star-routing.cc +++ /dev/null @@ -1,108 +0,0 @@ -/* -*- 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 - */ - -#include - -#include "ns3/core-module.h" -#include "ns3/node-module.h" -#include "ns3/helper-module.h" -#include "ns3/simulator-module.h" -#include "ns3/global-route-manager.h" - -NS_LOG_COMPONENT_DEFINE ("StarRoutingSimulation"); - -using namespace ns3; - -// Network topology -// -// n3 n2 -// | / -// | / -// n4 --- n0 --- n1 -// / | -// / | -// n5 n6 - -int -main (int argc, char *argv[]) -{ - LogComponentEnable ("StarRoutingSimulation", LOG_LEVEL_INFO); - - NS_LOG_INFO ("Star Topology with Routing Simulation"); - - NodeContainer n; - n.Create (7); - NodeContainer n01 = NodeContainer (n.Get (0), n.Get (1)); - NodeContainer n02 = NodeContainer (n.Get (0), n.Get (2)); - NodeContainer n03 = NodeContainer (n.Get (0), n.Get (3)); - NodeContainer n04 = NodeContainer (n.Get (0), n.Get (4)); - NodeContainer n05 = NodeContainer (n.Get (0), n.Get (5)); - NodeContainer n06 = NodeContainer (n.Get (0), n.Get (6)); - - InternetStackHelper internet; - internet.Install (n); - - PointToPointHelper p2p; - p2p.SetDeviceParameter ("DataRate", StringValue ("38400bps")); - p2p.SetChannelParameter ("Delay", StringValue ("20ms")); - - NetDeviceContainer d01 = p2p.Install (n01); - NetDeviceContainer d02 = p2p.Install (n02); - NetDeviceContainer d03 = p2p.Install (n03); - NetDeviceContainer d04 = p2p.Install (n04); - NetDeviceContainer d05 = p2p.Install (n05); - NetDeviceContainer d06 = p2p.Install (n06); - - Ipv4AddressHelper ipv4; - ipv4.SetBase ("10.1.1.0", "255.255.255.252"); - Ipv4InterfaceContainer i01 = ipv4.Assign (d01); - ipv4.SetBase ("10.1.2.0", "255.255.255.252"); - Ipv4InterfaceContainer i02 = ipv4.Assign (d02); - ipv4.SetBase ("10.1.3.0", "255.255.255.252"); - Ipv4InterfaceContainer i03 = ipv4.Assign (d03); - ipv4.SetBase ("10.1.4.0", "255.255.255.252"); - Ipv4InterfaceContainer i04 = ipv4.Assign (d04); - ipv4.SetBase ("10.1.5.0", "255.255.255.252"); - Ipv4InterfaceContainer i05 = ipv4.Assign (d05); - ipv4.SetBase ("10.1.6.0", "255.255.255.252"); - Ipv4InterfaceContainer i06 = ipv4.Assign (d06); - - uint16_t port = 7; - - UdpEchoServerHelper server; - server.SetPort (port); - ApplicationContainer apps = server.Install (n.Get (1)); - apps.Start (Seconds (1.0)); - apps.Stop (Seconds (10.0)); - - UdpEchoClientHelper client; - client.SetRemote (i01.GetAddress (1), port); - client.SetAppAttribute ("MaxPackets", UintegerValue (1)); - client.SetAppAttribute ("Interval", StringValue ("1s")); - client.SetAppAttribute ("PacketSize", UintegerValue (1024)); - apps = client.Install (n.Get (0)); - apps.Start (Seconds (2.0)); - apps.Stop (Seconds (10.0)); - - GlobalRouteManager::PopulateRoutingTables (); - - std::ofstream ascii; - ascii.open ("tutorial.tr"); - PointToPointHelper::EnableAsciiAll (ascii); - - Simulator::Run (); - Simulator::Destroy (); -} diff --git a/tutorial/tutorial-star.cc b/tutorial/tutorial-star.cc deleted file mode 100644 index f13018b9c..000000000 --- a/tutorial/tutorial-star.cc +++ /dev/null @@ -1,105 +0,0 @@ -/* -*- 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 - */ - -#include - -#include "ns3/core-module.h" -#include "ns3/node-module.h" -#include "ns3/helper-module.h" -#include "ns3/simulator-module.h" - -NS_LOG_COMPONENT_DEFINE ("StarRoutingSimulation"); - -using namespace ns3; - -// Network topology -// -// n3 n2 -// | / -// | / -// n4 --- n0 --- n1 -// / | -// / | -// n5 n6 - -int -main (int argc, char *argv[]) -{ - LogComponentEnable ("StarRoutingSimulation", LOG_LEVEL_INFO); - - NS_LOG_INFO ("Star Topology with Routing Simulation"); - - NodeContainer n; - n.Create (7); - NodeContainer n01 = NodeContainer (n.Get (0), n.Get (1)); - NodeContainer n02 = NodeContainer (n.Get (0), n.Get (2)); - NodeContainer n03 = NodeContainer (n.Get (0), n.Get (3)); - NodeContainer n04 = NodeContainer (n.Get (0), n.Get (4)); - NodeContainer n05 = NodeContainer (n.Get (0), n.Get (5)); - NodeContainer n06 = NodeContainer (n.Get (0), n.Get (6)); - - InternetStackHelper internet; - internet.Install (n); - - PointToPointHelper p2p; - p2p.SetDeviceParameter ("DataRate", StringValue ("38400bps")); - p2p.SetChannelParameter ("Delay", StringValue ("20ms")); - - NetDeviceContainer d01 = p2p.Install (n01); - NetDeviceContainer d02 = p2p.Install (n02); - NetDeviceContainer d03 = p2p.Install (n03); - NetDeviceContainer d04 = p2p.Install (n04); - NetDeviceContainer d05 = p2p.Install (n05); - NetDeviceContainer d06 = p2p.Install (n06); - - Ipv4AddressHelper ipv4; - ipv4.SetBase ("10.1.1.0", "255.255.255.252"); - Ipv4InterfaceContainer i01 = ipv4.Assign (d01); - ipv4.SetBase ("10.1.2.0", "255.255.255.252"); - Ipv4InterfaceContainer i02 = ipv4.Assign (d02); - ipv4.SetBase ("10.1.3.0", "255.255.255.252"); - Ipv4InterfaceContainer i03 = ipv4.Assign (d03); - ipv4.SetBase ("10.1.4.0", "255.255.255.252"); - Ipv4InterfaceContainer i04 = ipv4.Assign (d04); - ipv4.SetBase ("10.1.5.0", "255.255.255.252"); - Ipv4InterfaceContainer i05 = ipv4.Assign (d05); - ipv4.SetBase ("10.1.6.0", "255.255.255.252"); - Ipv4InterfaceContainer i06 = ipv4.Assign (d06); - - uint16_t port = 7; - - UdpEchoServerHelper server; - server.SetPort (port); - ApplicationContainer apps = server.Install (n.Get (1)); - apps.Start (Seconds (1.0)); - apps.Stop (Seconds (10.0)); - - UdpEchoClientHelper client; - client.SetRemote (i01.GetAddress (1), port); - client.SetAppAttribute ("MaxPackets", UintegerValue (1)); - client.SetAppAttribute ("Interval", StringValue ("1s")); - client.SetAppAttribute ("PacketSize", UintegerValue (1024)); - apps = client.Install (n.Get (0)); - apps.Start (Seconds (2.0)); - apps.Stop (Seconds (10.0)); - - std::ofstream ascii; - ascii.open ("tutorial.tr"); - PointToPointHelper::EnableAsciiAll (ascii); - - Simulator::Run (); - Simulator::Destroy (); -} diff --git a/tutorial/waf b/tutorial/waf deleted file mode 100755 index 191b7dbb2..000000000 --- a/tutorial/waf +++ /dev/null @@ -1 +0,0 @@ -exec "`dirname "$0"`"/../waf "$@" diff --git a/tutorial/wscript b/tutorial/wscript deleted file mode 100644 index a302c39bb..000000000 --- a/tutorial/wscript +++ /dev/null @@ -1,32 +0,0 @@ -## -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*- - -def build(bld): - obj = bld.create_ns3_program('hello-simulator', ['simulator']) - obj.source = 'hello-simulator.cc' - - obj = bld.create_ns3_program('tutorial-csma-echo', ['internet-stack', 'csma']) - obj.source = 'tutorial-csma-echo.cc' - - obj = bld.create_ns3_program('tutorial-csma-echo-ascii-trace', ['internet-stack', 'csma']) - obj.source = 'tutorial-csma-echo-ascii-trace.cc' - - obj = bld.create_ns3_program('tutorial-csma-echo-pcap-trace', ['internet-stack', 'csma']) - obj.source = 'tutorial-csma-echo-pcap-trace.cc' - - obj = bld.create_ns3_program('tutorial-point-to-point', ['internet-stack', 'point-to-point']) - obj.source = 'tutorial-point-to-point.cc' - - obj = bld.create_ns3_program('tutorial-star', ['internet-stack', 'point-to-point']) - obj.source = ['tutorial-star.cc'] - - obj = bld.create_ns3_program('tutorial-star-routing', ['internet-stack', 'point-to-point']) - obj.source = ['tutorial-star-routing.cc'] - - obj = bld.create_ns3_program('tutorial-linear-dumbbell', ['internet-stack', 'point-to-point']) - obj.source = 'tutorial-linear-dumbbell.cc' - - obj = bld.create_ns3_program('testipv4', ['node']) - obj.source = ['testipv4.cc'] - - obj = bld.create_ns3_program('tutorial-bus-network', ['internet-stack']) - obj.source = ['tutorial-bus-network.cc'] From f58dda2fcb3d06c14d00d2e1f35053d79cc73735 Mon Sep 17 00:00:00 2001 From: Craig Dowell Date: Sat, 28 Jun 2008 19:39:46 -0700 Subject: [PATCH 065/495] add updated tutorial examples --- examples/first.cc | 70 +++++++++++++++++++++ examples/second.cc | 92 ++++++++++++++++++++++++++++ examples/third.cc | 148 +++++++++++++++++++++++++++++++++++++++++++++ examples/wscript | 8 +++ wscript | 2 +- 5 files changed, 319 insertions(+), 1 deletion(-) create mode 100644 examples/first.cc create mode 100644 examples/second.cc create mode 100644 examples/third.cc diff --git a/examples/first.cc b/examples/first.cc new file mode 100644 index 000000000..74d7f54f3 --- /dev/null +++ b/examples/first.cc @@ -0,0 +1,70 @@ +/* -*- 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 + */ + +#include "ns3/core-module.h" +#include "ns3/simulator-module.h" +#include "ns3/node-module.h" +#include "ns3/helper-module.h" + +using namespace ns3; + +NS_LOG_COMPONENT_DEFINE ("FirstScriptExample"); + + int +main (int argc, char *argv[]) +{ + LogComponentEnable("UdpEchoClientApplication", LOG_LEVEL_INFO); + LogComponentEnable("UdpEchoServerApplication", LOG_LEVEL_INFO); + + NodeContainer nodes; + nodes.Create (2); + + PointToPointHelper pointToPoint; + pointToPoint.SetDeviceParameter ("DataRate", StringValue ("5Mbps")); + pointToPoint.SetChannelParameter ("Delay", StringValue ("2ms")); + + NetDeviceContainer devices; + devices = pointToPoint.Install (nodes); + + InternetStackHelper stack; + stack.Install (nodes); + + Ipv4AddressHelper address; + address.SetBase ("10.1.1.0", "255.255.255.0"); + + Ipv4InterfaceContainer interfaces = address.Assign (devices); + + UdpEchoServerHelper echoServer; + echoServer.SetPort (9); + + ApplicationContainer serverApps = echoServer.Install (nodes.Get (1)); + serverApps.Start (Seconds (1.0)); + serverApps.Stop (Seconds (10.0)); + + UdpEchoClientHelper echoClient; + echoClient.SetRemote (interfaces.GetAddress (1), 9); + echoClient.SetAppAttribute ("MaxPackets", UintegerValue (1)); + echoClient.SetAppAttribute ("Interval", TimeValue (Seconds (1.))); + echoClient.SetAppAttribute ("PacketSize", UintegerValue (1024)); + + ApplicationContainer clientApps = echoClient.Install (nodes.Get (0)); + clientApps.Start (Seconds (2.0)); + clientApps.Stop (Seconds (10.0)); + + Simulator::Run (); + Simulator::Destroy (); + return 0; +} diff --git a/examples/second.cc b/examples/second.cc new file mode 100644 index 000000000..03e77c5fd --- /dev/null +++ b/examples/second.cc @@ -0,0 +1,92 @@ +/* -*- 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 + */ + +#include "ns3/core-module.h" +#include "ns3/simulator-module.h" +#include "ns3/node-module.h" +#include "ns3/helper-module.h" +#include "ns3/global-routing-module.h" + +using namespace ns3; + +NS_LOG_COMPONENT_DEFINE ("SecondScriptExample"); + +int +main (int argc, char *argv[]) +{ + LogComponentEnable("UdpEchoClientApplication", LOG_LEVEL_INFO); + LogComponentEnable("UdpEchoServerApplication", LOG_LEVEL_INFO); + + uint32_t nCsma = 10; + CommandLine cmd; + cmd.AddValue ("nCsma", "number of csma devices", nCsma); + cmd.Parse (argc,argv); + + NodeContainer p2pNodes; + p2pNodes.Create (2); + + NodeContainer csmaNodes; + csmaNodes.Add (p2pNodes.Get (1)); + csmaNodes.Create (nCsma); + + PointToPointHelper pointToPoint; + pointToPoint.SetDeviceParameter ("DataRate", StringValue ("5Mbps")); + pointToPoint.SetChannelParameter ("Delay", StringValue ("2ms")); + + NetDeviceContainer p2pDevices; + p2pDevices = pointToPoint.Install (p2pNodes); + + CsmaHelper csma; + + NetDeviceContainer csmaDevices; + csmaDevices = csma.Install (csmaNodes); + + InternetStackHelper stack; + stack.Install (p2pNodes.Get (0)); + stack.Install (csmaNodes); + + Ipv4AddressHelper address; + address.SetBase ("10.1.1.0", "255.255.255.0"); + Ipv4InterfaceContainer p2pInterfaces; + p2pInterfaces = address.Assign (p2pDevices); + + address.SetBase ("10.1.2.0", "255.255.255.0"); + Ipv4InterfaceContainer csmaInterfaces; + csmaInterfaces = address.Assign (csmaDevices); + + UdpEchoServerHelper echoServer; + echoServer.SetPort (9); + + ApplicationContainer serverApps = echoServer.Install (csmaNodes.Get (5)); + serverApps.Start (Seconds (1.0)); + serverApps.Stop (Seconds (10.0)); + + UdpEchoClientHelper echoClient; + echoClient.SetRemote (csmaInterfaces.GetAddress (5), 9); + echoClient.SetAppAttribute ("MaxPackets", UintegerValue (1)); + echoClient.SetAppAttribute ("Interval", TimeValue (Seconds (1.))); + echoClient.SetAppAttribute ("PacketSize", UintegerValue (1024)); + + ApplicationContainer clientApps = echoClient.Install (p2pNodes.Get (0)); + clientApps.Start (Seconds (2.0)); + clientApps.Stop (Seconds (10.0)); + + GlobalRouteManager::PopulateRoutingTables (); + + Simulator::Run (); + Simulator::Destroy (); + return 0; +} diff --git a/examples/third.cc b/examples/third.cc new file mode 100644 index 000000000..8e79183a2 --- /dev/null +++ b/examples/third.cc @@ -0,0 +1,148 @@ +/* -*- 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 + */ + +#include "ns3/core-module.h" +#include "ns3/simulator-module.h" +#include "ns3/node-module.h" +#include "ns3/helper-module.h" +#include "ns3/global-routing-module.h" +#include "ns3/wifi-module.h" +#include "ns3/mobility-module.h" + +using namespace ns3; + +NS_LOG_COMPONENT_DEFINE ("ThirdScriptExample"); + +int +main (int argc, char *argv[]) +{ + LogComponentEnable("UdpEchoClientApplication", LOG_LEVEL_INFO); + LogComponentEnable("UdpEchoServerApplication", LOG_LEVEL_INFO); + + uint32_t nCsma = 10; + uint32_t nWifi = 10; + CommandLine cmd; + cmd.AddValue ("nCsma", "number of csma devices", nCsma); + cmd.AddValue ("nWifi", "number of wifi devices", nWifi); + cmd.Parse (argc,argv); + + NodeContainer p2pNodes; + p2pNodes.Create (2); + + PointToPointHelper pointToPoint; + pointToPoint.SetDeviceParameter ("DataRate", StringValue ("5Mbps")); + pointToPoint.SetChannelParameter ("Delay", StringValue ("2ms")); + + NetDeviceContainer p2pDevices; + p2pDevices = pointToPoint.Install (p2pNodes); + + NodeContainer csmaNodes; + csmaNodes.Add (p2pNodes.Get (1)); + csmaNodes.Create (nCsma); + + CsmaHelper csma; + + NetDeviceContainer csmaDevices; + csmaDevices = csma.Install (csmaNodes); + + NodeContainer wifiStaNodes; + wifiStaNodes.Create (nWifi); + NodeContainer wifiApNode = p2pNodes.Get (0); + + // setup the wifi channel: this is a log distance propagation model + // with a friis model as reference model for the log distance model. + Ptr channel = CreateObject (); + channel->SetPropagationDelayModel (CreateObject ()); + Ptr log = CreateObject (); + log->SetReferenceModel (CreateObject ()); + channel->SetPropagationLossModel (log); + + Ssid ssid = Ssid ("ns-3-ssid"); + WifiHelper wifi; + wifi.SetPhy ("ns3::WifiPhy"); + wifi.SetRemoteStationManager ("ns3::ArfWifiManager"); + // setup stas. + wifi.SetMac ("ns3::NqstaWifiMac", + "Ssid", SsidValue (ssid), + "ActiveProbing", BooleanValue (false)); + NetDeviceContainer staDevices; + staDevices = wifi.Install (wifiStaNodes, channel); + // setup ap. + wifi.SetMac ("ns3::NqapWifiMac", "Ssid", SsidValue (ssid), + "BeaconGeneration", BooleanValue (true), + "BeaconInterval", TimeValue (Seconds (2.5))); + NetDeviceContainer apDevices; + apDevices = wifi.Install (wifiApNode, channel); + + MobilityHelper mobility; + // layout the initial position of the nodes. + mobility.SetPositionAllocator ("ns3::GridPositionAllocator", + "MinX", DoubleValue (0.0), + "MinY", DoubleValue (0.0), + "DeltaX", DoubleValue (5.0), + "DeltaY", DoubleValue (10.0), + "GridWidth", UintegerValue (3), + "LayoutType", StringValue ("RowFirst")); + + mobility.SetMobilityModel ("ns3::RandomWalk2dMobilityModel", + "Bounds", RectangleValue (Rectangle (-50, 50, -50, 50))); + mobility.Install (wifiStaNodes); + mobility.SetMobilityModel ("ns3::StaticMobilityModel"); + mobility.Install (wifiApNode); + + InternetStackHelper stack; + stack.Install (csmaNodes); + stack.Install (wifiApNode); + stack.Install (wifiStaNodes); + + Ipv4AddressHelper address; + address.SetBase ("10.1.1.0", "255.255.255.0"); + Ipv4InterfaceContainer p2pInterfaces; + p2pInterfaces = address.Assign (p2pDevices); + + address.SetBase ("10.1.2.0", "255.255.255.0"); + Ipv4InterfaceContainer csmaInterfaces; + csmaInterfaces = address.Assign (csmaDevices); + + address.SetBase ("10.1.3.0", "255.255.255.0"); + address.Assign (staDevices); + address.Assign (apDevices); + + UdpEchoServerHelper echoServer; + echoServer.SetPort (9); + + ApplicationContainer serverApps = echoServer.Install (csmaNodes.Get (5)); + serverApps.Start (Seconds (1.0)); + serverApps.Stop (Seconds (10.0)); + + UdpEchoClientHelper echoClient; + echoClient.SetRemote (csmaInterfaces.GetAddress (5), 9); + echoClient.SetAppAttribute ("MaxPackets", UintegerValue (1)); + echoClient.SetAppAttribute ("Interval", TimeValue (Seconds (1.))); + echoClient.SetAppAttribute ("PacketSize", UintegerValue (1024)); + + ApplicationContainer clientApps = echoClient.Install (wifiStaNodes.Get (3)); + clientApps.Start (Seconds (2.0)); + clientApps.Stop (Seconds (10.0)); + + GlobalRouteManager::PopulateRoutingTables (); + + Simulator::Stop (Seconds (10.0)); + + Simulator::Run (); + Simulator::Destroy (); + return 0; +} diff --git a/examples/wscript b/examples/wscript index c3170a597..cb8f52ae3 100644 --- a/examples/wscript +++ b/examples/wscript @@ -1,6 +1,14 @@ ## -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*- def build(bld): + obj = bld.create_ns3_program('hello-simulator') + obj.source = 'hello-simulator.cc' + + obj = bld.create_ns3_program('second') + obj.source = 'second.cc' + + obj = bld.create_ns3_program('third') + obj.source = 'third.cc' obj = bld.create_ns3_program('mixed-wireless', ['core', 'simulator', 'mobility', 'wifi', 'point-to-point', 'internet-stack']) diff --git a/wscript b/wscript index 84fade74a..52856eeba 100644 --- a/wscript +++ b/wscript @@ -304,7 +304,7 @@ def build(bld): print "Entering directory `%s'" % os.path.join(Params.g_build.m_curdirnode.abspath(), 'build') # process subfolders from here bld.add_subdirs('src') - bld.add_subdirs('samples utils examples tutorial') + bld.add_subdirs('samples utils examples') add_scratch_programs(bld) From 5cf2aa1ebff8ce474928d943203d4931231e858d Mon Sep 17 00:00:00 2001 From: Craig Dowell Date: Sat, 28 Jun 2008 19:46:55 -0700 Subject: [PATCH 066/495] swap in new tutorial --- doc/tutorial/building-topologies.texi | 300 ++++++ doc/tutorial/conceptual-overview.texi | 809 +++++++++++++++ doc/tutorial/getting-started.texi | 275 +++++ doc/tutorial/{ => in-process}/Makefile | 0 doc/tutorial/{ => in-process}/attributes.texi | 0 doc/tutorial/{ => in-process}/figures/README | 0 .../{ => in-process}/figures/dumbbell.dia | Bin .../{ => in-process}/figures/helpers.obj | 0 .../{ => in-process}/figures/oneobj.png | Bin doc/tutorial/{ => in-process}/figures/pp.dia | Bin .../{ => in-process}/figures/star.dia | Bin .../{ => in-process}/figures/threeobj.png | Bin doc/tutorial/{ => in-process}/helpers.texi | 0 .../{ => in-process}/introduction.texi | 0 doc/tutorial/{ => in-process}/log.texi | 0 doc/tutorial/{ => in-process}/other.texi | 0 doc/tutorial/{ => in-process}/output.texi | 0 doc/tutorial/{ => in-process}/statistics.texi | 0 .../{ => in-process}/troubleshoot.texi | 0 doc/tutorial/in-process/tutorial.css | 156 +++ doc/tutorial/in-process/tutorial.texi | 105 ++ doc/tutorial/tutorial.texi | 31 +- doc/tutorial/tweaking.texi | 978 ++++++++++++++++++ examples/hello-simulator.cc | 27 + 24 files changed, 2660 insertions(+), 21 deletions(-) create mode 100644 doc/tutorial/building-topologies.texi create mode 100644 doc/tutorial/conceptual-overview.texi create mode 100644 doc/tutorial/getting-started.texi rename doc/tutorial/{ => in-process}/Makefile (100%) rename doc/tutorial/{ => in-process}/attributes.texi (100%) rename doc/tutorial/{ => in-process}/figures/README (100%) rename doc/tutorial/{ => in-process}/figures/dumbbell.dia (100%) rename doc/tutorial/{ => in-process}/figures/helpers.obj (100%) rename doc/tutorial/{ => in-process}/figures/oneobj.png (100%) rename doc/tutorial/{ => in-process}/figures/pp.dia (100%) rename doc/tutorial/{ => in-process}/figures/star.dia (100%) rename doc/tutorial/{ => in-process}/figures/threeobj.png (100%) rename doc/tutorial/{ => in-process}/helpers.texi (100%) rename doc/tutorial/{ => in-process}/introduction.texi (100%) rename doc/tutorial/{ => in-process}/log.texi (100%) rename doc/tutorial/{ => in-process}/other.texi (100%) rename doc/tutorial/{ => in-process}/output.texi (100%) rename doc/tutorial/{ => in-process}/statistics.texi (100%) rename doc/tutorial/{ => in-process}/troubleshoot.texi (100%) create mode 100644 doc/tutorial/in-process/tutorial.css create mode 100644 doc/tutorial/in-process/tutorial.texi create mode 100644 doc/tutorial/tweaking.texi create mode 100644 examples/hello-simulator.cc diff --git a/doc/tutorial/building-topologies.texi b/doc/tutorial/building-topologies.texi new file mode 100644 index 000000000..a78531b11 --- /dev/null +++ b/doc/tutorial/building-topologies.texi @@ -0,0 +1,300 @@ + +@c ======================================================================== +@c Begin document body here +@c ======================================================================== + +@c ======================================================================== +@c PART: Building Topologies +@c ======================================================================== +@c The below chapters are under the major heading "Building Topologies" +@c This is similar to the Latex \part command +@c +@c ======================================================================== +@c Building Topologies +@c ======================================================================== +@node Building Topologies +@chapter Building Topologies + +@menu +* Building a Star Topology +@end menu + +@c ======================================================================== +@c Building a Star Topology +@c ======================================================================== +@node Building a Star Topology +@section Building a Star Topology + +@cindex topology +@cindex topology|star +In this section we are going to use the point-to-point topology primitive we +have explored in quite some detail to construct a star network. In the star, +there is a central node that is connected to other nodes in a ``hub and spoke'' +fashion, with each ``spoke'' being a point-to-point link. + +We provide an example of a star topology simulation script on our +@code{examples} directory. Go ahead and open @code{examples/star.cc} in your +favorite editor. You will have already seen enough ns-3 code to understand +this example, but we will go over the script briefly and examine some of the +output. + +There is an amazingly beautiful bit of ASCII art at the beginning of the file +that shows the topology used in the script. Most ns-3 example programs +provide this, which can be surprisingly useful in understanding the code. + +@verbatim + // Network topology + // + // n3 n2 + // | / + // | / + // n4 --- n0 --- n1 + // / | + // / | + // n5 n6 +@end verbatim + +There are seven nodes in this simulation, nodes zero through six. Node zero is +the hub of this star network. We are going to discover that there will be a +flow of echo packets between node four and node one, between node three and +node six, and node five and node two. + +The script starts by creating seven nodes in a @code{NodeContainer} and +installs internet protocol stacks on all seven. + +@verbatim + int + main (int argc, char *argv[]) + { + NodeContainer nodes; + nodes.Create (7); + + InternetStackHelper stack; + stack.Install (nodes); + + ... +@end verbatim + +It then creates six more @code{NodeContainer}s representing the nodes at each +end of the six spokes. In all cases, the first node in the spoke is node zero. + +@verbatim + NodeContainer nodes0and1 = NodeContainer (nodes.Get (0), nodes.Get (1)); + NodeContainer nodes0and2 = NodeContainer (nodes.Get (0), nodes.Get (2)); + NodeContainer nodes0and3 = NodeContainer (nodes.Get (0), nodes.Get (3)); + NodeContainer nodes0and4 = NodeContainer (nodes.Get (0), nodes.Get (4)); + NodeContainer nodes0and5 = NodeContainer (nodes.Get (0), nodes.Get (5)); + NodeContainer nodes0and6 = NodeContainer (nodes.Get (0), nodes.Get (6)); +@end verbatim + +These node containers will be used during the creation of the point-to-point +links by the @code{PointToPointHelper}. The next bit of code instantiates +a helper and sets the default values for the device @code{DataRate} and the +channel @code{Delay} attributes as we have previously seen. + +@verbatim + PointToPointHelper pointToPoint; + pointToPoint.SetDeviceParameter ("DataRate", StringValue ("5Mbps")); + pointToPoint.SetChannelParameter ("Delay", StringValue ("2ms")); +@end verbatim + +The next step is to install the net devices on the nodes referenced by the +six node containers and connect them via channels. We used one instance +of the @code{pointToPoint.Install} method to construct our single +point-to-point link in the @code{first.cc} script. This code just does that +six times between different combinations of nodes. + +@verbatim + NetDeviceContainer devicesOnNodes0and1 = pointToPoint.Install (nodes0and1); + NetDeviceContainer devicesOnNodes0and2 = pointToPoint.Install (nodes0and2); + NetDeviceContainer devicesOnNodes0and3 = pointToPoint.Install (nodes0and3); + NetDeviceContainer devicesOnNodes0and4 = pointToPoint.Install (nodes0and4); + NetDeviceContainer devicesOnNodes0and5 = pointToPoint.Install (nodes0and5); + NetDeviceContainer devicesOnNodes0and6 = pointToPoint.Install (nodes0and6); +@end verbatim + +Note that this does mean that node zero will have six net devices after this +code executes. Recall that we need to keep containers holding the net devices +we created in order to do IP address assignment. This is the next step in the +script. + +Just as in @code{first.cc} we use the Ipv4AddressHelper to make it easy to +deal with addressing. We need to create different networks for each stub, so +we have to call the @code{SetBase} method and provide a different network +number before assigning addresses to the devices on each network. We make it +easy to remember what is what by setting the least significant bits of the +network number to the unique node on the spoke. For example, the spoke between +nodes zero and one is network 10.1.1; and the spoke between nodes zero and +two is 10.1.2, etc. Note that the network mask is set to 255.255.255.252 in +all cases. + +@verbatim + Ipv4AddressHelper ipv4; + + ipv4.SetBase ("10.1.1.0", "255.255.255.252"); + Ipv4InterfaceContainer interfacesOnNodes0and1 = + ipv4.Assign (devicesOnNodes0and1); + + ipv4.SetBase ("10.1.2.0", "255.255.255.252"); + Ipv4InterfaceContainer interfacesOnNodes0and2 = + ipv4.Assign (devicesOnNodes0and2); + + ipv4.SetBase ("10.1.3.0", "255.255.255.252"); + Ipv4InterfaceContainer interfacesOnNodes0and3 = + ipv4.Assign (devicesOnNodes0and3); + + ipv4.SetBase ("10.1.4.0", "255.255.255.252"); + Ipv4InterfaceContainer interfacesOnNodes0and4 = + ipv4.Assign (devicesOnNodes0and4); + + ipv4.SetBase ("10.1.5.0", "255.255.255.252"); + Ipv4InterfaceContainer interfacesOnNodes0and5 = + ipv4.Assign (devicesOnNodes0and5); + + ipv4.SetBase ("10.1.6.0", "255.255.255.252"); + Ipv4InterfaceContainer interfacesOnNodes0and6 = + ipv4.Assign (devicesOnNodes0and6); +@end verbatim + +When the above code has executed, we will have the topology complete and then +need to move on to applications. The code to do this should be familiar to +you, but we have rearranged it slightly. + +We use an ApplicationContainer to hold the results of the helper operations, +and use the UdpEchoServerHelper and UdpEchoClient server to configure the +apps just as we did in the @code{first.cc} script. + +@verbatim + uint16_t port = 9; + + ApplicationContainer apps; + + UdpEchoServerHelper server; + server.SetPort (port); + + UdpEchoClientHelper client; + client.SetAppAttribute ("MaxPackets", UintegerValue (10)); + client.SetAppAttribute ("Interval", StringValue ("10ms")); + client.SetAppAttribute ("PacketSize", UintegerValue (137)); +@end verbatim + +The next section of code is repeated three times, once for each data flow. +We'll skim over the first instance quickly. The other two differ only in +the nodes selected and the starting times of the flows. + +Just as we did in the @code{first.cc} script, we use the +@code{UdpEchoServerHelper} to install the echo server on a node (in this case, +node number one -- the rightmost spoke in the topology). We tell the server +application to start at a simulation time of one second. We use the +@code{UdpEchoClientHelper} to install the echo client on a node (in this case, +node number four -- the leftmost spoke in the topology). We tell the client +to start sending data at a simulation time of two seconds. + +@verbatim + // + // Echo from node 4 to node 1 starting at 2 sec + // + apps = server.Install (nodes.Get (1)); + apps.Start (Seconds (1.0)); + + client.SetRemote (interfacesOnNodes0and1.GetAddress (1), port); + apps = client.Install (nodes.Get (4)); + apps.Start (Seconds (2.0)); +@end verbatim + +The next sections do the same thing, but for nodes three and six with a flow +starting at 2.1 seconds, and for nodes five and two with flow starting at 2.2 +seconds. + +The only piece of code you may not have seen before follows. Since we have +built an internetwork, we need some form of internetwork routing. Ns-3 +provides what we call a global route manager to set up the routing tables on +nodes. This route manager has a global function that runs though the nodes +of the simulation and does the hard work of setting up routing for you. + +Basically, what happens is that each node behaves as if it were an OSPF router +that communicates instantly and magically with all other routers. Each node +generates link advertisements to the global route manager, which uses this +information to construct the routing tables for each node. + +@verbatim + GlobalRouteManager::PopulateRoutingTables (); +@end verbatim + +The remainder of the script should be very familiar to you. We just enable +ASCII and pcap tracing and run the simulation: + +@verbatim + std::ofstream ascii; + ascii.open (``star.tr''); + PointToPointHelper::EnableAsciiAll (ascii); + PointToPointHelper::EnablePcapAll (``star''); + + Simulator::Run (); + Simulator::Destroy (); + } +@end verbatim + +In order to run this example, you use waf. All of our example programs are +built by default, so all you have to do is run it. Now, you did not build +this script by copying it into the scratch directory, so you don't have to +add the scratch directory to the run command. You just do the following, + +@verbatim + ./waf --run star +@end verbatim + +There is no output from this script by default. It will just go off and +silently do its thing. All you will see are waf messages: + +@verbatim + ~/repos/ns-3-tutorial > ./waf --run star + Entering directory `/home/craigdo/repos/ns-3-tutorial/build' + Compilation finished successfully + ~/repos/ns-3-tutorial > +@end verbatim + +If you now go and look in the top level directory, you will find a number of +trace files: + +@verbatim + ~/repos/ns-3-tutorial > ls *.pcap *.tr + star-0-0.pcap star-0-3.pcap star-1-0.pcap star-4-0.pcap star.tr + star-0-1.pcap star-0-4.pcap star-2-0.pcap star-5-0.pcap + star-0-2.pcap star-0-5.pcap star-3-0.pcap star-6-0.pcap + ~/repos/ns-3-tutorial > +@end verbatim + +If you have gone through the tracing section of this tutorial, you know how to +interpret all of these files. For your reading pleasure, we reproduce a +tcpdump from the net device on node four: + +@verbatim + [ns-regression] ~/repos/ns-3-tutorial > tcpdump -r star-4-0.pcap -nn -tt + reading from file star-4-0.pcap, link-type PPP (PPP) + 2.000000 IP 10.1.4.2.49153 > 10.1.1.2.9: UDP, length 137 + 2.009068 IP 10.1.1.2.9 > 10.1.4.2.49153: UDP, length 137 + 2.010000 IP 10.1.4.2.49153 > 10.1.1.2.9: UDP, length 137 + 2.019068 IP 10.1.1.2.9 > 10.1.4.2.49153: UDP, length 137 + 2.020000 IP 10.1.4.2.49153 > 10.1.1.2.9: UDP, length 137 + 2.029068 IP 10.1.1.2.9 > 10.1.4.2.49153: UDP, length 137 + 2.030000 IP 10.1.4.2.49153 > 10.1.1.2.9: UDP, length 137 + 2.039068 IP 10.1.1.2.9 > 10.1.4.2.49153: UDP, length 137 + 2.040000 IP 10.1.4.2.49153 > 10.1.1.2.9: UDP, length 137 + 2.049068 IP 10.1.1.2.9 > 10.1.4.2.49153: UDP, length 137 + 2.050000 IP 10.1.4.2.49153 > 10.1.1.2.9: UDP, length 137 + 2.059068 IP 10.1.1.2.9 > 10.1.4.2.49153: UDP, length 137 + 2.060000 IP 10.1.4.2.49153 > 10.1.1.2.9: UDP, length 137 + 2.069068 IP 10.1.1.2.9 > 10.1.4.2.49153: UDP, length 137 + 2.070000 IP 10.1.4.2.49153 > 10.1.1.2.9: UDP, length 137 + 2.079068 IP 10.1.1.2.9 > 10.1.4.2.49153: UDP, length 137 + 2.080000 IP 10.1.4.2.49153 > 10.1.1.2.9: UDP, length 137 + 2.089068 IP 10.1.1.2.9 > 10.1.4.2.49153: UDP, length 137 + 2.090000 IP 10.1.4.2.49153 > 10.1.1.2.9: UDP, length 137 + 2.099068 IP 10.1.1.2.9 > 10.1.4.2.49153: UDP, length 137 + [ns-regression] ~/repos/ns-3-tutorial > +@end verbatim + +You are encouraged to think through the pcap traces and map them back to the +script. Also, take a look at the @code{star.tr} ASCII trace file (which is +quite large) to make sure you understand what it is telling you. diff --git a/doc/tutorial/conceptual-overview.texi b/doc/tutorial/conceptual-overview.texi new file mode 100644 index 000000000..10130f322 --- /dev/null +++ b/doc/tutorial/conceptual-overview.texi @@ -0,0 +1,809 @@ + +@c ======================================================================== +@c Begin document body here +@c ======================================================================== + +@c ======================================================================== +@c PART: Conceptual Overview +@c ======================================================================== +@c The below chapters are under the major heading "Getting Started" +@c This is similar to the Latex \part command +@c ======================================================================== +@c Some Conceptual Overview +@c ======================================================================== +@node Conceptual Overveiw +@chapter Conceptual Overview + +@menu +* Key Abstractions:: +@end menu + +The first thing we need to do before actually starting to look at or write +ns-3 code is to explain a few core concepts, abstractions and idioms in the +system. Much of this may appear transparently obvious to some, but we +recommend taking the time to read through this chapter just to ensure you +are starting on a firm foundation. + +@node Key Abstractions +@section Key Abstractions + +In this section, we'll review some terms that are commonly used in +networking, but have a specific meaning in ns-3. + +@subsection Node +@cindex Node +In Internet jargon, a computing device that connects to a network is called +a @emph{host} or sometimes an @emph{end system}. Because ns-3 is a +@emph{network} simulator, not specifically an @emph{Internet} simulator, we +intentionally do not use the term host since it is closely associated with +the Internet and its protocols. Instead, we use a more generic term also +used by other simulators that originates in Graph Theory --- the @emph{node}. + +@cindex Node!class +In ns-3 the basic computing device abstraction is called the +node. This abstraction is represented in C++ by the class @code{Node}. The +@code{Node} class provides methods for managing the representations of +computing devices in simulations. Developers are expected to specialize the +@code{Node} in the object-oriented programming sense to create new computing +device models. In this tutorial, we will use a specialization of class +@code{Node} called @code{InternetNode}. As you might expect, the +@code{InternetNode} is a class that represents a host in the Internet sense, +and automatically provides core IPv4 networking protocols. + +You should think of a @code{Node} as a computer to which you will add +functionality. One adds things like applications, protocol stacks and +peripheral cards with their associated drivers to enable the computer to do +useful work. We use the same basic model in ns-3. + +@subsection Application +@cindex Application +Typically, computer software is divided into two broad classes. @emph{System +Software} organizes various computer resources such as memory, processor +cycles, disk, network, etc., according to some computing model. System +software usually does not use those resources to complete tasks that directly +benefit a user. A user would typically run an @emph{application} that acquires +and uses the resources controlled by the system software to accomplish some +goal. + +@cindex system call +Often, the line of separation between system and application software is made +at the privilege level change that happens in operating system traps. +In ns-3 there is no real concept of operating system and especially +no concept of privilege levels or system calls. We do, however, have the +idea of an application. Just as software applications run on computers to +perform tasks in the ``real world,'' ns-3 applications run on +ns-3 @code{Node}s to drive simulations in the simulated world. + +@cindex Application!class +In ns-3 the basic abstraction for a user program that generates some +activity to be simulated is the application. This abstraction is represented +in C++ by the class @code{Application}. The @code{Application} class provides +methods for managing the representations of our version of user-level +applications in simulations. Developers are expected to specialize the +@code{Application} in the object-oriented programming sense to create new +applications. In this tutorial, we will use specializations of class +@code{Application} called @code{UdpEchoClient} and @code{UdpEchoServer}. +As you might expect, these applications compose a client/server application set +used to generate and echo simulated network packets + +@subsection Channel +@cindex Channel + +In the real world, one can connect a computer to a network. Often the media +over which data flows in these netowrks are called @emph{channels}. When +you connect your Ethernet cable to the plug in the wall, you are connecting +your computer to an Ethernet communication channel. In the simulated world +of ns-3 one connects a @code{Node} to an object representing a +communication channel. Here the basic communication subnetwork abstraction +is called the channel and is represented in C++ by the class @code{Channel}. + +The @code{Channel} class provides methods for managing communication +subnetwork objects and connecting nodes to them. They may also be specialized +by developers in the object oriented programming sense. A @code{Channel} +specialization may model something as simple as a wire. The specialized +@code{Channel} can also model things as complicated as a large Ethernet +switch, or three-dimensional space in the case of wireless networks. + +We will use specialized versions of the @code{Channel} called +@code{CsmaChannel} and @code{PointToPointChannel} in this tutorial. The +@code{CsmaChannel}, for example, models a version of a communication subnetwork +that implements a @emph{carrier sense multiple access} communication medium. +This gives us Ethernet-like functionality. + +@subsection Net Device +@cindex NetDevice +@cindex Ethernet +It used to be the case that if you wanted to connect a computers to a network, +you had to buy a specific kind of network cable and a hardware device called +(in PC terminology) a @emph{peripheral card} that needed to be installed in +your computer. These cards were called Network Interface Cards, or +@emph{NIC}s. Today most computers come with the network controller hardware +built in and users don't see these building blocks. + +A NIC will not work without a software driver to control the hardware. In +Unix (or Linux), a piece of peripheral hardware is classified as a +@emph{device}. Devices are controlled using @emph{device drivers}, and network +devices (NICs) are controlled using @emph{network device drivers} +collectively known as @emph{net devices}. In Unix and Linux you refer +to these net devices by names such as @emph{eth0}. + +In ns-3 the @emph{net device} abstraction covers both the software +driver and the simulated hardware. A net device is ``attached'' to a +@code{Node} in order to enable the @code{Node} to communicate with other +@code{Node}s in the simulation via @code{Channel}s. Just as in a real +computer, a @code{Node} may be connected to more than one @code{Channel} via +multiple @code{NetDevice}s. + +The net device abstraction is represented in C++ by the class @code{NetDevice}. +The @code{NetDevice} class provides methods for managing connections to +@code{Node} and @code{Channel} objects; and may be specialized by developers +in the object-oriented programming sense. We will use the specialized version +of the @code{NetDevice} called the @code{CsmaNetDevice} in this tutorial. +Just as an Ethernet NIC is designed to work with an Ethernet network, the +@code{CsmaNetDevice} is designed to work with a @code{CsmaChannel}. + +@subsection Topology Helpers +@cindex helper +@cindex topology +@cindex helper|topology +In a real network, you will find host computers with added (or built-in) +NICs. In ns-3 we would say that you will find @code{Nodes} with +attached @code{NetDevices}. In a large simulated network you will need to +arrange many connections between @code{Node}s, @code{NetDevice}s and +@code{Channel}s. + +Since connecting @code{NetDevice}s to @code{Node}s, @code{NetDevice}s +to @code{Channel}s, assigning IP addresses, etc., are such common tasks +in ns-3 we provide what we call @emph{topology helpers} to make this as easy +as possible. For example, will take several distinct ns-3 core operations +to create a NetDevice, add a MAC address, connect the net device to a +@code{Node}, configure the protocol stack, and then connect the +@code{NetDevice} to a @code{Channel}. More higher level operations would be +required to connect multiple devices onto multipoint channels and then to +connect networks together into internetworks. We use topology helper objects +to compose those distinct operations into an easy to use model. + +@c ======================================================================== +@c A First ns-3 script +@c ======================================================================== +@node A First ns-3 Script +@chapter A First ns-3 script +@cindex first script +If you downloaded the system as was suggested above, you will have a release +of ns-3 in a directory called @code{repos} under your home directory. Change +into that release directory, and you should find a directory structure +something like the following: + +@verbatim + AUTHORS examples/ README samples/ tutorial/ waf* + build/ LICENSE regression/ scratch/ utils/ waf.bat* + doc/ ns3/ RELEASE_NOTES src/ VERSION wscript +@end verbatim + +@cindex first.cc +Change into the examples directory. You should see a file named +@code{first.cc} located there. This is a script that will create a simple +point-to-point link between two nodes and echo a single packet between the +nodes. Let's take a look at the script line by line. + +The first line in the file is an emacs mode line. This tells emacs about the +formatting conventions (coding style) we use in our source code. + +@verbatim + /* -*- Mode:C++; c-file-style:''gnu''; indent-tabs-mode:nil; -*- */ +@end verbatim + +This is always a somewhat controversial subject, so we might as well get it +out of the way immediately. The ns-3 project, like most large projects, has +adopted a coding style to which all contributed code must adhere. If you want +to contribute your code to the project, you will eventually have to conform to +the ns-3 coding style as described in INSERT LINK TO CODING STYLE PAGE ON WEB. +The emacs mode line above makes it easier to get the formatting correct if you +use the emacs editor. + +The ns-3 simulator is licentsed using the GNU General Public License. You +will see the appropriate GNU legalese at the head of every file in the ns-3 +distribution. + +@verbatim + /* + * 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 + */ +@end verbatim + +@section Module Includes +The code proper starts with a number of include statements. To help our high +level users deal with the large number of include files present in the system, +we group includes according to relatively large modules. We provide a single +include file that, in turn, includes all of the include files used in each +module. Rather than having to look up exactly what header you need, and +possibly have to get dependencies right, we give you the ability to load a +group of files at a large granularity. This is not the most efficient approach +but it certainly makes writing scripts much easier. Each of the ns-3 files +is placed in a directory called @code{ns3} to help with include file name +collisions. + +@verbatim + #include "ns3/core-module.h" + #include "ns3/simulator-module.h" + #include "ns3/node-module.h" + #include "ns3/helper-module.h" +@end verbatim + +The @code{ns3/core-module.h} file corresponds to the ns-3 module you will find +in the directory @code{src/core} in your downloaded release distribution. If +you list this directory you will find a large number of header files. When +you do a build, Waf will place public header files in an @code{ns3} directory +under the appropriate @code{build/debug} or @code{build/optimized} directory +depending on your configuration. Waf will also automatically generate a module +include file to load all of the public header files. Since you are following +this tutorial perfectly, you will have done a + +@verbatim + ./waf -d debug configure +@end verbatim + +to configure the project to perform debug builds. You will also have done a, + +@verbatim + ./waf +@end verbatim + +to build the project. So if you look in the directory @code{build/debug/ns-3} +you will find the four module includes shown above. + +@section Ns3 Namespace +The next line in the @code{first.cc} script is a namespace statement: + +@verbatim + using namespace ns3; +@end verbatim + +The ns-3 project is implemented in a C++ namespace called @code{ns3}. This +groups all ns-3-related declarations in a scope outside the global namespace +which we hope will help with integration with other code. The C++ @code{using} +statement introduces the ns-3 namespace into the current (global) declarative +region. This is a fancy way of saying that after this declaration, you will +not have to type @code{ns3::} before all of the ns-3 code in order to use it. +If you are unfamiliar with namespaces, please consult almost any C++ tutorial +and compare the ns3 namespace and usage here with the std namespace and +a @code{using namespace std;} statement. + +@section Logging +The next line of the script is the following, + +@verbatim + NS_LOG_COMPONENT_DEFINE ("FirstScriptExample"); +@end verbatim + +We will use this statement as a convenient place to talk about our Doxygen +documentation system. If you look at the project web site, +@uref{http://www.nsnam.org,,ns-3 project}, you will find a link to ``Other +Documentation'' in the navigation bar. If you select this link, you will be +taken to our documentation page. You will find links to our development +@code{ns-3-dev} documentation as well as that for our latest release. If you +select the @code{HTML} link you will be taken to the Doxygen documentation for +that version. + +Along the left side, you will find a graphical representation of the structure +of the documentation. A good place to start is the @code{NS-3 Modules} +``book.'' If you expand @code{Modules} you will see a list of ns-3 module +documentation. The concept of module here ties directly into the module +include files discussed above. It turns out that the ns-3 logging subsystem +is part of the @code{core} module, so go ahead and expand that node. Now, +open the @code{Debugging} book and then select the @code{Logging} page. + +You should now be looking at the Doxygen documentation for the Logging module. +In the list of @code{#define}s you will see @code{NS_LOG_COMPONENT_DEFINE}. +It would probably be good to look for the ``Detailed Description'' of the +logging module now to get a feel for the overall operation and then look at +the specific @code{NS_LOG_COMPONENT_DEFINE} documentation. I won't duplicate +the documentation here, but to summarize, this line declares a logging +component called @code{FirstScriptExample} that allows you to enable and +disable console message logging by reference to the name. + +The next lines of the script you will find are: + +@verbatim + int + main (int argc, char *argv[]) + { +@end verbatim + +This is just the declaration of the main function of your program. Just as in +any C++ program, you need to define a main function that will be the first +function run. There is nothing at all special here. Your ns-3 script is just +a C++ program. + +The next two lines of the script are used to enable two logging components that +are built into the Echo Client and Echo Server applications: + +@verbatim + LogComponentEnable("UdpEchoClientApplication", LOG_LEVEL_INFO); + LogComponentEnable("UdpEchoServerApplication", LOG_LEVEL_INFO); +@end verbatim + +If you have read over the Logging component documentation you will see that +there are a number of levels of detail that you enable on each component. +These two lines of code enable debug logging at the INFO level for echo +clients and servers. This will result in the application printing out +a message as packets are sent and received. + +Now we will get directly to the business of creating a topology and running +a simulation. We will use the topology helper objects to make this job as +easy as possible. + +@section Topology Helpers +@subsection NodeContainer +The next two lines of code in our script will actually create the ns-3 objects +that will represent the computers in the simulation. + +@verbatim + NodeContainer nodes; + nodes.Create (2); +@end verbatim + +Let's find the documentation for the first object before we continue. Another +way to get into the documentation system is via the @code{Classes} tab in the +HTML pages. If you still have the Doxygen handy, just scroll up to the top +of the page and select the @code{Classes} tab. You should see a new set of +tabs appear, one of which is @code{Class List}. Under that tab you will see +a list of all of the ns-3 classes. Scroll down, looking for +@code{ns3::NodeContainer}. When you find the class, go ahead and select it to +go to the Doxygen. + +You may recall that one of our key abstractions is the @code{Node}. This +represents a computer to which we are going to add things like protocol stacks, +applications and peripheral cards. The @code{NodeContainer} topology helper +provides a convenient way to create, manage and access any @code{Node} objects +that we create in order to run a simulation. The first line just declares a +NodeContainer which we call @code{nodes}. The second line calls the +@code{Create} method on the @code{nodes} object and asks the container to +create two nodes. As described in the Doxygen, the container calls down into +the ns-3 system to create two @code{Node} objects and stores the pointers +internally. + +The nodes as they stand at this point in the script do nothing. The next step +in constructing a topology is to connect our nodes together into a network. +The simplest form of network is a single point-to-point link between two nodes +so we'll construct one here. + +@subsection PointToPointHelper +We are constructing a point to point link, and in a pattern which will become +quite familiar to you, we use a topology helper object to do the low-level +work required to put the link together. Recall that two of our key +abstractions are the @code{NetDevice} and the @code{Channel}. In the real +world, this corresponds roughly to peripheral cards and network cables. +Typically these two things are intimately tied together and one cannot expect +to interchange Ethernet devices and wireless channels, for example. Our +Topology Helpers follow this intimate coupling and therefore you will use a +single @code{PointToPointHelper} to configure and connect ns-3 +@code{PointToPointNetDevice} and @code{PointToPointChannel} objects in this +script. + +The next three lines in the @code{first.cc} script are + +@verbatim + PointToPointHelper pointToPoint; + pointToPoint.SetDeviceParameter ("DataRate", StringValue ("5Mbps")); + pointToPoint.SetChannelParameter ("Delay", StringValue ("2ms")); +@end verbatim + +The first line + +@verbatim + PointToPointHelper pointToPoint; +@end verbatim + +creates a @code{PointToPointHelper} object on the stack. + +From a high-level perspective the next line, + +@verbatim + pointToPoint.SetDeviceParameter ("DataRate", StringValue ("5Mbps")); +@end verbatim + +tells the @code{PointToPointHelper} object to use the value ``5mbps'' +(five megabits per second) as the ``DataRate'' when it creates a +@code{PointToPointNetDevice} object. + +From a more detailed perspective, the string ``DataRate'' corresponds +to what we call an @code{Attribute} of the @code{PointToPointNetDevice}. +If you look at the Doxygen for class @code{ns3::PointToPointNetDevice} and +find the documentation for the @code{GetTypeId} method, you will find a list +of @code{Attributes} defined for the device. Among these is the ``DataRate'' +attribute. Most user-visible ns-3 objects have similar lists of attributes. +We use this mechanism to easily configure simulations without recompiling +as you will see in a following section. + +Similar to the ``DataRate'' on the @code{PointToPointNetDevice} we find a +``Delay'' attribute associated with the @code{PointToPointChannel}. THe +final line, + +@verbatim + pointToPoint.SetChannelParameter ("Delay", StringValue ("2ms")); +@end verbatim + +Tells the @code{PointToPointHelper} to use the value ``2ms'' (two milliseconds) +as the value of the transmission delay of every point to point channel it +creates. + +@subsection NetDeviceContainer +At this point in the script, we have a @code{NodeContainer} that contains +two nodes. We have a @code{PointToPointHelper} that is primed and ready to +make @code{PointToPointNetDevices} and wire @code{PoiintToPointChannel} objects +between them. Just as we used the @code{NodeContainer} topology helper object +to create the @code{Node}s for our simulation, we will ask the +@code{PointToPointHelper} to do the work involved in creating, configuring and +installing our devices for us. We will need to have a list of all of the +NetDevice objects that are created, so we use a NetDeviceContainer to hold +them just as we used a NodeContainer to hold the nodes we created. The +following two lines of code, + +@verbatim + NetDeviceContainer devices; + devices = pointToPoint.Install (nodes); +@end verbatim + +will finish configuring the devices and channel. The first line declares the +device container mentioned above and the second does the heavy lifting. The +@code{Install} method of the @code{PointToPointHelper} takes a +@code{NodeContainer} as a parameter. Internally, a @code{NetDeviceContainer} +is created. For each node in the @code{NodeContainer} (there must be exactly +two for a point-to-point link) a @code{PointToPointNetDevice} is created and +saved in the device container. A @code{PointToPointChannel} is created and +the two @code{PointToPointNetDevices} are attached. When objects are created +by the @code{PointToPointHelper} the attributes previously set in the helper +are used to initialize the corresponding attributes in the created objects. + +After executing the the @code{pointToPoint.Install (nodes)} call we will have +two nodes, each with an installed point-to-point net device and a +point-to-point channel between them. Both devices will send data at five +megabits per second over the channel which has a two millisecond transmission +delay. + +@subsection InternetStackHelper +We have nodes and devices configured, but we don't have any protocol stacks +installed on our nodes. The next two lines of code take care of that. + +@verbatim + InternetStackHelper stack; + stack.Install (nodes); +@end verbatim + +The @code{InternetStackHelper} is a topology helper that is to internet stacks +what the @code{PointToPointHelper} is to point-to-point net devices. The +@code{Install} method takes a @code{NodeContainer} as a parameter. When it is +executed, it will install an Internet Stack (TCP, UDP, IP, etc.) on each of +the nodes in the node container. + +@subsection Ipv4AddressHelper +Next we need to associate the devices on our nodes with IP addresses. We +provide a topology helper to manage the allocation of IP addresses. The only +user-visible API is to set the base IP address and network mask to use when +performing the actual address allocation (which is done at a lower level in the +code). + +The next two lines of code in our example script, @code{first.cc}, + +@verbatim + Ipv4AddressHelper address; + address.SetBase ("10.1.1.0", "255.255.255.0"); +@end verbatim + +declare an address helper object and tell it that it should begin allocating IP +addresses from the network 10.1.1.0 using the mask 255.255.255.0 to define +the allocatable bits. + +The next line of code, + +@verbatim + Ipv4InterfaceContainer interfaces = address.Assign (devices); +@end verbatim + +performs the actual address assignment. In ns-3 we make the association +between an IP address and a device using an @code{Ipv4Interface} object. +Just as we sometimes need a list of net devices created by a helper for future +reference we sometimes need a list of @code{Ipv4Interface} objects. The +@code{Ipv4InterfaceContainer} provides this functionality. + +Now we have a point-to-point network made with IP addresses assigned. What +we need at this point are applications to generate traffic. + +@section Applications +Another one of the core abstractions of the ns-3 system is the +@code{Application}. In this script we use two specializations of the core +ns-3 class @code{Application} called @code{UdpEchoServerApplication} and +@code{UdpEchoClientApplication}. Just as in the previous instances of ns-3 +objects, we use helper objects to help configure and manage the underlying +objects. Here, we use @code{UdpEchoServerHelper} and +@code{UdpEchoClientHelper} objects to make our lives easier. + +@subsection UdpEchoServerHelper +The following lines of code in our example script, @code{first.cc}, are used +to set up a UDP echo server application on one of the nodes we have previously +created and connected using a point-to-point link. + +@verbatim + UdpEchoServerHelper echoServer; + echoServer.SetPort (9); + + ApplicationContainer serverApps = echoServer.Install (nodes.Get (1)); + serverApps.Start (Seconds (1.0)); + serverApps.Stop (Seconds (10.0)); +@end verbatim + +The first line of code in the above snippet declares the +@code{UdpEchoServerHelper}. As usual, this isn't the application itself, it +is an object to help us create the actual applications. The second line +that has the @code{SetPort} call, is used to tell the helper to assign the +value nine to the ``Port'' attribute when creating +@code{UdpEchoServerApplication} objects. + +Similar to many other helper objects, the @code{UdpEchoServerHelper} object +has an @code{Install} method. It is the execution of this method that actually +causes the underlying echo server application to be instantiated and attached +to a node. Interestingly, the @code{Install} method takes a +@code{NodeContainter} as a parameter just as the other @code{Install} methods +we have seen. This is actually what is passed to the method even though it +doesn't look so in this case. It will be worth a slight digression +to undersand what is going on here. + +@subsubsection Implicit Conversions +This is an example of a C++ @code{implicit conversion} at work. Many +programmers use implicit conversions without even realizing it since they are +sometimes so intuitive. For example, in the following code, + +@verbatim + int i = 1; + double d = 2.; + if (n == d) ... +@end verbatim + +@cindex standard conversion +the integer (1) is implicitly converted to a double (1.) before the comparison +takes place. This conversion is performed using what is known as a C++ +@emph{standard conversion}. + +C++ will try to determine a sequence of type conversions to use in order to +convert an argument in a function call to the type of a corresponding paramter +in a method declaration. The method call in this case is, + +@verbatim + ApplicationContainer serverApps = echoServer.Install (nodes.Get (1)); +@end verbatim + +If you look at the declaration of the Install method in the source (or the +Doxygen) you will see, + +@verbatim + ApplicationContainer + UdpEchoServerHelper::Install (NodeContainer c) + { + ... + } +@end verbatim + +Now, the @code{Get} method of the @code{NodeContainer} returns a smart pointer +to a node object: + +@verbatim + Ptr + NodeContainer::Get (uint32_t i) const + { + ... + } +@end verbatim + +C++ notices that it needs to convert a type @code{Ptr} into a type +@code{NodeContainer}. It turns out that @code{NodeContainer} has a +constructor that takes a @code{Ptr} as a parameter. + +@verbatim + NodeContainer::NodeContainer (Ptr node) + { + ... + } +@end verbatim + +The C++ compiler implicitly provides the @code{Ptr} returned from the +@code{NodeContainer::Get} to the above constructor for @code{NodeContainer} to +make a new @code{NodeContainer} to pass to the @code{Install} method of the +@code{UdpEchoServerHelper} object. + +Taking advantage of these implicit conversion sequences can allow you to +avoid doing a lot of typing. The result is also fairly intuitive if you +don't pay close attention to the called method signatures. If you are +one of those folks that pays close attention, it does have the downside of +sometimes being surprising when you, for example, look for the method +in @code{UdpEchoServerHelper} named @code{Install} that takes a parameter +@code{Ptr} and cannot find it. + +@subsection UdpEchoServerHelper Continued +Returning to the example script, we are looking at the following code snippet. + +@verbatim + UdpEchoServerHelper echoServer; + echoServer.SetPort (9); + + ApplicationContainer serverApps = echoServer.Install (nodes.Get (1)); + serverApps.Start (Seconds (1.0)); + serverApps.Stop (Seconds (10.0)); +@end verbatim + +We now see that @code{echoServer.Install} is going to install an +@code{UdpEchoServerApplication} on the node found at index number one of the +@code{NodeContainer} we use to manage our nodes. @code{Install} will return +a container that has all of the applications (one in this case since we passed +a @code{NodeContainer} containing one node) made by the helper. + +Applications require a time to ``start'' generating traffic and a time to +``stop.'' These times are set using @code{ApplicationContainer} methods +@code{Start} and @code{Stop}. These methods take @code{Time} parameters. +In this case, we use an explicit conversion sequence to take a c++ double +1.0 and convert it to a @code{Time} object using a @code{Seconds ()} cast. +The two lines, + +@verbatim + serverApps.Start (Seconds (1.0)); + serverApps.Stop (Seconds (10.0)); +@end verbatim + +will cause the echo server application to @code{Start} (enable itself) at one +second into the simulation and to @code{Stop} (disable itself) at ten seconds +into the simulation. By virtue of the fact that we have implicilty declared +a simulation event at ten seconds, the simulation will last at least ten +seconds. + +@subsection UdpEchoClientHelper + +The echo client application is set up in a method similar to the server. +There is an underlying @code{UdpEchoClientApplication} that is managed by an +@code{UdpEchoClientHelper}. + +@verbatim + UdpEchoClientHelper echoClient; + echoClient.SetRemote (interfaces.GetAddress (1), 9); + echoClient.SetAppAttribute ("MaxPackets", UintegerValue (1)); + echoClient.SetAppAttribute ("Interval", TimeValue (Seconds (1.))); + echoClient.SetAppAttribute ("PacketSize", UintegerValue (1024)); + + ApplicationContainer clientApps = echoClient.Install (nodes.Get (0)); + clientApps.Start (Seconds (2.0)); + clientApps.Stop (Seconds (10.0)); +@end verbatim + +For the echo client, we need to set four different attributes. The first +attribute is set using the @code{SetRemote} method. Here we refer back to +the @code{Ipv4InterfaceContainer} we created to keep track of the IP addresses +we assigned to our devices. + +@verbatim + Ipv4InterfaceContainer interfaces = address.Assign (devices); +@end verbatim + +In this case, the zeroth interface in the @code{interfaces} container +cooresponds to the IP address of the zeroth node in the @code{nodes} container. +The first interface in the @code{interfaces} container cooresponds to the IP +address of the first node in the @code{nodes} container. So, in the following +line of code, we are setting the remote address of the client to be the IP +address assigned to the node on which the server resides. We tell it to send +to port nine. + +@verbatim + echoClient.SetRemote (interfaces.GetAddress (1), 9); +@end verbatim + +The ``MaxPackets'' attribute tells the client the maximum number of packets +it can send. The ``Interval'' attribute tells the cleint how long to wait +between packets and the ``PacketSize'' attribute tells the client how large +its packets should be. In this case we are telling the client to send one +1024-byte packet. + +Just as in the case of the echo server, we tell the echo client to @code{Start} +and @code{Stop}, but here we start the client one second after the server is +enabled (at two seconds into the simulation). + +@subsection Simulator +What we need to do at this point is to actually run the simulation. This is +done using the @code{Simulator} singleton which is accessed via the global +function @code{Simulator::Run} + +@verbatim + Simulator::Run (); +@end verbatim + +When we called the methods, + +@verbatim + serverApps.Start (Seconds (1.0)); + serverApps.Stop (Seconds (10.0)); + ... + clientApps.Start (Seconds (2.0)); + clientApps.Stop (Seconds (10.0)); +@end verbatim + +we actually scheduled events in the simulator at 1.0 seconds, 2.0 seconds and +10.0 seconds. When @code{Simulator::Run} is called, it will begin looking +through the list of scheduled events and executing them. First it will run +the event at 1.0 seconds, which will enable the echo server application. Then +it will run the event scheduled for t=2.0 seconds which will start the echo +client application. The start event implementation in the echo cleint will +begin the data transfer phase of the simulation by sending a packet to the +server. + +The act of sending the packet to the server will trigger a chain of events +which will be automatically scheduled and which will perform the packet echo +according to the various timing parameters that we have set in the script. + +Eventually, since we only sent one packet, the chain of events triggered by +the single client echo request will taper off and the simulation will go +idle. Once this happens, the remaining events are the @code{Stop} events +for the server and the client. When these events are executed, there are +no further events to process and @code{Simulator::Run} returns. The simulation +is complete. + +All that remains is to clean up after ourselves. This is done by calling the +global function @code{Simulator::Destroy}. As the helper functions (or low +level ns-3 code) executed they arranged it so that hooks were inserted in the +simulator to destruct all of the objects that were created. You do not have +to keep track of all of these objects yourself --- all you have to do is to +call @code{Simulator::Destroy} and exit. The remaining lines of our first +ns-3 script, @code{first.cc}, do just that + +@verbatim + Simulator::Destroy (); + return 0; + } +@end verbatim + +@section Building Your Script +We have made it trivial to build your simple scripts. All you have to do is +to drop your script into the scratch directory and it will automatically be built. Let's try it. Copy @code{examples/first.cc} into @code{scratch}: + +@verbatim + ~/repos/ns-3-tutorial > cp examples/first.cc scratch +@end verbatim + +and then build it using waf, + +@verbatim + ~/repos/ns-3-tutorial > ./waf + Entering directory `/home/craigdo/repos/ns-3-tutorial/build' + [432/477] cxx: scratch/first.cc -> build/debug/scratch/first_2.o + [433/477] cxx: scratch/simple.cc -> build/debug/scratch/simple_3.o + [475/477] cxx_link: build/debug/scratch/first_2.o -> build/debug/scratch/first + Compilation finished successfully +~/repos/ns-3-tutorial > +@end verbatim + +You can now run the example (note that if you build your program in the scratch +directory you must run it out of the scratch direcory): + +@verbatim + ~/repos/ns-3-tutorial > ./waf --run scratch/first + Entering directory `/home/craigdo/repos/ns-3-tutorial/build' + Compilation finished successfully + Sent 1024 bytes to 10.1.1.2 + Received 1024 bytes from 10.1.1.1 + Received 1024 bytes from 10.1.1.2 + ~/repos/ns-3-tutorial > +@end verbatim + +Here you see that the build system checks to make sure that the file has been +build and then runs it. You see the logging component on the echo client +note that it has sent one 1024 byte packet to the Echo Server on 10.1.1.2. +You also see the logging component on the echo server receive the 1024 bytes +from 10.1.1.1. The echo server silently echoes the packet and you see the +echo client note that it has received its packet back from the server. diff --git a/doc/tutorial/getting-started.texi b/doc/tutorial/getting-started.texi new file mode 100644 index 000000000..17519e51c --- /dev/null +++ b/doc/tutorial/getting-started.texi @@ -0,0 +1,275 @@ + +@c ======================================================================== +@c Begin document body here +@c ======================================================================== + +@c ======================================================================== +@c PART: Getting Started +@c ======================================================================== +@c The below chapters are under the major heading "Getting Started" +@c This is similar to the Latex \part command +@c +@c ======================================================================== +@c Getting Started +@c ======================================================================== +@node Getting Started +@chapter Getting Started + +@menu +* Downloading and Compiling ns-3:: +@end menu + +@c ======================================================================== +@c Downloading and Compiling ns-3 +@c ======================================================================== + +@node Downloading and Compiling ns-3 +@section Downloading and Compiling ns-3 + +@cindex Linux +@cindex Cygwin +@cindex GNU +@cindex toolchain +From this point forward, we are going to assume that the reader is working in +Linux or a Linux emulation environment (Linux, Cygwin, etc.) and has the GNU +toolchain installed and verified. + +@cindex Mercurial +@cindex Waf +We are going to assume that you have Mercurial and Waf installed and running +on the target system as described in the Getting Started section of the +ns-3 web site: @uref{http://www.nsnam.org/getting_started.html}. + +@section Downloading +@cindex tarball +The ns-3 code is available in Mercurial repositories on the server +code.nsnam.org. You can download a tarball, but we recommend working with +Mercurial --- it will make your life easier in the long run. + +@cindex repository +If you go to the following link: @uref{http://code.nsnam.org/}, +you will see a number of repositories. Many are the private repositories of +the ns-3 development team. The repositories of interest to you will be +prefixed with ``ns-3''. The current development snapshot (unreleased) +of ns-3 may be found at: @uref{http://code.nsnam.org/ns-3-dev/}. Official +releases of ns-3 will be numbered as @code{ns-3.} with any requred +hotfixes added as minor release numbers. For example, a second hotfix to a +hypothetical release nine of ns-3 would be numbered @code{ns-3.9.2}. + +The current development snapshot (unreleased) of ns-3 may be found at: +@uref{http://code.nsnam.org/ns-3-dev/}. The developers attempt to keep this +repository in a consistent, working state but it is a development area with +unreleased code present, so you may want to consider staying with an official +release. + +Since the release numbers are going to be changing, I will stick with +the more constant ns-3-dev here in the tutorial, but you can replace the +string ns-3-dev with your choice of release (e.g., ns-3.1) in the text below. +You can find the latest version of the code either by inspection of the +repository list or by going to the ``Getting Started'' web page and looking +for the latest release identifier. + +One practice is to create a directory called @code{repos} in one's home +directory under which one can keep local Mercurial repositories. +@emph{Hint: we will assume you do this later in the tutorial.} If you adopt +that approach, you can get a copy of any of the development versions of ns-3 +by typing the following into your Linux shell (assuming you have installed +Mercurial): + +@verbatim + cd + mkdir repos + cd !$ + hg clone http://code.nanam.org/ns-3-dev +@end verbatim + +As the hg command executes, you should see something like the following, + +@verbatim + destination directory: ns-3-dev + requesting all changes + adding changesets + adding manifests + adding file changes + added 3276 changesets with 12301 changes to 1353 files + 594 files updated, 0 files merged, 0 files removed, 0 files unresolved +@end verbatim + +After the clone command completes, you should have a directory called +ns-3-dev under your @code{~/repos} directory, the contents of which should +look something like the following: + +@verbatim + AUTHORS LICENSE regression/ scratch/ utils/ waf.bat* + doc/ ns3/ RELEASE_NOTES src/ VERSION wscript + examples/ README samples/ tutorial/ waf* +@end verbatim + +You are now ready to build the ns-3 distribution. + +@section Building and Testing +@cindex Waf!build +@cindex Waf!configure +@cindex Waf!debug +@cindex Waf!compile +@cindex Waf!check +@cindex Waf!regression +We use Waf to build the ns-3 project. The first thing you will need to do is +to configure the build. For reasons that will become clear later, we are +going to work with debug builds in the tutorial. To explain to Waf that it +should do debug builds you will need to execute the following command, + +@verbatim + ./waf -d debug configure +@end verbatim + +This runs the copy of Waf in the local directory (which is provided as a +convenience for you). As the build system checks for various dependencies +you should see output that looks similar to the following, + +@verbatim + ~/repos/ns-3-dev >./waf -d debug configure + Checking for program g++ : ok /usr/bin/g++ + Checking for compiler version : ok Version 4.1.2 + Checking for program cpp : ok /usr/bin/cpp + Checking for program ar : ok /usr/bin/ar + Checking for program ranlib : ok /usr/bin/ranlib + Checking for compiler could create programs : ok + Checking for compiler could create shared libs : ok + Checking for compiler could create static libs : ok + Checking for flags -O2 -DNDEBUG : ok + Checking for flags -g -DDEBUG : ok + Checking for flags -g3 -O0 -DDEBUG : ok + Checking for flags -Wall : ok + Checking for g++ : ok + Checking for header stdlib.h : ok + Checking for header stdlib.h : ok + Checking for header signal.h : ok + Checking for high precision time implementation : 128-bit integer + Checking for header stdint.h : ok + Checking for header inttypes.h : ok + Checking for header sys/inttypes.h : not found + Checking for package gtk+-2.0 >= 2.12 : not found + Checking for package goocanvas gthread-2.0 : not found + Checking for program diff : ok /usr/bin/diff + Configuration finished successfully; project is now ready to build. + ~/repos/ns-3-dev > +@end verbatim + +The build system is now configured and you can build the debug versions of +the ns-3 programs by simply typing, + +@verbatim + ./waf check +@end verbatim + +You will see many Waf status messages displayed as the system compiles. The +most important is the last one, + +@verbatim + Compilation finished successfully +@end verbatim + +@cindex tests|unit +You can run the unit tests of the ns-3 distribution by running the ``check'' +command, + +@verbatim + ./waf check +@end verbatim + +You should see a report from each unit test that executes indicating that the +test has passed. + +@verbatim + ~/repos/ns-3-dev > ./waf check + Entering directory `/home/craigdo/repos/ns-3-dev/build' + Compilation finished successfully + PASS AddressHelper + PASS Wifi + PASS DcfManager + + ... + + PASS Object + PASS Ptr + PASS Callback + ~/repos/ns-3-dev > +@end verbatim + +@cindex tests|regression +This command is typically run by @code{users} to quickly verify that an ns-3 +distribution has built correctly. + +You can also run @code{regression tests} to ensure that your distribution and +tool chain have produced binaries that generate trace files which are +compatible with reference trace files stored in a central location. To run the +regression tests you run Waf with the regression flag. + +@verbatim + ./waf --regression +@end verbatim + +Waf will verify that the current files in the ns-3 distribution are built and +will then look for trace files in the aforementioned centralized location. If +your tool chain includes Mercurial, the regression tests will be downloaded +from a repository at @code{code.nsnam.org}. If you do not have Mercurial +installed, the reference traces will be downloaded from a tarball located in +the @code{releases} section of @code{www.nsnam.org}. The particular name of +the reference trace location is built from the ns-3 version located in the +VERSION file, so don't change that string. + +Once the reference traces are downloaded to your local machine, Waf will run +a number of tests that generate trace files. The content of these trace +files are compared with the reference traces just downloaded. If they are +identical, the regression tests report a PASS status. If the regression tests +pass, you should see something like, + +@verbatim + ~/repos/ns-3-dev > ./waf --regression + Entering directory `/home/craigdo/repos/ns-3-dev/build' + Compilation finished successfully + ========== Running Regression Tests ========== + Synchronizing reference traces using Mercurial. + http://code.nsnam.org/ns-3-dev-ref-traces + Done. + PASS test-csma-broadcast + PASS test-csma-multicast + PASS test-csma-one-subnet + PASS test-csma-packet-socket + PASS test-simple-error-model + PASS test-simple-global-routing + PASS test-simple-point-to-point-olsr + PASS test-tcp-large-transfer + PASS test-udp-echo + ~/repos/ns-3-dev > +@end verbatim + +If a regression tests fails you will see a FAIL indication along with a +pointer to the offending trace file and its associated reference trace file +along with a suggestion on how to run diff in order to see what has gone awry. + +@section Running a Script +@cindex Waf!run +We typically run scripts under the control of Waf. This allows the build +system to ensure that the shared library paths are set correctly and that +the libraries are available at run time. To run a program, simply use the +@code{run} option in Waf. Let's run the ns-3 equivalent of the hello +world program by typing the following: + +@verbatim + ./waf --run hello-simulator +@end verbatim + +Waf first checks to make sure that the program is built correctly and +executes a build if required. Waf then then executes the program, which +produces the following output. + +@verbatim + Hello Simulator +@end verbatim + +If you want to run programs under another tool such as gdb or valgrind, +see this @uref{http://www.nsnam.org/wiki/index.php/User_FAQ#How_to_run_NS-3_programs_under_another_tool,,wiki entry}. + +@emph{Congratulations. You are now an ns-3 user.} diff --git a/doc/tutorial/Makefile b/doc/tutorial/in-process/Makefile similarity index 100% rename from doc/tutorial/Makefile rename to doc/tutorial/in-process/Makefile diff --git a/doc/tutorial/attributes.texi b/doc/tutorial/in-process/attributes.texi similarity index 100% rename from doc/tutorial/attributes.texi rename to doc/tutorial/in-process/attributes.texi diff --git a/doc/tutorial/figures/README b/doc/tutorial/in-process/figures/README similarity index 100% rename from doc/tutorial/figures/README rename to doc/tutorial/in-process/figures/README diff --git a/doc/tutorial/figures/dumbbell.dia b/doc/tutorial/in-process/figures/dumbbell.dia similarity index 100% rename from doc/tutorial/figures/dumbbell.dia rename to doc/tutorial/in-process/figures/dumbbell.dia diff --git a/doc/tutorial/figures/helpers.obj b/doc/tutorial/in-process/figures/helpers.obj similarity index 100% rename from doc/tutorial/figures/helpers.obj rename to doc/tutorial/in-process/figures/helpers.obj diff --git a/doc/tutorial/figures/oneobj.png b/doc/tutorial/in-process/figures/oneobj.png similarity index 100% rename from doc/tutorial/figures/oneobj.png rename to doc/tutorial/in-process/figures/oneobj.png diff --git a/doc/tutorial/figures/pp.dia b/doc/tutorial/in-process/figures/pp.dia similarity index 100% rename from doc/tutorial/figures/pp.dia rename to doc/tutorial/in-process/figures/pp.dia diff --git a/doc/tutorial/figures/star.dia b/doc/tutorial/in-process/figures/star.dia similarity index 100% rename from doc/tutorial/figures/star.dia rename to doc/tutorial/in-process/figures/star.dia diff --git a/doc/tutorial/figures/threeobj.png b/doc/tutorial/in-process/figures/threeobj.png similarity index 100% rename from doc/tutorial/figures/threeobj.png rename to doc/tutorial/in-process/figures/threeobj.png diff --git a/doc/tutorial/helpers.texi b/doc/tutorial/in-process/helpers.texi similarity index 100% rename from doc/tutorial/helpers.texi rename to doc/tutorial/in-process/helpers.texi diff --git a/doc/tutorial/introduction.texi b/doc/tutorial/in-process/introduction.texi similarity index 100% rename from doc/tutorial/introduction.texi rename to doc/tutorial/in-process/introduction.texi diff --git a/doc/tutorial/log.texi b/doc/tutorial/in-process/log.texi similarity index 100% rename from doc/tutorial/log.texi rename to doc/tutorial/in-process/log.texi diff --git a/doc/tutorial/other.texi b/doc/tutorial/in-process/other.texi similarity index 100% rename from doc/tutorial/other.texi rename to doc/tutorial/in-process/other.texi diff --git a/doc/tutorial/output.texi b/doc/tutorial/in-process/output.texi similarity index 100% rename from doc/tutorial/output.texi rename to doc/tutorial/in-process/output.texi diff --git a/doc/tutorial/statistics.texi b/doc/tutorial/in-process/statistics.texi similarity index 100% rename from doc/tutorial/statistics.texi rename to doc/tutorial/in-process/statistics.texi diff --git a/doc/tutorial/troubleshoot.texi b/doc/tutorial/in-process/troubleshoot.texi similarity index 100% rename from doc/tutorial/troubleshoot.texi rename to doc/tutorial/in-process/troubleshoot.texi diff --git a/doc/tutorial/in-process/tutorial.css b/doc/tutorial/in-process/tutorial.css new file mode 100644 index 000000000..a7586ac83 --- /dev/null +++ b/doc/tutorial/in-process/tutorial.css @@ -0,0 +1,156 @@ +body { + font-family: "Trebuchet MS", "Bitstream Vera Sans", verdana, lucida, arial, helvetica, sans-serif; + background: white; + color: black; + font-size: 11pt; +} + +h1, h2, h3, h4, h5, h6 { +# color: #990000; + color: #009999; +} + +pre { + font-size: 10pt; + background: #e0e0e0; + color: black; +} + +a:link, a:visited { + font-weight: normal; + text-decoration: none; + color: #0047b9; +} + +a:hover { + font-weight: normal; + text-decoration: underline; + color: #0047b9; +} + +img { + border: 0px; +} + +#main th { + font-size: 12pt; + background: #b0b0b0; +} + +.odd { + font-size: 12pt; + background: white; +} + +.even { + font-size: 12pt; + background: #e0e0e0; +} + +.answer { + font-size: large; + font-weight: bold; +} + +.answer p { + font-size: 12pt; + font-weight: normal; +} + +.answer ul { + font-size: 12pt; + font-weight: normal; +} + +#container { + position: absolute; + width: 100%; + height: 100%; + top: 0px; +} + +#feedback { + color: #b0b0b0; + font-size: 9pt; + font-style: italic; +} + +#header { + position: absolute; + margin: 0px; + top: 10px; + height:96px; + left: 175px; + right: 10em; + bottom: auto; + background: white; + clear: both; +} + +#middle { + position: absolute; + left: 0; + height: auto; + width: 100%; +} + +#main { + position: absolute; + top: 50px; + left: 175px; + right: 100px; + background: white; + padding: 0em 0em 0em 0em; +} + +#navbar { + position: absolute; + top: 75px; + left: 0em; + width: 146px; + padding: 0px; + margin: 0px; + font-size: 10pt; +} + +#navbar a:link, #navbar a:visited { + font-weight: normal; + text-decoration: none; + color: #0047b9; +} + +#navbar a:hover { + font-weight: normal; + text-decoration: underline; + color: #0047b9; +} + +#navbar dl { + width: 146px; + padding: 0; + margin: 0 0 10px 0px; + background: #99ffff url(images/box_bottom2.gif) no-repeat bottom left; +} + +#navbar dt { + padding: 6px 10px; + font-size: 100%; + font-weight: bold; + background: #009999; + margin: 0px; + border-bottom: 1px solid #fff; + color: white; + background: #009999 url(images/box_top2.gif) no-repeat top left; +} + +#navbar dd { + font-size: 100%; + margin: 0 0 0 0px; + padding: 6px 10px; + color: #0047b9; +} + +dd#selected { + background: #99ffff url(images/arrow.gif) no-repeat; + background-position: 4px 10px; +} diff --git a/doc/tutorial/in-process/tutorial.texi b/doc/tutorial/in-process/tutorial.texi new file mode 100644 index 000000000..d2e7a4813 --- /dev/null +++ b/doc/tutorial/in-process/tutorial.texi @@ -0,0 +1,105 @@ +\input texinfo @c -*-texinfo-*- +@c %**start of header +@setfilename ns-3.info +@settitle ns-3 tutorial +@c @setchapternewpage odd +@c %**end of header + +@ifinfo +Primary documentation for the @command{ns-3} project is available in +three forms: +@itemize @bullet +@item @uref{http://www.nsnam.org/doxygen/index.html,,ns-3 Doxygen/Manual}: Documentation of the public APIs of the simulator +@item Tutorial (this document) +@item @uref{http://www.nsnam.org/wiki/index.php,, ns-3 wiki} +@end itemize + +This document is written in GNU Texinfo and is to be maintained in +revision control on the @command{ns-3} code server. Both PDF and HTML versions +should be available on the server. Changes to +the document should be discussed on the ns-developers@@isi.edu mailing list. +@end ifinfo + +@copying + +This is an @command{ns-3} tutorial. +Primary documentation for the @command{ns-3} project is available in +three forms: +@itemize @bullet +@item @uref{http://www.nsnam.org/doxygen/index.html,,ns-3 Doxygen/Manual}: Documentation of the public APIs of the simulator +@item Tutorial (this document) +@item @uref{http://www.nsnam.org/wiki/index.php,, ns-3 wiki} +@end itemize + +This document is written in GNU Texinfo and is to be maintained in +revision control on the @command{ns-3} code server. Both PDF and HTML +versions should be available on the server. Changes to +the document should be discussed on the ns-developers@@isi.edu mailing list. + +This software is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This software 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, see @uref{http://www.gnu.org/licenses/}. +@end copying + +@titlepage +@title ns-3 Tutorial +@author ns-3 project +@author feedback: ns-developers@@isi.edu +@today{} + +@c @page +@vskip 0pt plus 1filll +@insertcopying +@end titlepage + +@c So the toc is printed at the start. +@anchor{Full Table of Contents} +@contents + +@ifnottex +@node Top, Overview, Full Table of Contents +@top ns-3 Tutorial (html version) + +For a pdf version of this tutorial, +see @uref{http://www.nsnam.org/docs/tutorial.pdf}. + +@insertcopying +@end ifnottex + +@menu +* Tutorial Goals:: +Part 1: Getting Started with ns-3 +* Overview:: +* Browsing:: +* Resources:: +* Downloading and Compiling:: +* Some-Prerequisites:: +Part 2: Reading ns-3 Programs +* A-First-ns-3-Script:: +Part 3: Reconfiguring Existing ns-3 Scripts +* Logging:: +* ns-3 Attributes:: +* Tracing:: +* Statistics:: +Part 4: Creating New or Revised Topologies +* Helper Functions:: +@end menu + +@include introduction.texi +@include log.texi +@include attributes.texi +@include statistics.texi +@include helpers.texi + +@printindex cp + +@bye diff --git a/doc/tutorial/tutorial.texi b/doc/tutorial/tutorial.texi index d2e7a4813..8869fcab3 100644 --- a/doc/tutorial/tutorial.texi +++ b/doc/tutorial/tutorial.texi @@ -66,7 +66,7 @@ along with this program. If not, see @uref{http://www.gnu.org/licenses/}. @contents @ifnottex -@node Top, Overview, Full Table of Contents +@node Top, Introduction, Full Table of Contents @top ns-3 Tutorial (html version) For a pdf version of this tutorial, @@ -76,29 +76,18 @@ see @uref{http://www.nsnam.org/docs/tutorial.pdf}. @end ifnottex @menu -* Tutorial Goals:: -Part 1: Getting Started with ns-3 -* Overview:: -* Browsing:: -* Resources:: -* Downloading and Compiling:: -* Some-Prerequisites:: -Part 2: Reading ns-3 Programs -* A-First-ns-3-Script:: -Part 3: Reconfiguring Existing ns-3 Scripts -* Logging:: -* ns-3 Attributes:: -* Tracing:: -* Statistics:: -Part 4: Creating New or Revised Topologies -* Helper Functions:: +* Introduction:: +* Geting Started:: +* Conceptual Overview:: +* Tweaking Ns-3:: +* Building Topologies:: @end menu @include introduction.texi -@include log.texi -@include attributes.texi -@include statistics.texi -@include helpers.texi +@include getting-started.texi +@include conceptual-overview.texi +@include tweaking.texi +@include building-topologies.texi @printindex cp diff --git a/doc/tutorial/tweaking.texi b/doc/tutorial/tweaking.texi new file mode 100644 index 000000000..2bfb70505 --- /dev/null +++ b/doc/tutorial/tweaking.texi @@ -0,0 +1,978 @@ + +@c ======================================================================== +@c Begin document body here +@c ======================================================================== + +@c ======================================================================== +@c PART: Tweaking Ns-3 +@c ======================================================================== +@c The below chapters are under the major heading "Tweaking Ns-3" +@c This is similar to the Latex \part command +@c +@c ======================================================================== +@c Tweaking Ns-3 +@c ======================================================================== +@node Tweaking Ns-3 +@chapter Tweaking Ns-3 + +@menu +* Using the Logging Module:: +* Using Command Line Arguments:: +* Using the Tracing System:: +@end menu + +@c ======================================================================== +@c Using the Logging Module +@c ======================================================================== +@node Using the Logging Module +@section Using the Logging Module + +@cindex logging +We have already taken a brief look at the ns-3 logging module while going +over the @code{first.cc} script. We will now take a closer look and see what +kind of use-cases the logging subsystem was designed to cover. + +@section Logging Overview +Many large systems support some kind of message logging facility, and ns-3 +is not an exception. In some cases, only error messages are logged to the +``operator console'' (which is typically @code{stderr} in Unix-based systems). +In other systems, warning messages may be output as well as more detailed +informational messages. In some cases, logging facilities are used to output +debug messages which can quickly turn the output into a blur. + +Ns-3 takes the view that all of these verbosity levels are useful and se +provides a selectable, multi-level approach to message logging. Logging can +be disabled completely, enabled on a component-by-component basis, enabled +globally and has selectable verbosity levels. The ns-3 log module provides +a straightforward, relatively easy to use way to get some kinds of information +out of your simulation. + +You should understand that we do provide a general purpose mechanism --- +tracing --- to get data out of your models which should be preferred for +simulation output (see the tutorial section Using the Tracing System for +more details on our tracing system). Logging should be preferred for +debugging information, warnings, error messages, or any time you want to +easily get a quick message out of your scripts or models. + +There are currently seven levels of log messages of increasing verbosity +defined in the system. + +@itemize @bullet +@item NS_LOG_ERROR --- Log error messages; +@item NS_LOG_WARN --- Log warning messages; +@item NS_LOG_DEBUG --- Log relatively rare, ad-hoc debugging messages; +@item NS_LOG_INFO --- Log informational messages about program progress; +@item NS_LOG_FUNCTION --- Log a message describing each function called; +@item NS_LOG_LOGIC -- Log messages describing logical flow in a function; +@item NS_LOG_ALL --- Log everything. +@end itemize + +We also provide an unconditional logging level that is always displayed, +irrespective of logging levels or component selection. + +@itemize @bullet +NS_LOG_UNCOND -- Log the associated message unconditionally. +@end itemize + +Each level can be requested singly or cumulatively; and can be set using a +shell environment variable (NS_LOG) or by logging system function call. As +was seen earlier in the tutorial, the logging system has Doxygen documentation +so now would be a good time to peruse the Logging Module documentation. + +Now that you have read the documentation in great detail, we can get some +interesting information out of the @code{first.cc} example script you dropped +in the scratch directory after the script walkthrough. + +@section Enabling Logging Using the NS_LOG Environment Variable +@cindex NS_LOG +First, let's use the NS_LOG environment variable to turn on some more logging +in the @code{first.cc} script you have already built. Go ahead and run the +script just as you did previously, + +@verbatim + ~/repos/ns-3-tutorial > ./waf --run scratch/first + Entering directory `/home/craigdo/repos/ns-3-tutorial/build' + Compilation finished successfully + Sent 1024 bytes to 10.1.1.2 + Received 1024 bytes from 10.1.1.1 + Received 1024 bytes from 10.1.1.2 + ~/repos/ns-3-tutorial > +@end verbatim + +The ``Sent'' and ``Received'' messages are actually logging messages from the +@code{UdpEchoClientApplication} and @code{UdpEchoServerApplication}. We can +ask the client application, for example, to print more information by setting +its logging level via the NS_LOG environment variable. I am going to assume +from here on that are using an sh-like shell that uses the``VARIABLE=value'' +syntax. If you are using a csh-like shell, then you will have to convert to +``setenv VARIABLE value'' syntax. + +Let's ask the UDP echo client application to print a little more information. +Right now, it is responding to the following line of code in @code{first.cc}, + +@verbatim + LogComponentEnable("UdpEchoClientApplication", LOG_LEVEL_INFO); +@end verbatim + +This line of code enables the @code{LOG_LEVEL_INFO} level of logging. When +we pass a logging level flag, we are actually enabling the given level and +all lower levels. In this case, we have enabled @code{NS_LOG_INFO}, +@code{NS_LOG_DEBUG}, @code{NS_LOG_WARN} and @code{NS_LOG_ERROR}. We can +increase the logging level and get more information without changing the +script and recompiling by setting the NS_LOG environment variable like this: + +@verbatim + ~/repos/ns-3-tutorial > export NS_LOG=UdpEchoClientApplication=level_all +@end verbatim + +This sets the environment variable @code{NS_LOG} to the string, + +@verbatim + UdpEchoClientApplication=level_all +@end verbatim + +The left hand side of the assignment is the name of the logging component we +want to set, and the right hand side is the flag we want to use. In this case, +we are going to turn on all of the debugging levels for the application. If +you run the script with NS_LOG set this way you should see the following +output: + +@verbatim + ~/repos/ns-3-tutorial > ./waf --run scratch/first + Entering directory `/home/craigdo/repos/ns-3-tutorial/build' + Compilation finished successfully + UdpEchoClientApplication:UdpEchoClient() + UdpEchoClientApplication:StartApplication() + UdpEchoClientApplication:ScheduleTransmit() + UdpEchoClientApplication:Send() + Sent 1024 bytes to 10.1.1.2 + Received 1024 bytes from 10.1.1.1 + UdpEchoClientApplication:HandleRead(0x62c640, 0x62cd70) + Received 1024 bytes from 10.1.1.2 + UdpEchoClientApplication:StopApplication() + UdpEchoClientApplication:DoDispose() + UdpEchoClientApplication:~UdpEchoClient() + ~/repos/ns-3-tutorial > +@end verbatim + +The only additional debug information provided by the application is from +the NS_LOG_FUNCTION level. You can now see a log of the function calls that +were made to the application. If you look closely you will notice a single +colon between the string @code{UdpEchoClientApplication} and the method name +where you might have expected a C++ scope operator (@code{::}). This is +intentional. The name is not actually a class name, it is a logging component +name. When there is a one-to-one correspondence between a source file and a +class, this will generally be the class name but you should understand that +it is not actually a class name, and there is a single colon to separate the +logging component name from the function name that is printed. + +It turns out that in come cases, it can be hard to determine which method +actually generates a log message. If you look in the text above, you may +wonder where the string ``@code{Received 1024 bytes from 10.1.1.1}'' comes +from. You can resolve this by ORing the @code{prefix_func} level into the +@code{NS_LOG} environment variable. Try doing the following, + +@verbatim + export 'NS_LOG=UdpEchoClientApplication=level_all|prefix_func' +@end verbatim + +Note that the single quotes are required since the vertical bar is a Unix +pipe connector. + +Now, if you run the script you will see that the logging system makes sure +that every message from the given log component is prefixed with the component +name. + +@verbatim + ~/repos/ns-3-tutorial > ./waf --run scratch/first + Entering directory `/home/craigdo/repos/ns-3-tutorial/build' + Compilation finished successfully + UdpEchoClientApplication:UdpEchoClient() + UdpEchoClientApplication:StartApplication() + UdpEchoClientApplication:ScheduleTransmit() + UdpEchoClientApplication:Send() + UdpEchoClientApplication:Send(): Sent 1024 bytes to 10.1.1.2 + Received 1024 bytes from 10.1.1.1 + UdpEchoClientApplication:HandleRead(0x62c710, 0x62ce40) + UdpEchoClientApplication:HandleRead(): Received 1024 bytes from 10.1.1.2 + UdpEchoClientApplication:StopApplication() + UdpEchoClientApplication:DoDispose() + UdpEchoClientApplication:~UdpEchoClient() + ~/repos/ns-3-tutorial > +@end verbatim + +You can now see all of the messages coming from the UDP echo client application +are identified as such. The remaining message must be coming from the UDP +echo server application. We can enable that component by entering a colon +separated list of components in the NS_LOG environment variable. + +@verbatim + export 'NS_LOG=UdpEchoClientApplication=level_all|prefix_func: + UdpEchoServerApplication=level_all|prefix_func' +@end verbatim + +Note that you will need to remove the newline after the @code{:} in the +example text above. + +Now, if you run the script you will see all of the log messages from both the +echo client and server applications. You may see that this can be very useful +in debugging problems. + +@verbatim + ~/repos/ns-3-tutorial > ./waf --run scratch/first + Entering directory `/home/craigdo/repos/ns-3-tutorial/build' + Compilation finished successfully + UdpEchoServerApplication:UdpEchoServer() + UdpEchoClientApplication:UdpEchoClient() + UdpEchoServerApplication:StartApplication() + UdpEchoClientApplication:StartApplication() + UdpEchoClientApplication:ScheduleTransmit() + UdpEchoClientApplication:Send() + UdpEchoClientApplication:Send(): Sent 1024 bytes to 10.1.1.2 + UdpEchoServerApplication:HandleRead(): Received 1024 bytes from 10.1.1.1 + UdpEchoServerApplication:HandleRead(): Echoing packet + UdpEchoClientApplication:HandleRead(0x62c760, 0x62ce90) + UdpEchoClientApplication:HandleRead(): Received 1024 bytes from 10.1.1.2 + UdpEchoServerApplication:StopApplication() + UdpEchoClientApplication:StopApplication() + UdpEchoClientApplication:DoDispose() + UdpEchoServerApplication:DoDispose() + UdpEchoClientApplication:~UdpEchoClient() + UdpEchoServerApplication:~UdpEchoServer() + ~/repos/ns-3-tutorial > +@end verbatim + +It is also sometimes useful to be able to see the simulation time at which a +log message is generated. You can do this by ORing in the prefix_time bit. + +@verbatim + export 'NS_LOG=UdpEchoClientApplication=level_all|prefix_func|prefix_time: + UdpEchoServerApplication=level_all|prefix_func|prefix_time' +@end verbatim + +If you run the script now, you should see the following output: + +@verbatim + ~/repos/ns-3-tutorial > ./waf --run scratch/first + Entering directory `/home/craigdo/repos/ns-3-tutorial/build' + Compilation finished successfully + 0ns UdpEchoServerApplication:UdpEchoServer() + 0ns UdpEchoClientApplication:UdpEchoClient() + 1000000000ns UdpEchoServerApplication:StartApplication() + 2000000000ns UdpEchoClientApplication:StartApplication() + 2000000000ns UdpEchoClientApplication:ScheduleTransmit() + 2000000000ns UdpEchoClientApplication:Send() + 2000000000ns UdpEchoClientApplication:Send(): Sent 1024 bytes to 10.1.1.2 + 2003686400ns UdpEchoServerApplication:HandleRead(): Received 1024 bytes + from 10.1.1.1 + 2003686400ns UdpEchoServerApplication:HandleRead(): Echoing packet + 2007372800ns UdpEchoClientApplication:HandleRead(0x62c8c0, 0x62d020) + 2007372800ns UdpEchoClientApplication:HandleRead(): Received 1024 bytes + from 10.1.1.2 + 10000000000ns UdpEchoServerApplication:StopApplication() + 10000000000ns UdpEchoClientApplication:StopApplication() + UdpEchoClientApplication:DoDispose() + UdpEchoServerApplication:DoDispose() + UdpEchoClientApplication:~UdpEchoClient() + UdpEchoServerApplication:~UdpEchoServer() + ~/repos/ns-3-tutorial > +@end verbatim + +You can see that the constructor for the UdpEchoServer was called at a +simulation time of 0 nanoseconds. This is actually happening before the +simulation starts. The same for the UdpEchoClient constructor. + +Recall that the @code{first.cc} script started the echo server application at +one second into the simulation. You can now see that the +@code{StartApplication} of the server is, in fact, called at one second (or +one billion nanoseconds). You can also see that the echo client application +is started at a simulation time of two seconds as we requested in the script. + +You can now follow the progress of the simulation from the +@code{ScheduleTransmit} call in the client that calls @code{Send} to the +@code{HandleRead} callback in the echo server application. Note that the +elapsed time as the packet is sent across the point-to-point link is 3.6864 +milliseconds. You see the echo server logging a message telling you that it +has echoed the packet and then, after a delay, you see the echo client receive +the echoed packet. + +There is a lot that is happening under the covers in this simulation that you +are not seeing as well. You can very easily follow the entire process by +turning on all of the logging components in the system. Try setting the +@code{NS_LOG} variable to the following, + +@verbatim + export 'NS_LOG=*=level_all|prefix_func|prefix_time' +@end verbatim + +The asterisk is the logging component wildcard. This will turn on all of the +logging in all of the components in the system. I won't reproduce the output +here (as of this writing it produces 772 lines of output for the single packet +echo) but you can redirect this information into a file and look through it +with your favorite editor if you like, + +@verbatim + ~/repos/ns-3-tutorial > ./waf --run scratch/first >& log.out +@end verbatim + +I personally use this quite a bit when I am presented with a problem and I +have no idea where things are going wrong. I can follow the progress of the +code quite easily without having to set breakpoints and step through code +in a debugger. When I have a general idea about what is going wrong, I +transition into a debugger for fine-grained examination of the problem. This +output can be especially useful when your script does something completely +unexpected. + +@section Adding Logging to your Code +@cindex NS_LOG +You can add new logging to your simulations by making calls to the log +component via several macros. Let's do so in the @code{first.cc} script we +have in the @code{scratch} directory. + +Recall that we have defined a logging component in that script. + +@verbatim + NS_LOG_COMPONENT_DEFINE ("FirstScriptExample"); +@end verbatim + +You now know that you can enable all of the logging for this component by +setting the @code{NS_LOG} environment variable to the various levels. Let's +add some logging. The macro to add an informational level log message is +@code{NS_LOG_INFO}. Add one just before we start creating the nodes that +tells you that the script is ``Creating Topology.'' This is done as in this +code snippet, + +@verbatim + NS_LOG_INFO ("Creating Topology"); +@end verbatim + +Now build the script using waf and clear the @code{NS_LOG} variable to turn +off the torrent of logging we previously enabled: + +@verbatim + ~/repos/ns-3-tutorial > export NS_LOG= +@end verbatim + +Now, if you run the script, you will not see your new message since its +associated logging component has not been enabled. In order to see your +message you will have to enable the @code{FirstScriptExample} logging +component with a level greater than or equal to @code{NS_LOG_INFO}. If +you just want to see this particular level of logging, you can enable that +by, + +@verbatim + ~/repos/ns-3-tutorial > export NS_LOG=FirstScriptExample=info +@end verbatim + +If you now run the script you will see your new logging message, + +@verbatim + ~/repos/ns-3-tutorial > ./waf --run scratch/first + Entering directory `/home/craigdo/repos/ns-3-tutorial/build' + Compilation finished successfully + Creating Topology + Sent 1024 bytes to 10.1.1.2 + Received 1024 bytes from 10.1.1.1 + Received 1024 bytes from 10.1.1.2 + ~/repos/ns-3-tutorial > +@end verbatim + +As previously described, this does not also enable the lower levels of logging +but selects out the single infomational level. + +As we outlined in the Logging Overview, there are currently seven levels of +logging verbosity you can use and you can also prefix your various log messages +with component name and simulation time. + +@c ======================================================================== +@c Using Command Line Arguments +@c ======================================================================== +@node Using Command Line Arguments +@section Using Command Line Arguments + +@section Overriding Default Attributes +@cindex arguments|command line +Another way you can change the way that ns-3 scripts behave without editing +and building scripts is via @emph{command line arguments.} We provide a +mechanism to parse command line arguments and automatically set local and +global variables based on those arguments. + +The first step in using the command line argument system is to declare the +command line parser. This is done quite simply (in your main program) as +in the following code, + +@verbatim + int + main (int argc, char *argv[]) + { + ... + + CommandLine cmd; + cmd.Parse (argc, argv); + + ... + } +@end verbatim + +This simple two line snippet is actually very useful by itself. It opens the +door to the ns-3 global variable and attribute systems. Go ahead and add that +two lines of code to the @code{first.cc} script at the start of @code{main}. +Go ahead and build the script and run it, but ask the script for help in the +following way, + +@verbatim + ~/repos/ns-3-tutorial > ./waf --run "scratch/first --PrintHelp" +@end verbatim + +This will ask way to run the @code{scratch/first} script and pass the command +line argument @code{--PrintHelp} to the script. The command line parser will +now see the @code{PrintHelp} argument and respond with, + +@verbatim + ~/repos/ns-3-tutorial > ./waf --run ``scratch/first --PrintHelp'' + Entering directory `/home/craigdo/repos/ns-3-tutorial/build' + Compilation finished successfully + --PrintHelp: Print this help message. + --PrintGroups: Print the list of groups. + --PrintTypeIds: Print all TypeIds. + --PrintGroup=[group]: Print all TypeIds of group. + --PrintAttributes=[typeid]: Print all attributes of typeid. + --PrintGlobals: Print the list of globals. + ~/repos/ns-3-tutorial > +@end verbatim + +Let's focus on the @code{--PrintAttributes} option. We have already hinted +at the attribute system while walking through the @code{first.cc} script. We +looked at the following lines of code, + +@verbatim + PointToPointHelper pointToPoint; + pointToPoint.SetDeviceParameter ("DataRate", StringValue ("5Mbps")); + pointToPoint.SetChannelParameter ("Delay", StringValue ("2ms")); +@end verbatim + +and mentioned that @code{DataRate} was actually an @code{Attribute} of the +@code{PointToPointNetDevice}. Let's use the command line argument parser +to take a look at the attributes of the PointToPointNetDevice. The help +listing says that we should provide a typeid. This corresponds to the class +name of the class to which the attributes belong. In this case it will be +@code{ns3::PointToPointNetDevice}. Let's go ahead and type in, + +@verbatim + ./waf --run "scratch/first --PrintAttributes=ns3::PointToPointNetDevice" +@end verbatim + +The system will print out all of the attributes of this kind of net device. +Among the attributes you will see listed is, + +@verbatim + --ns3::PointToPointNetDevice::DataRate=[32768bps]: + The default data rate fo r point to point links +@end verbatim + +This is the default value that will be used when a PointToPointNetDevice is +created in the system. We overrode this default with the parameter setting +in the PointToPointHelper above. Let's use the default values for the +PointToPoint devices and channels by deleting the SetDeviceParameter call and +the SetChannelParameter call from the @code{first.cc} we have in the scratch +directory. + +Your script should now just declare the PointToPointHelper and not do any +sets as in the following example, + +@verbatim + ... + + NodeContainer nodes; + nodes.Create (2); + + PointToPointHelper pointToPoint; + + NetDeviceContainer devices; + devices = pointToPoint.Install (nodes); + + ... +@end verbatim + +Go ahead and build the new script with waf. Now let's go back and enable some +logging from the UDP echo server application and turn on the time prefix. + +@verbatim + export 'NS_LOG=UdpEchoServerApplication=level_all|prefix_time' +@end verbatim + +If you run the script, you should now see the following output, + +@verbatim + ~/repos/ns-3-tutorial > ./waf --run scratch/first + Entering directory `/home/craigdo/repos/ns-3-tutorial/build' + Compilation finished successfully + 0ns UdpEchoServerApplication:UdpEchoServer() + 1000000000ns UdpEchoServerApplication:StartApplication() + Sent 1024 bytes to 10.1.1.2 + 2257324218ns Received 1024 bytes from 10.1.1.1 + 2257324218ns Echoing packet + Received 1024 bytes from 10.1.1.2 + 10000000000ns UdpEchoServerApplication:StopApplication() + UdpEchoServerApplication:DoDispose() + UdpEchoServerApplication:~UdpEchoServer() + ~/repos/ns-3-tutorial > +@end verbatim + +Recall that the last time we looked at the simulation time at which the packet +was received by the echo server, it was at 2.0036864 seconds. Now it is +receiving the packet at about 2.257 seconds. This is because we just dropped +the data rate of the @code{PointToPointNetDevice} down to its default of +32768 bits per second from five megabits per second. + +If we were to provide a new @code{DataRate} using the command line, we could +speed our simulation up again, + +@verbatim + ./waf --run "scratch/first --ns3::PointToPointNetDevice::DataRate=5Mbps" +@end verbatim + +This will set the default value of the @code{DataRate} attribute back to +five megabits per second. To get the old behavior back, we will have to set +the speed-of-light delay of the channel. We can ask the command line system +to print out the @code{Attributes} of the channel just like we did the net +device: + +@verbatim + ./waf --run "scratch/first --PrintAttributes=ns3::PointToPointChannel" +@end verbatim + +and we discover the @code{Delay} attribute. + +@verbatim + --ns3::PointToPointChannel::Delay=[0ns]: + Transmission delay through the channel +@end verbatim + +We can then set both of these default values through the command line system, + +@verbatim + ./waf --run "scratch/first + --ns3::PointToPointNetDevice::DataRate=5Mbps + --ns3::PointToPointChannel::Delay=2ms" +@end verbatim + +In which case we recover the timing we had when we explicitly set the +@code{DataRate} and @code{Delay} in the script: + +@verbatim + Compilation finished successfully + 0ns UdpEchoServerApplication:UdpEchoServer() + 1000000000ns UdpEchoServerApplication:StartApplication() + Sent 1024 bytes to 10.1.1.2 + 2003686400ns Received 1024 bytes from 10.1.1.1 + 2003686400ns Echoing packet + Received 1024 bytes from 10.1.1.2 + 10000000000ns UdpEchoServerApplication:StopApplication() + UdpEchoServerApplication:DoDispose() + UdpEchoServerApplication:~UdpEchoServer() +@end verbatim + +Note that the packet is received by the server at 2.0036864 seconds. We +could actually set any of the attributes used in the script in this way. In +particular we could set the @code{UdpEchoClient} attribute @code{MaxPackets} +to some other value than one. + +How would you go about that? Give it a try. Remember you have to comment +out the place we override the default attribute in the script. Then you +have to rebuild the script using the default. You will also have to find the +syntax for actually setting the new default atribute value using the command +line help facility. Once you have this figured out you should be able to +control the number of packets echoed from the command line. Since we're nice +folks, we'll tell you that your command line should end up looking something +like, + +@verbatim + ./waf --run "scratch/first + --ns3::PointToPointNetDevice::DataRate=5Mbps + --ns3::PointToPointChannel::Delay=2ms + --ns3::UdpEchoClient::MaxPackets=2" +@end verbatim + +@subsection Hooking Your Own Values +You can also add your own hooks to the command line system. This is done +quite simply by using the @code{AddValue} method to the command line parser. + +Let's use this facility to specify the number of packets to echo in a +completely different way. Let's add a local variable called @code{nPackets} +to the main function. We'll initialize it to one to match our previous +default behavior. To allow the command line parser to change this value, we +need to hook the value into the parser. Do this by adding a call to +@code{AddValue}. Go ahead and change the @code{scratch/first.cc} script to +start with the following code, + +@verbatim + int + main (int argc, char *argv[]) + { + uint32_t nPackets = 1; + + CommandLine cmd; + cmd.AddValue("nPackets", "Number of packets to echo", nPackets); + cmd.Parse (argc, argv); + + ... +@end verbatim + +Scroll down to the point in the script where we set the @code{MaxPackets} +attribute and change it so that it is set to the variable @code{nPackets} +instead of the constant @code{1} as below. + +@verbatim + echoClient.SetAppAttribute ("MaxPackets", UintegerValue (nPackets)); +@end verbatim + +Now if you run the script and provide the @code{--PrintHelp} argument, you +should see your new @code{User Argument} listed in the help. + +@verbatim + ~/repos/ns-3-tutorial > ./waf --run "scratch/first --PrintHelp" + Entering directory `/home/craigdo/repos/ns-3-tutorial/build' + Compilation finished successfully + --PrintHelp: Print this help message. + --PrintGroups: Print the list of groups. + --PrintTypeIds: Print all TypeIds. + --PrintGroup=[group]: Print all TypeIds of group. + --PrintAttributes=[typeid]: Print all attributes of typeid. + --PrintGlobals: Print the list of globals. + User Arguments: + --nPackets: Number of packets to echo + ~/repos/ns-3-tutorial > +@end verbatim + +If you want to specify the number of packets to echo, you can now do so by +setting the @code{nPackets} argument, + +@verbatim + ~/repos/ns-3-tutorial > ./waf --run "scratch/first --nPackets=2" + Entering directory `/home/craigdo/repos/ns-3-tutorial/build' + Compilation finished successfully + Sent 1024 bytes to 10.1.1.2 + Received 1024 bytes from 10.1.1.1 + Received 1024 bytes from 10.1.1.2 + Sent 1024 bytes to 10.1.1.2 + Received 1024 bytes from 10.1.1.1 + Received 1024 bytes from 10.1.1.2 + ~/repos/ns-3-tutorial > +@end verbatim + +If you are an ns-3 user, you can use the command line argument system to +control global values and attributes. If you are a model author, you can +add new attributes to your Objects and they will automatically be available +for setting by your users through the command line system. If you are a +script author, you can add new variables to your scripts and hook them into +the command line system quite painlessly. + +@c ======================================================================== +@c Using the Tracing System +@c ======================================================================== +@node Using the Tracing System +@section Using the Tracing System + +The whole point of simulation is to generate output for further study, and +the @command{ns-3} tracing system is a primary mechanism for this. Since +@command{ns-3} is a C++ program, standard facilities for generating output +from C++ programs apply: + +@verbatim + #include + ... + int main () + { + ... + std::cout << "The value of x is " << x << std::endl; + ... + } +@end verbatim + +The basic goals of the @command{ns-3} tracing system are: + +@itemize @bullet +@item For basic tasks, the tracing system should allow the user to generate +standard tracing for popular tracing sources, and to customize which objects +generate the tracing; +@item Intermediate users must be able to extend the tracing system to modify +the output format generated, or to insert new tracing sources, without +modifying the core of the simulator; +@item Advanced users can modify the simulator core to add new tracing sources +and sinks. +@end itemize + +The @command{ns-3} tracing system is built on the concepts of independent +tracing sources and tracing sinks and a uniform mechanism for connecting +sources to sinks. Trace sources are entities that can signal events that +happen in a simulation and provide access to interesting underlying data. +For example, a trace source could indicate when a packet is received by a net +device and provide access to the packet for interested trace sinks. + +Trace sources are not useful by themselves, they must be ``connected'' to +other pieces of code that actually do something useful with the information +provided by the sink. Trace sinks are consumers of the events and data +provided by the trace sources. For example, one could create a trace sink t +hat would (when connected to the trace source of the previous example) print +out interesting parts of the received packet. + +The rationale for this explicit division is to allow users to attach new +types of sinks to existing tracing sources, without requiring editing and +recompilation of the the core of the simulator. Thus, in the example above, +a user could define a new tracing sink in her script and attach it to an +existing tracing source defined in the simulation core editing only the +user script. + +What remains to be defined is a way for users to find these hooks (tracing +sources) and attach sinks to them. A tracing namespace is defined for +this purpose. + +In this tutorial, we will walk through some pre-defined sources and sinks and +show how they may be customized with little user effort. See the ns-3 manual +or how-to sections for information on advanced tracing configuration including +extending the tracing namespace and creating new tracing sources. + +@cindex tracing +@cindex tracing|ASCII +@subsection ASCII Tracing +Ns-3 provides an ASCII trace helper that is a wrapper around low-level +tracing system. This helper lets you configure some useful and easily +understood packet traces easily. The output of a trace of a simulation run +is an ASCII file --- thus the name. For those familiar with @command{ns-2} +output, this type of trace is analogous to the @command{out.tr} generated +by many scripts. + +@cindex tracing|packets +Let's just jump right in and add some ASCII tracing output to our +@code{first.cc} script. The first thing you need to do is to add the +following code to the script just before the call to @code{Simulator::Run ()}. + +@verbatim + std::ofstream ascii; + ascii.open ("first.tr"); + PointToPointHelper::EnableAsciiAll (ascii); +@end verbatim + +The first two lines are just vanilla C++ code to open a stream that will be +written to a file named ``first.tr.'' See your favorite C++ tutorial if you +are unfamiliar with this code. The last line of code in the snippet above +tells ns-3 that you want to enable ASCII tracing on all point-to-point devices +in your simulation; and you want the (provided) trace sinks to write out +information about packet movement in ASCII format to the stream provided. +For those familiar with @command{ns-2}, the traced events are equivalent +to the popular trace points that log "+", "-", "d", and "r" events. + +Since we have used a @code{std::ofstream} object, we also need to include the +appropriate header. Add the following line to the script (I typically add it +above the ns-3 includes): + +@verbatim + #include +@end verbatim + +You can now build the script and run it from the command line: + +@verbatim + ./waf --run scratch/first +@end verbatim + +@cindex first.tr +Just as you have seen previously, you may see some messages from Waf and then +the ``Compilation finished successfully'' message. The following messages are +from the running program. When it ran, the program will have created a file +named @code{first.tr}. Because of the way that Waf works, the file is not +created in the local directory, it is created at the top-level directory of +the repository by default. If you want to control where the traces are saved +you can use the @code{--cwd} option of Waf to specify this. We have not done +so, thus we need to change into the top level directory of our repo and take a +look at the file @code{first.tr} in your favorite editor. + +@subsubsection Parsing Ascii Traces +@cindex parsing ascii traces +There's a lot of information there in a pretty dense form, but the first thing +to notice is that there are a number of distinct lines in this file. It may +be difficult to see this clearly unless you widen your windows considerably. +Each line in the file corresponds to a @emph{trace event}. In this case +we are tracing events on the @emph{device queue} present in every net device +on every node in the simulation. The device queue is a queue through which +every packet destined for a channel must pass --- it is the device +@emph{transmit} queue. Note that each line in the trace file begins with a +lone character (has a space after it). This character will have the following +meaning: + +@cindex ascii trace|enqueue +@cindex ascii trace|dequeue +@cindex ascii trace|drop +@cindex ascii trace|receive +@itemize @bullet +@item @code{+}: An enqueue operation occurred on the device queue; +@item @code{-}: A dequeue operation occurred on the device queue; +@item @code{d}: A packet was dropped, typically because the queue was full; +@item @code{r}: A packet was received by the net device. +@end itemize + +Let's take a more detailed view of the first line. I'll break it down into +sections (indented for clarity) with a two digit reference number on the +left side: + +@verbatim + 00 + + 01 2 + 02 /NodeList/0/DeviceList/0/$ns3::PointToPointNetDevice/TxQueue/Enqueue + 03 ns3::PppHeader ( + 04 Point-to-Point Protocol: IP (0x0021)) + 05 ns3::Ipv4Header ( + 06 tos 0x0 ttl 64 id 0 offset 0 flags [none] + 07 length: 1052 10.1.1.1 > 10.1.1.2) + 08 ns3::UdpHeader ( + 09 length: 1032 49153 > 9) + 10 Payload (size=1024) +@end verbatim + +@cindex trace event +@cindex simulation time +The first line of this expanded trace event (reference number 00) is the +queue operation. We have a @code{+} character, so this corresponds to an +@emph{enqueue} operation. The second line (reference 01) is the simulation +time expressed in seconds. You may recall that we asked the +@code{UdpEchoClient} to start sending packets at two seconds. Here we again +see confirmation that this is, indeed, happening. + +@cindex node number +@cindex net device number +@cindex smart pointer +The next line of the example listing (reference 02) tell us the trace source +that originated this even expressed in the tracing namespace. You can think +of the tracing womewhat like you would a filesystem namespace. The root of +the namespace is the @code{NodeList}. This corresponds to a container in the +ns-3 code that contains all of the nodes that were created in the system. +Just as a filesystem has may have directories under the root, we have node +numbers in the @code{NodeList}. The string @code{/NodeList/0} therefore +refers to the zeroth node in the @code{NodeList} which we can think of as +``node 0.'' In each node there is a list of devices that have been installed. +This list appears next. You can see that this trace event comes from +@code{DeviceList/0} which is the zeroth device installed in the node. + +The next string, @code{$ns3::PointToPointNetDevice} tells you what kind of +device it is that is in the zeroth position of the device list for node zero. +This should by now be completely expected. Recall that the operation @code{+} +found at reference 00 means an enqueue operation on the transmit queue of the +device. This is reflected in the final segments of the ``trace path'' which +are @code{TxQueue/Enqueue}. + +The remaining lines in the trace should be fairly intuitive. References 03-04 +indicate that the packet is encapulated in the point-to-point protocol. +References 05-07 show that the packet has an IP version four header and has +originated from IP address 10.1.1.1 and is destined for 10.1.1.2. References +08-09 show that this is a UDP packet from and finally reference 10 shows that +the payload is the expected 1024 bytes. + +The next line in the trace file shows the same packet being dequeued from the +transmit queue on the same node. + +The Third line in the trace file shows the packet being received by the net +device on the node with the echo server. I have reproduced that event below. + +@verbatim + 00 r + 01 2.25732 + 02 /NodeList/1/DeviceList/0/$ns3::PointToPointNetDevice/Rx + 03 ns3::PppHeader ( + 04 Point-to-Point Protocol: IP (0x0021)) + 05 ns3::Ipv4Header ( + 06 tos 0x0 ttl 64 id 0 offset 0 flags [none] + 07 length: 1052 10.1.1.1 > 10.1.1.2) + 08 ns3::UdpHeader ( + 09 length: 1032 49153 > 9) + 10 Payload (size=1024) +@end verbatim + +Notice that the trace operation is now @code{r} and the simulation time has +increased to 2.25732 seconds. If you have been following the tutorial steps +closely this means that you have left the @code{DataRate} of the net devices +set to their default value of 32768 bps with a channel @code{Delay} of two +milliseconds. This time should be familiar as you have seen it before in a +previous section. + +The trace source namespace entry (reference 02) has changed to reflect that +this event is coming from node 1 (@code{/NodeList/1}) and the packet reception +trace source (@code{/Rx}). It should be quite easy for you to follow the +progress of the packet through the topology by looking at the rest of the +traces in the file. + +@subsection PCAP Trace Helper +@cindex pcap +@cindex Wireshark +The @command{ns-3} @emph{pcap trace helper} is used to create trace files in +@code{.pcap} format. The acronym pcap (usually written in lower case) stands +for @emph{p}acket @emph{cap}ture, and is actually an API that includes the +definition of a @code{.pcap} file format. The most popular program that can +read and display this format is Wireshark (formerly called Ethereal). +However, there are many traffic trace analyzers that use this packet format. +We encourage users to exploit the many tools available for analyzing pcap +traces. In this tutorial, we show how tcpdump and Wireshark can be used. + +@cindex tracing|pcap +The code used to enable pcap tracing is a one-liner. + +@verbatim + PointToPointHelper::EnablePcapAll ("first"); +@end verbatim + +Go ahead and insert this line of code after the ASCII tracing code we just +added to @code{scratch/first.cc}. Notice that we only gave the pcap trace +helper call the string, ``first,'' and not ``first.pcap'' or something +similar. This is because the parameter is a prefix, not a complete file name. +The pcap trace helper will actually create a trace file for every device in +the simulation that generates a traced event. The file names will be built +using the prefix, the node number, the device number and a ``.pcap'' suffix. + +In our example script, we will see a files named ``first-0-0.pcap'' and +``first.1-0.pcap'' which are the pcap traces for node 0, device 0 and node 1, +device 1, respectively. + +You can now run the script as you have been: + +@verbatim + ./waf --run scratch/first +@end verbatim + +If you look at the top level directory of your distribution, you should now +see three log files: @code{first.tr} is the ASCII trace file we have +previously examined. @code{first-0-0.pcap} and @code{first-1-0.pcap} +are the new pcap files we just generated. + +@subsubsection Reading output with tcpdump +@cindex tcpdump +The easiest thing to do at this point will be to use @code{tcpdump} to look +at the @code{pcap} files. Output from dumping both files is shown below: + +@verbatim + ~/repos/ns-3-tutorial > /usr/sbin/tcpdump -r first-0-0.pcap -nn -tt + reading from file first-0-0.pcap, link-type PPP (PPP) + 2.000000 IP 10.1.1.1.49153 > 10.1.1.2.9: UDP, length 1024 + 2.514648 IP 10.1.1.2.9 > 10.1.1.1.49153: UDP, length 1024 + ~/repos/ns-3-tutorial > /usr/sbin/tcpdump -r first-1-0.pcap -nn -tt + reading from file first-1-0.pcap, link-type PPP (PPP) + 2.257324 IP 10.1.1.1.49153 > 10.1.1.2.9: UDP, length 1024 + 2.257324 IP 10.1.1.2.9 > 10.1.1.1.49153: UDP, length 1024 + ~/repos/ns-3-tutorial > +@end verbatim + +You can see in the dump of ``first-0.0.pcap'' (the client device) that the +echo packet is sent at 2 seconds into the simulation. If you look at the +second dump (of ``first-1-0.pcap'') you can see that packet being received +at 2.257324 seconds. You see the packet being echoed at 2.257324 seconds +in the second dump, and finally, you see the packet being received back at +the client in the first dump at 2.514648 seconds. + +@subsubsection Reading output with Wireshark +@cindex Wireshark +If you are unfamilar with Wireshark, there is a web site available from which +you can download programs and documentation: @uref{http://www.wireshark.org/}. + +Wireshark is a graphical user interface which can be used for displaying these +trace files. If you have Wireshark available, you can open each of the trace +files and display the contents as if you had captured the packets using a +@emph{packet sniffer}. diff --git a/examples/hello-simulator.cc b/examples/hello-simulator.cc new file mode 100644 index 000000000..37f99ccd5 --- /dev/null +++ b/examples/hello-simulator.cc @@ -0,0 +1,27 @@ +/* -*- 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 + */ + +#include "ns3/core-module.h" + +NS_LOG_COMPONENT_DEFINE ("HelloSimulator"); + +using namespace ns3; + + int +main (int argc, char *argv[]) +{ + NS_LOG_UNCOND ("Hello Simulator"); +} From eb848bb7191a8f5de9b47cf714fbae2b6203f7bd Mon Sep 17 00:00:00 2001 From: Craig Dowell Date: Sat, 28 Jun 2008 19:48:14 -0700 Subject: [PATCH 067/495] swapping in all of tutorial would be better --- doc/tutorial/Makefile | 49 +++++ doc/tutorial/introduction.texi | 360 +++++++++++++++++++++++++++++++++ 2 files changed, 409 insertions(+) create mode 100644 doc/tutorial/Makefile create mode 100644 doc/tutorial/introduction.texi diff --git a/doc/tutorial/Makefile b/doc/tutorial/Makefile new file mode 100644 index 000000000..5428d9265 --- /dev/null +++ b/doc/tutorial/Makefile @@ -0,0 +1,49 @@ +TEXI2HTML = texi2html +TEXI2PDF = texi2dvi --pdf +EPSTOPDF = epstopdf +TGIF = tgif +DIA = dia +CONVERT = convert +CSS = --css-include=tutorial.css +SPLIT = --split section + +DIA_SOURCES = pp.dia dumbbell.dia star.dia +TGIF_SOURCES = helpers.obj + +DIA_EPS = ${DIA_SOURCES:.dia=.eps} +DIA_PNG = ${DIA_SOURCES:.dia=.png} +DIA_PDF = ${DIA_SOURCES:.dia=.pdf} + +TGIF_EPS = ${TGIF_SOURCES:.obj=.eps} +TGIF_PNG = ${TGIF_SOURCES:.obj=.png} +TGIF_PDF = ${TGIF_SOURCES:.obj=.pdf} + +all: html split-html pdf + +# Note: tgif requires a valid x display to convert from .obj to .png. +# If running this makefile on a remote console, the X virtual frame +# buffer may be needed (xorg-x11-server-Xvfb) to provide a "fake" +# display +images: + cd figures/; $(DIA) -t png $(DIA_SOURCES) + cd figures/; $(DIA) -t eps $(DIA_SOURCES) + cd figures/; $(foreach FILE,$(DIA_EPS),$(EPSTOPDF) $(FILE);) + cd figures/; $(TGIF) -print -png $(TGIF_SOURCES) + cd figures/; $(TGIF) -print -eps $(TGIF_SOURCES) + cd figures/; $(foreach FILE,$(TGIF_EPS),$(EPSTOPDF) $(FILE);) + +html: + $(TEXI2HTML) ${CSS} tutorial.texi + +split-html: + $(TEXI2HTML) ${CSS} ${SPLIT} tutorial.texi + +pdf: + $(TEXI2PDF) tutorial.texi + +figures-clean: + cd figures/; rm -rf $(DIA_EPS); rm -rf $(DIA_PNG); rm -rf $(DIA_PDF) + cd figures/; rm -rf $(TGIF_EPS); rm -rf $(TGIF_PNG); rm -rf $(TGIF_PDF) + +clean: figures-clean + rm -rf tutorial.aux tutorial.cp tutorial.cps tutorial.fn tutorial.ky tutorial.pg tutorial.tp tutorial.vr tutorial.toc tutorial.log tutorial.pdf tutorial.html tutorial/ diff --git a/doc/tutorial/introduction.texi b/doc/tutorial/introduction.texi new file mode 100644 index 000000000..f9233250b --- /dev/null +++ b/doc/tutorial/introduction.texi @@ -0,0 +1,360 @@ + +@c ======================================================================== +@c Begin document body here +@c ======================================================================== + +@c ======================================================================== +@c PART: Introduction +@c ======================================================================== +@c The below chapters are under the major heading "Introduction" +@c This is similar to the Latex \part command +@c +@c ======================================================================== +@c Introduction +@c ======================================================================== +@node Introduction +@chapter Introduction + +@menu +* For ns-2 Users:: +* Contributing:: +* Tutorial Organization:: +@end menu + +The ns-3 simulator is a discrete-event network simulator targeted primarily +for research and educational use. The +@uref{http://www.nsnam.org,,ns-3 project}, +started in 2006, is an open-source project. The goal of the project is to +build a new network simulator primarily for research and educational use. + +Primary documentation for the ns-3 project is available in three forms: +@itemize @bullet +@item @uref{http://www.nsnam.org/doxygen/index.html,,ns-3 Doxygen/Manual}: +Documentation of the public APIs of the simulator +@item Tutorial (this document) +@item @uref{http://www.nsnam.org/wiki/index.php,, ns-3 wiki} +@end itemize + +The purpose of this tutorial is to introduce new ns-3 users to the +system in a structured way. It is sometimes difficult for new users to +glean essential information from detailed manuals and to convert this +information into working simulations. In this tutorial, we will build +several example simulations, introducing and explaining key concepts and +features as we go. + +As the tutorial unfolds, we will introduce the full ns-3 documentation +and provide pointers to source code for those interested in delving deeper +into the workings of the system. + +A few key points are worth noting at the onset: +@itemize @bullet +@item ns-3 is not an extension of @uref{http://www.isi.edu/nsnam/ns,,ns-2}; +it is a new simulator. The two simulators are both written in C++ but ns-3 +is a new simulator that does not support the ns-2 APIs. Some models from ns-2 +have already been ported from ns-2 to ns-3. The project will continue to +maintain ns-2 while ns-3 is being built, and will study transition and +integration mechanisms. +@item ns-3 is open-source, and the project strives to maintain an open +environment for researchers to contribute and share their software. +@end itemize + +@node For ns-2 Users +@section For ns-2 Users + +For those familiar with ns-2, the most visible outward change when moving to +ns-3 is the choice of scripting language. ns-2 is typically scripted in Tcl +and results of simulations can be visualized using the Network Animator +@command{nam}. In ns-3 there is currently no visualization module, and Python +bindings have been developed (Tcl bindings have been prototyped +using @uref{http://www.swig.org,,SWIG}, but are not supported by the +current development team). In this tutorial, we will concentrate on +scripting directly in C++ and interpreting results via trace files. + +But there are similarities as well (both, for example, are based +on C++ objects, and some code from ns-2 has already been ported +to ns-3). We will try to highlight differences between ns-2 and ns-3 +as we proceed in this tutorial. + +@node Contributing +@section Contributing + +@cindex contributing +ns-3 is a research and educational simulator, by and for the research +community. It will rely on the ongoing contributions of the community to +develop new models, debug or maintain existing ones, and share results. There +are a few policies that we hope will encourage people to contribute to ns-3 +like they have for ns-2: +@itemize @bullet +@item open source licensing based on GNU GPLv2 compatibility +@item @uref{http://www.nsnam.org/wiki/index.php,,wiki} +@item @uref{http://www.nsnam.org/wiki/index.php/Contributed_Code,,Contributed Code} page, similar to ns-2's popular +@uref{http://nsnam.isi.edu/nsnam/index.php/Contributed_Code,,Contributed Code} +page +@item @code{src/contrib} directory (we will host your contributed code) +@item open @uref{http://www.nsnam.org/bugzilla,,bug tracker} +@item ns-3 developers will gladly help potential contributors to get +started with the simulator (please contact @uref{http://www.nsnam.org/people.html,,one of us}) +@end itemize + +If you are an ns user, please consider providing your feedback, bug fixes, or +code to the project. + +@node Tutorial Organization +@section Tutorial Organization + +The tutorial assumes that new users might initially follow a path such as the +following: + +@itemize @bullet +@item Browse the source code and documentation, to get a feel for +the simulator and what it might be like to use; +@item Try to download and build a copy; +@item Try to run a few sample programs, and perhaps change some configurations; +@item Look at simulation output, and try to adjust it +@end itemize + +As a result, we have tried to organize the tutorial along the above +broad sequences of events. + +@c ======================================================================== +@c Browsing ns-3 +@c ======================================================================== + +@node Browsing ns-3 +@chapter Browsing ns-3 + +@menu +* Source Code:: +* Doxygen:: +* Other Documentation:: +@end menu + +@node Source Code +@section Source Code + +The most recent code can be browsed on our web server at the following link: +@uref{http://code.nsnam.org/?sort=lastchange}. If you click on the bold +repository names on the left of the page, you will see @emph{changelogs} for +these repositories, and links to the @emph{manifest}. From the manifest +links, one can browse the source tree. + +The top-level directory will look something like: +@verbatim +drwxr-xr-x [up] +drwxr-xr-x doc manifest +drwxr-xr-x examples manifest +drwxr-xr-x ns3 manifest +drwxr-xr-x regression manifest +drwxr-xr-x samples manifest +drwxr-xr-x scratch manifest +drwxr-xr-x src manifest +drwxr-xr-x tutorial manifest +drwxr-xr-x utils manifest +-rw-r--r-- 135 .hgignore file | revisions | annotate +-rw-r--r-- 891 .hgtags file | revisions | annotate +-rw-r--r-- 441 AUTHORS file | revisions | annotate +-rw-r--r-- 17987 LICENSE file | revisions | annotate +-rw-r--r-- 4948 README file | revisions | annotate +-rw-r--r-- 4917 RELEASE_NOTES file | revisions | annotate +-rw-r--r-- 7 VERSION file | revisions | annotate +-rwxr-xr-x 99143 waf file | revisions | annotate +-rwxr-xr-x 28 waf.bat file | revisions | annotate +-rw-r--r-- 30584 wscript file | revisions | annotate +@end verbatim + +The source code is mainly in the @code{src} directory. You can view source +code by clicking on the @code{manifest} link to the right of the directory +name. If you click on the @code{manifest} link to the right of the src +directory you will find a subdirectory. If you click on the @code{manifest} +link next to the @code{core} subdirectory in under @code{src}, you will find +a list of files. The first file you will find is @code{assert.h}. If you +click on the @code{file} link, you will be sent to the source file for +@code{assert.h}. + +Example scripts are in the @code{examples} directory. The @code{examples} +directory is a good place to start browsing the code. + +For ns-2 users, who may be familiar with the @code{simple.tcl} example script +in the ns-2 documentation, an analogous script is found in +@code{examples/simple-point-to-point.cc} with a Python equivalent found +in @emph{(pending Python merge)}. + +@node Doxygen +@section Doxygen + +We document all of our APIs using @uref{http://www.stack.nl/~dimitri/doxygen/,,Doxygen}. Current builds of this documentation are available at: +@uref{http://www.nsnam.org/doxygen/index.html}, which are worth an initial +look. + +@node Other Documentation +@section Other Documentation + +We provide a large amount of documentation regarding the various components +of ns-2 on our website. See: @uref{http://www.nsnam.org/documents.html}. + +@c ======================================================================== +@c Resources +@c ======================================================================== + +@node Resources +@chapter Resources + +@menu +* The Web:: +* Mercurial:: +* Waf:: +* Environment Idioms Design Patterns:: +* Socket Programming:: +@end menu + +@node The Web +@section The Web + +@cindex www.nsnam.org +There are several important resources of which any ns-3 user must be +aware. The main web site is located at @uref{http://www.nsnam.org} +and provides access to basic information about the ns-3 system. +Detailed documentation is available through the main web site at +@uref{http://www.nsnam.org/documents.html}. + +@cindex documentation +@cindex architecture +You can find documents relating to the system architecture from this page, +and also gain access to the detailed software documentation. The software +system is documented in great detail using +@uref{http://www.stack.nl/~dimitri/doxygen/,,Doxygen}. There is a Wiki that +complements the main ns-3 web site which you will find at +@uref{http://www.nsnam.org/wiki/}. + +You will find user and developer FAQs there as well as troubleshooting guides, +third-party contributed code, papers, etc. The source code may be found +and browsed at @uref{http://code.nsnam.org/}. + +@cindex repository!ns-3-dev +@cindex repository!releases +There you will find the current development tree in the repository named +@code{ns-3-dev}. Past releases and experimental repositories of the core +developers may also be found there. + +@node Mercurial +@section Mercurial + +Complex software systems need some way to manage the organization and +changes to the underlying code and documentation. There are many ways to +perform this feat, and you may have heard of some of the systems that are +currently used to do this. The Concurrent Version System (CVS) is probably +the most well known. + +@cindex software configuration management +@cindex Mercurial +The ns-3 project uses Mercurial as its source code management system. +Although you do not need to know much about Mercurial in order to complete +this tutorial, we recommend becoming familiar with Mercurial and using it +to access the source code. Mercurial has a web site at +@uref{http://www.selenic.com/mercurial/}, +from which you can get binary or source releases of this Software +Configuration Management (SCM) system. Selenic (the developer of Mercurial) +also provides a tutorial at +@uref{http://www.selenic.com/mercurial/wiki/index.cgi/Tutorial/}, +and a QuickStart guide at +@uref{http://www.selenic.com/mercurial/wiki/index.cgi/QuickStart/}. + +You can also find vital information about using Mercurial and ns-3 +on the main ns-3 web site. + +@node Waf +@section Waf + +@cindex Waf +@cindex make +@cindex build +Once you have source code downloaded to your local system, you will need +to compile that source to produce usable programs. Just as in the case of +source code management, there are many tools available to perform this +function. Probably the most will known of these tools is @code{make}. Along +with being the most well known, @code{make} is probably the most difficult to +use in a very large and highly configurable system. Because of this, many +alternatives have been developed. Recently these systems have been developed +using the Python language. + +The build system @code{Waf} is used on the ns-3 project. It is one +of the new generation of Python-based build systems. You will not need to +understand any Python to build the existing ns-3 system, and will +only have to understand a tiny and intuitively obvious subset of Python in +order to extend the system in most cases. + +For those interested in the gory details of Waf, the main web site can be +found at @uref{http://freehackers.org/\~tnagy/waf.html}. + +@node Environment Idioms Design Patterns +@section Environment, Idioms, and Design Patterns + +@cindex C++ +As mentioned above, scripting in ns-3 is done in C++. A working +knowledge of C++ and object-oriented concepts is assumed in this document. +We will take some time to review some of the more advanced concepts or +possibly unfamiliar language features, idioms and design patterns as they +appear. We don't want this tutorial to devolve into a C++ tutorial, though, +so we do expect a basic command of the language. There are an almost +unimaginable number of sources of information on C++ available on the web or +in print. + +If you are new to C++, you may want to find a tutorial- or cookbook-based +book or web site and work through at least the basic features of the language +before proceeding. + +@subsection Environment + +@cindex toolchain +@cindex GNU +The ns-3 system uses the GNU ``toolchain'' for development. +A software toolchain is the set of programming tools available in the given +environment. For a quick review of what is included in the GNU toolchain see, +@uref{http://en.wikipedia.org/wiki/GNU_toolchain}. + +@cindex Linux +Typically an ns-3 author will work in Linux or a Linux-like +environment. For those running under Windows, there do exist environments +which simulate the Linux environment to various degrees. The ns-3 +project supports development in the Cygwin and the MinGW environments for +these users. See @uref{http://www.cygwin.com/} and +@uref{http://www.mingw.org/} for details on downloading and using these +systems. Cygwin provides many of the popular Linux system commands. +It can, however, sometimes be problematic due to the way it actually does its +emulation, and sometimes interactions with other Windows software can cause +problems. + +@cindex Cygwin +@cindex MinGW +If you do use Cygwin or MinGW; and use Logitech products, we will save you +quite a bit of heartburn right off the bat and encourage you to take a look +at the @uref{http://www.mingw.org/MinGWiki/index.php/FAQ,,MinGW FAQ}. + +@cindex Logitech +Search for ``Logitech'' and read the FAQ entry, ``why does make often +crash creating a sh.exe.stackdump file when I try to compile my source code.'' +Believe it or not, the @code{Logitech Process Monitor} insinuates itself into +every DLL in the system when it is running. It can cause your Cygwin or +MinGW DLLs to die in mysterious ways and often prevents debuggers from +running. Beware of Logitech. + +@node Socket Programming +@section Socket Programming + +@cindex sockets +We will assume a basic facility with the Berkeley Sockets API in the examples +used in this tutorial. If you are new to sockets, we recommend reviewing the +API and some common usage cases. For a good overview of programming TCP/IP +sockets we recommend @uref{http://www.elsevier.com/wps/product/cws_home/680765,,Practical TCP/IP Sockets in C, Donahoo and Calvert}. + +There is an associated web site that includes source for the examples in the +book, which you can find at: +@uref{http://cs.baylor.edu/~donahoo/practical/CSockets/}. + +If you understand the first four chapters of the book (or for those who do +not have access to a copy of the book, the echo clients and servers shown in +the website above) you will be in good shape to understand the tutorial. +There is a similar book on Multicast Sockets, +@uref{http://www.elsevier.com/wps/product/cws_home/700736,,Multicast Sockets, Makofske and Almeroth}. +that covers material you may need to understand for the multicast examples. + From f201618a5fb92daf4b510d9123100e60cbfa86f5 Mon Sep 17 00:00:00 2001 From: Craig Dowell Date: Sat, 28 Jun 2008 19:55:58 -0700 Subject: [PATCH 068/495] ignore moved figures dir --- doc/tutorial/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/tutorial/Makefile b/doc/tutorial/Makefile index 5428d9265..3501a3e94 100644 --- a/doc/tutorial/Makefile +++ b/doc/tutorial/Makefile @@ -45,5 +45,5 @@ figures-clean: cd figures/; rm -rf $(DIA_EPS); rm -rf $(DIA_PNG); rm -rf $(DIA_PDF) cd figures/; rm -rf $(TGIF_EPS); rm -rf $(TGIF_PNG); rm -rf $(TGIF_PDF) -clean: figures-clean +clean: # figures-clean rm -rf tutorial.aux tutorial.cp tutorial.cps tutorial.fn tutorial.ky tutorial.pg tutorial.tp tutorial.vr tutorial.toc tutorial.log tutorial.pdf tutorial.html tutorial/ From 9f205e0fba69442f20c33c40a23c9f24f3943982 Mon Sep 17 00:00:00 2001 From: Craig Dowell Date: Sat, 28 Jun 2008 20:02:25 -0700 Subject: [PATCH 069/495] external dependency on figures --- doc/tutorial/{in-process => }/figures/README | 0 doc/tutorial/{in-process => }/figures/dumbbell.dia | Bin doc/tutorial/{in-process => }/figures/helpers.obj | 0 doc/tutorial/{in-process => }/figures/oneobj.png | Bin doc/tutorial/{in-process => }/figures/pp.dia | Bin doc/tutorial/{in-process => }/figures/star.dia | Bin doc/tutorial/{in-process => }/figures/threeobj.png | Bin 7 files changed, 0 insertions(+), 0 deletions(-) rename doc/tutorial/{in-process => }/figures/README (100%) rename doc/tutorial/{in-process => }/figures/dumbbell.dia (100%) rename doc/tutorial/{in-process => }/figures/helpers.obj (100%) rename doc/tutorial/{in-process => }/figures/oneobj.png (100%) rename doc/tutorial/{in-process => }/figures/pp.dia (100%) rename doc/tutorial/{in-process => }/figures/star.dia (100%) rename doc/tutorial/{in-process => }/figures/threeobj.png (100%) diff --git a/doc/tutorial/in-process/figures/README b/doc/tutorial/figures/README similarity index 100% rename from doc/tutorial/in-process/figures/README rename to doc/tutorial/figures/README diff --git a/doc/tutorial/in-process/figures/dumbbell.dia b/doc/tutorial/figures/dumbbell.dia similarity index 100% rename from doc/tutorial/in-process/figures/dumbbell.dia rename to doc/tutorial/figures/dumbbell.dia diff --git a/doc/tutorial/in-process/figures/helpers.obj b/doc/tutorial/figures/helpers.obj similarity index 100% rename from doc/tutorial/in-process/figures/helpers.obj rename to doc/tutorial/figures/helpers.obj diff --git a/doc/tutorial/in-process/figures/oneobj.png b/doc/tutorial/figures/oneobj.png similarity index 100% rename from doc/tutorial/in-process/figures/oneobj.png rename to doc/tutorial/figures/oneobj.png diff --git a/doc/tutorial/in-process/figures/pp.dia b/doc/tutorial/figures/pp.dia similarity index 100% rename from doc/tutorial/in-process/figures/pp.dia rename to doc/tutorial/figures/pp.dia diff --git a/doc/tutorial/in-process/figures/star.dia b/doc/tutorial/figures/star.dia similarity index 100% rename from doc/tutorial/in-process/figures/star.dia rename to doc/tutorial/figures/star.dia diff --git a/doc/tutorial/in-process/figures/threeobj.png b/doc/tutorial/figures/threeobj.png similarity index 100% rename from doc/tutorial/in-process/figures/threeobj.png rename to doc/tutorial/figures/threeobj.png From 9bb182aa54760d69288a174eb93e409a95f56e24 Mon Sep 17 00:00:00 2001 From: Craig Dowell Date: Sat, 28 Jun 2008 22:39:06 -0700 Subject: [PATCH 070/495] work through second tutorial example --- doc/tutorial/building-topologies.texi | 544 ++++++++++++++++---------- examples/second.cc | 20 +- examples/wscript | 6 - 3 files changed, 364 insertions(+), 206 deletions(-) diff --git a/doc/tutorial/building-topologies.texi b/doc/tutorial/building-topologies.texi index a78531b11..535477b24 100644 --- a/doc/tutorial/building-topologies.texi +++ b/doc/tutorial/building-topologies.texi @@ -16,285 +16,437 @@ @chapter Building Topologies @menu -* Building a Star Topology +* Building a Bus Network Topology @end menu @c ======================================================================== -@c Building a Star Topology +@c Building a Bus Network Topology @c ======================================================================== -@node Building a Star Topology -@section Building a Star Topology +@node Building a Bus Network Topology +@section Building a Bus Network Topology @cindex topology @cindex topology|star -In this section we are going to use the point-to-point topology primitive we -have explored in quite some detail to construct a star network. In the star, -there is a central node that is connected to other nodes in a ``hub and spoke'' -fashion, with each ``spoke'' being a point-to-point link. +In this section we are going to expand our mastery of ns-3 network devices and +channels to cover an example of a bus network. Ns-3 provides a net device and +channel we call CSMA (Carrier Sense Multiple Access). -We provide an example of a star topology simulation script on our -@code{examples} directory. Go ahead and open @code{examples/star.cc} in your -favorite editor. You will have already seen enough ns-3 code to understand -this example, but we will go over the script briefly and examine some of the -output. +The ns-3 CSMA device models a simple network in the spirit of Ethernet. A real +Ethernet uses CSMA/CD (Carrier Sense Multiple Access with Collision Detection) +scheme with exponentially increasing backoff to contend for the shared +transmission medium. The ns-3 CSMA device and channel models only a +subset of this. -There is an amazingly beautiful bit of ASCII art at the beginning of the file -that shows the topology used in the script. Most ns-3 example programs -provide this, which can be surprisingly useful in understanding the code. +Just as we have seen point-to-point topology helper objects when constructing +point-to-point topologies, we will see equivalent CSMA topology helpers in +this section. The appearance and operation of these helpers should look +quite familiar to you. + +We provide an example script in our @code{examples} directory. This script +builds on the @code{first.cc} script and adds a CSMA network to the +point-to-point simulation we've already considered. Go ahead and open +@code{examples/second.cc} in your favorite editor. You will have already seen +enough ns-3 code to understand most of what is going on in this example, but +we will go over the entire script and examine some of the output. + +Just as in the @code{first.cc} example (and in all ns-3 examples) the file +begins with an emacs mode line and some GPL boilerplate. + +One thing that can be surprisingly useful is a small bit of ASCII art that +shows a cartoon of the network topology constructed in the example. You will +find a similar ``drawing'' in most of our examples. + +In this case, you can see that we are going to extend our point-to-point +example (the link between the nodes n0 and n1 below) by hanging a bus network +off of the right side. Notice that this is the default network topology +since you can actually vary the number of nodes created on the LAN. If you +set nCsma to one, there will be a total of two nodes on the LAN (CSMA +channel) --- one required node and one ``extra'' node. By default there are +thee ``extra'' nodes as seen below: @verbatim - // Network topology - // - // n3 n2 - // | / - // | / - // n4 --- n0 --- n1 - // / | - // / | - // n5 n6 +// Default Network Topology +// +// 10.1.1.0 +// n0 -------------- n1 n2 n3 n4 +// point-to-point | | | | +// ================ +// LAN 10.1.2.0 @end verbatim -There are seven nodes in this simulation, nodes zero through six. Node zero is -the hub of this star network. We are going to discover that there will be a -flow of echo packets between node four and node one, between node three and -node six, and node five and node two. - -The script starts by creating seven nodes in a @code{NodeContainer} and -installs internet protocol stacks on all seven. +The actual code begins by loading module include files just as was done in the +@code{first.cc} example. Then the ns-3 namespace is @code{used} and a logging +component is defined. This is all just as it was in @code{first.cc}, so there +is nothing new yet. @verbatim - int + #include "ns3/core-module.h" + #include "ns3/simulator-module.h" + #include "ns3/node-module.h" + #include "ns3/helper-module.h" + #include "ns3/global-routing-module.h" + + using namespace ns3; + + NS_LOG_COMPONENT_DEFINE ("SecondScriptExample"); +@end verbatim + +The main program begins by enabling the @code{UdpEchoClientApplication} and +@code{UdpEchoServerApplication} logging components at @code{INFO} level so +we can see some output when we run the example. This should be entirely +familiar to you so far. + +@verbatim + int main (int argc, char *argv[]) { - NodeContainer nodes; - nodes.Create (7); - - InternetStackHelper stack; - stack.Install (nodes); - - ... + LogComponentEnable("UdpEchoClientApplication", LOG_LEVEL_INFO); + LogComponentEnable("UdpEchoServerApplication", LOG_LEVEL_INFO); @end verbatim -It then creates six more @code{NodeContainer}s representing the nodes at each -end of the six spokes. In all cases, the first node in the spoke is node zero. +Next, you will see some familiar code that will allow you to change the number +of devices on the CSMA network via command line argument. We did something +similar when we allowed the number of packets sent to be changed in the section +on command line arguments. @verbatim - NodeContainer nodes0and1 = NodeContainer (nodes.Get (0), nodes.Get (1)); - NodeContainer nodes0and2 = NodeContainer (nodes.Get (0), nodes.Get (2)); - NodeContainer nodes0and3 = NodeContainer (nodes.Get (0), nodes.Get (3)); - NodeContainer nodes0and4 = NodeContainer (nodes.Get (0), nodes.Get (4)); - NodeContainer nodes0and5 = NodeContainer (nodes.Get (0), nodes.Get (5)); - NodeContainer nodes0and6 = NodeContainer (nodes.Get (0), nodes.Get (6)); + uint32_t nCsma = 3; + CommandLine cmd; + cmd.AddValue ("nCsma", "Number of \"extra\" CSMA nodes/devices", nCsma); + cmd.Parse (argc,argv); @end verbatim -These node containers will be used during the creation of the point-to-point -links by the @code{PointToPointHelper}. The next bit of code instantiates -a helper and sets the default values for the device @code{DataRate} and the -channel @code{Delay} attributes as we have previously seen. +The next step is to create two nodes that we will connect via the +point-to-point link. The @code{NodeContainer} is used to do this just as was +done in @code{first.cc}. + +@verbatim + NodeContainer p2pNodes; + p2pNodes.Create (2); +@end verbatim + +Next, we delare another @code{NodeContainer} to hold the nodes that will be +part of the bus (CSMA) network. First we just instantiate the container +object itself. + +@verbatim + NodeContainer csmaNodes; + csmaNodes.Add (p2pNodes.Get (1)); + csmaNodes.Create (nCsma); +@end verbatim + +The next line of code @code{Get}s the first node (as in having an index of one) +from the point-to-point node container and adds it to the container of nodes +that will get CSMA devices. The node in question is going to end up with a +point-to-point device and a CSMA device. We then create a number of ``extra'' +nodes that compose the remainder of the CSMA network. + +The next bit of code should be quite familiar by now. We instantiate a +@code{PointToPointHelper} and set the associated default attributes so that +we create a five megabit per second transmitter on devices created using the +helper and a two millisecond delay on channels created by the helper. @verbatim PointToPointHelper pointToPoint; pointToPoint.SetDeviceParameter ("DataRate", StringValue ("5Mbps")); pointToPoint.SetChannelParameter ("Delay", StringValue ("2ms")); + + NetDeviceContainer p2pDevices; + p2pDevices = pointToPoint.Install (p2pNodes); @end verbatim -The next step is to install the net devices on the nodes referenced by the -six node containers and connect them via channels. We used one instance -of the @code{pointToPoint.Install} method to construct our single -point-to-point link in the @code{first.cc} script. This code just does that -six times between different combinations of nodes. +We then instantiate a @code{NetDeviceContainer} to keep track of the +point-to-point net devices and we install devices on the ``point-to-point +nodes. + +We mentioned above that you were going to see a helper for CSMA devices and +channels, and the next lines introduce them. The @code{CsmaHelper} works just +like a @code{PointToPointHelper}, but it creates and connects CSMA devices and +channels. @verbatim - NetDeviceContainer devicesOnNodes0and1 = pointToPoint.Install (nodes0and1); - NetDeviceContainer devicesOnNodes0and2 = pointToPoint.Install (nodes0and2); - NetDeviceContainer devicesOnNodes0and3 = pointToPoint.Install (nodes0and3); - NetDeviceContainer devicesOnNodes0and4 = pointToPoint.Install (nodes0and4); - NetDeviceContainer devicesOnNodes0and5 = pointToPoint.Install (nodes0and5); - NetDeviceContainer devicesOnNodes0and6 = pointToPoint.Install (nodes0and6); + CsmaHelper csma; + + NetDeviceContainer csmaDevices; + csmaDevices = csma.Install (csmaNodes); @end verbatim -Note that this does mean that node zero will have six net devices after this -code executes. Recall that we need to keep containers holding the net devices -we created in order to do IP address assignment. This is the next step in the -script. +Just as we created a @code{NetDeviceContainer} to hold the devices created by +the @code{PointToPointHelper} we create a @code{NetDeviceContainer} to hold +the devices created by our @code{CsmaHelper}. We call the @code{Install} +method of the @code{CsmaHelper} to install the devices into the nodes of the +@code{csmaNodes NodeContainer}. -Just as in @code{first.cc} we use the Ipv4AddressHelper to make it easy to -deal with addressing. We need to create different networks for each stub, so -we have to call the @code{SetBase} method and provide a different network -number before assigning addresses to the devices on each network. We make it -easy to remember what is what by setting the least significant bits of the -network number to the unique node on the spoke. For example, the spoke between -nodes zero and one is network 10.1.1; and the spoke between nodes zero and -two is 10.1.2, etc. Note that the network mask is set to 255.255.255.252 in -all cases. +We now have our nodes, devices and channels created, but we have no protocol +stacks present. Just as in the @code{first.cc} script, we will use the +@code{InternetStackHelper} to install these stacks. @verbatim - Ipv4AddressHelper ipv4; - - ipv4.SetBase ("10.1.1.0", "255.255.255.252"); - Ipv4InterfaceContainer interfacesOnNodes0and1 = - ipv4.Assign (devicesOnNodes0and1); - - ipv4.SetBase ("10.1.2.0", "255.255.255.252"); - Ipv4InterfaceContainer interfacesOnNodes0and2 = - ipv4.Assign (devicesOnNodes0and2); - - ipv4.SetBase ("10.1.3.0", "255.255.255.252"); - Ipv4InterfaceContainer interfacesOnNodes0and3 = - ipv4.Assign (devicesOnNodes0and3); - - ipv4.SetBase ("10.1.4.0", "255.255.255.252"); - Ipv4InterfaceContainer interfacesOnNodes0and4 = - ipv4.Assign (devicesOnNodes0and4); - - ipv4.SetBase ("10.1.5.0", "255.255.255.252"); - Ipv4InterfaceContainer interfacesOnNodes0and5 = - ipv4.Assign (devicesOnNodes0and5); - - ipv4.SetBase ("10.1.6.0", "255.255.255.252"); - Ipv4InterfaceContainer interfacesOnNodes0and6 = - ipv4.Assign (devicesOnNodes0and6); + InternetStackHelper stack; + stack.Install (p2pNodes.Get (0)); + stack.Install (csmaNodes); @end verbatim -When the above code has executed, we will have the topology complete and then -need to move on to applications. The code to do this should be familiar to -you, but we have rearranged it slightly. +Recall that we took one of the nodes from the @code{p2pNodes} container and +added it to the @code{csmaNodes} container. Thus we only need to install +the stacks on the remaining @code{p2pNodes} node, and all of the nodes in the +@code{csmaNodes} container. -We use an ApplicationContainer to hold the results of the helper operations, -and use the UdpEchoServerHelper and UdpEchoClient server to configure the -apps just as we did in the @code{first.cc} script. +Just as in the @code{first.cc} example script, we are going to use the +@code{Ipv4AddressHelper} to assign IP addresses to our device interfaces. +First we use the network 10.1.1.0 to create the two addresses needed for our +two point-to-point devices. @verbatim - uint16_t port = 9; - - ApplicationContainer apps; - - UdpEchoServerHelper server; - server.SetPort (port); - - UdpEchoClientHelper client; - client.SetAppAttribute ("MaxPackets", UintegerValue (10)); - client.SetAppAttribute ("Interval", StringValue ("10ms")); - client.SetAppAttribute ("PacketSize", UintegerValue (137)); + Ipv4AddressHelper address; + address.SetBase ("10.1.1.0", "255.255.255.0"); + Ipv4InterfaceContainer p2pInterfaces; + p2pInterfaces = address.Assign (p2pDevices); @end verbatim -The next section of code is repeated three times, once for each data flow. -We'll skim over the first instance quickly. The other two differ only in -the nodes selected and the starting times of the flows. +Recall that we save the created interfaces in a container to make it easy to +pull out addressing information later. -Just as we did in the @code{first.cc} script, we use the -@code{UdpEchoServerHelper} to install the echo server on a node (in this case, -node number one -- the rightmost spoke in the topology). We tell the server -application to start at a simulation time of one second. We use the -@code{UdpEchoClientHelper} to install the echo client on a node (in this case, -node number four -- the leftmost spoke in the topology). We tell the client -to start sending data at a simulation time of two seconds. +We then need to assign IP addresses to our CSMA device interfaces. The +operation works just as it did for the point-to-point case, except we now +are performing the operation on a container that has a variable number of +CSMA devices --- remember we made that number changeable by command line +argument. So the CSMA devices will be associated with IP addresses from +network number 10.1.2.0 in this case. @verbatim - // - // Echo from node 4 to node 1 starting at 2 sec - // - apps = server.Install (nodes.Get (1)); - apps.Start (Seconds (1.0)); - - client.SetRemote (interfacesOnNodes0and1.GetAddress (1), port); - apps = client.Install (nodes.Get (4)); - apps.Start (Seconds (2.0)); + address.SetBase ("10.1.2.0", "255.255.255.0"); + Ipv4InterfaceContainer csmaInterfaces; + csmaInterfaces = address.Assign (csmaDevices); @end verbatim -The next sections do the same thing, but for nodes three and six with a flow -starting at 2.1 seconds, and for nodes five and two with flow starting at 2.2 -seconds. +Now, we have a topology built, but we need applications. This section is +going to be fundamentally similar to the applications section of +@code{first.cc} but we are going to instantiate the server on one of the +nodes that has a CSMA node and the client on the node having only a +point-to-point device. -The only piece of code you may not have seen before follows. Since we have -built an internetwork, we need some form of internetwork routing. Ns-3 -provides what we call a global route manager to set up the routing tables on -nodes. This route manager has a global function that runs though the nodes -of the simulation and does the hard work of setting up routing for you. +You should completely understand the code for setting up the server since we +have seen this before. + +@verbatim + ApplicationContainer serverApps = echoServer.Install (csmaNodes.Get (nCsma)); + serverApps.Start (Seconds (1.0)); + serverApps.Stop (Seconds (10.0)); +@end verbatim + +Recall that the @code{csmaNodes NodeContainer} contains one of the +nodes created for the point-to-point network and @code{nCsma} extra nodes. +What we want to get is the last of the ``extra'' nodes. The zeroth entry of +the @code{csmaNodes} container will the the point-to-point node. The easy +way to think of this, then, is if we create one ``extra'' CSMA node, then it +will be be at index one of the @code{csmaNodes} container and, by induction, +if we create @code{nCsma} ``extra'' nodes the last one will be at index +@code{nCsma}. You see this exhibited in the first line of code. + +The client application is set up exactly as we did in the @code{first.cc} +example script. We point the client to the server we set up on the last of +the ``extra'' CSMA nodes and install the client onto the point-to-point node +that is not associated with any CSMA device. + +@verbatim + UdpEchoClientHelper echoClient; + echoClient.SetRemote (csmaInterfaces.GetAddress (nCsma), 9); + echoClient.SetAppAttribute ("MaxPackets", UintegerValue (1)); + echoClient.SetAppAttribute ("Interval", TimeValue (Seconds (1.))); + echoClient.SetAppAttribute ("PacketSize", UintegerValue (1024)); + + ApplicationContainer clientApps = echoClient.Install (p2pNodes.Get (0)); + clientApps.Start (Seconds (2.0)); + clientApps.Stop (Seconds (10.0)); +@end verbatim + +Since we have actually built an internetwork here, we need some form of +internetwork routing. Ns-3 provides what we call a global route manager to +set up the routing tables on nodes. This route manager has a global function + that runs though the nodes created for the simulation and does the hard work +of setting up routing for you. Basically, what happens is that each node behaves as if it were an OSPF router that communicates instantly and magically with all other routers. Each node -generates link advertisements to the global route manager, which uses this -information to construct the routing tables for each node. +generates link advertisements and communicates them directly to a global route + manager, which uses this global information to construct the routing tables +for each node. Setting up this form of routing is a one-liner: @verbatim GlobalRouteManager::PopulateRoutingTables (); @end verbatim The remainder of the script should be very familiar to you. We just enable -ASCII and pcap tracing and run the simulation: +pcap tracing, run the simulation and exit the script. Notice that enabling +pcap tracing using the CSMA helper is done in the same way as for the pcap +tracing with the point-to-point helper. @verbatim - std::ofstream ascii; - ascii.open (``star.tr''); - PointToPointHelper::EnableAsciiAll (ascii); - PointToPointHelper::EnablePcapAll (``star''); + PointToPointHelper::EnablePcapAll ("second"); + CsmaHelper::EnablePcapAll ("second"); Simulator::Run (); Simulator::Destroy (); + return 0; } @end verbatim -In order to run this example, you use waf. All of our example programs are -built by default, so all you have to do is run it. Now, you did not build -this script by copying it into the scratch directory, so you don't have to -add the scratch directory to the run command. You just do the following, +In order to run this example, you have to copy the @code{second.cc} example +script into the scratch directory and use waf to build just as you did with +the @code{first.cc} example. If you are in the top-level directory of the +repository you would type, @verbatim - ./waf --run star + cp examples/second.cc scratch/ + ./waf + ./waf --run scratch/second @end verbatim -There is no output from this script by default. It will just go off and -silently do its thing. All you will see are waf messages: +Since we have set up the UDP echo applications just as we did in the +@code{first.cc} script, you will see similar output. @verbatim - ~/repos/ns-3-tutorial > ./waf --run star - Entering directory `/home/craigdo/repos/ns-3-tutorial/build' + ~/repos/ns-3-dev > ./waf --run scratch/second + Entering directory `/home/craigdo/repos/ns-3-dev/build' Compilation finished successfully - ~/repos/ns-3-tutorial > + Sent 1024 bytes to 10.1.2.4 + Received 1024 bytes from 10.1.1.1 + Received 1024 bytes from 10.1.2.4 + ~/repos/ns-3-dev > @end verbatim +Recall that the first message, @code{Sent 1024 bytes to 10.1.2.4} is the +UDP echo client sending a packet to the server. In this case, the server +is on a different network (10.1.2.0). The second message, @code{Received 1024 +bytes from 10.1.1.1}, is from the UDP echo server, generated when it receives +the echo packet. The final message, @code{Received 1024 bytes from 10.1.2.4} +is from the echo client, indicating that it has received its echo back from +the server. + If you now go and look in the top level directory, you will find a number of trace files: @verbatim - ~/repos/ns-3-tutorial > ls *.pcap *.tr - star-0-0.pcap star-0-3.pcap star-1-0.pcap star-4-0.pcap star.tr - star-0-1.pcap star-0-4.pcap star-2-0.pcap star-5-0.pcap - star-0-2.pcap star-0-5.pcap star-3-0.pcap star-6-0.pcap - ~/repos/ns-3-tutorial > + ~/repos/ns-3-dev > ls *.pcap + second-0-0.pcap second-1-1.pcap second-3-0.pcap + second-1-0.pcap second-2-0.pcap second-4-0.pcap + ~/repos/ns-3-dev > @end verbatim -If you have gone through the tracing section of this tutorial, you know how to -interpret all of these files. For your reading pleasure, we reproduce a -tcpdump from the net device on node four: +Let's take a moment to look at the naming of these files. They all have the +same form --- @code{--.pcap}. For example, the first file +in the listing is @code{second-0-0.pcap} which is the pcap trace from node +zero, device zero. There are no other devices on node zero so this is the +only trace from that node. + +Now look at @code{second-1-0.pcap} and @code{second-1-1.pcap}. The former is +the pcap trace for device zero on node one and the latter is the trace file +for device one on node one. If you refer back to the topology cartoon at +the start of the section, you will see that node one is the node that has +both a point-to-point device and a CSMA device, so we should expect two pcap +traces for that node. + +Now, let's follow the echo packet through the internetwork. First, do a +tcpdump of the trace file for the leftmost point-to-point node --- node zero. @verbatim - [ns-regression] ~/repos/ns-3-tutorial > tcpdump -r star-4-0.pcap -nn -tt - reading from file star-4-0.pcap, link-type PPP (PPP) - 2.000000 IP 10.1.4.2.49153 > 10.1.1.2.9: UDP, length 137 - 2.009068 IP 10.1.1.2.9 > 10.1.4.2.49153: UDP, length 137 - 2.010000 IP 10.1.4.2.49153 > 10.1.1.2.9: UDP, length 137 - 2.019068 IP 10.1.1.2.9 > 10.1.4.2.49153: UDP, length 137 - 2.020000 IP 10.1.4.2.49153 > 10.1.1.2.9: UDP, length 137 - 2.029068 IP 10.1.1.2.9 > 10.1.4.2.49153: UDP, length 137 - 2.030000 IP 10.1.4.2.49153 > 10.1.1.2.9: UDP, length 137 - 2.039068 IP 10.1.1.2.9 > 10.1.4.2.49153: UDP, length 137 - 2.040000 IP 10.1.4.2.49153 > 10.1.1.2.9: UDP, length 137 - 2.049068 IP 10.1.1.2.9 > 10.1.4.2.49153: UDP, length 137 - 2.050000 IP 10.1.4.2.49153 > 10.1.1.2.9: UDP, length 137 - 2.059068 IP 10.1.1.2.9 > 10.1.4.2.49153: UDP, length 137 - 2.060000 IP 10.1.4.2.49153 > 10.1.1.2.9: UDP, length 137 - 2.069068 IP 10.1.1.2.9 > 10.1.4.2.49153: UDP, length 137 - 2.070000 IP 10.1.4.2.49153 > 10.1.1.2.9: UDP, length 137 - 2.079068 IP 10.1.1.2.9 > 10.1.4.2.49153: UDP, length 137 - 2.080000 IP 10.1.4.2.49153 > 10.1.1.2.9: UDP, length 137 - 2.089068 IP 10.1.1.2.9 > 10.1.4.2.49153: UDP, length 137 - 2.090000 IP 10.1.4.2.49153 > 10.1.1.2.9: UDP, length 137 - 2.099068 IP 10.1.1.2.9 > 10.1.4.2.49153: UDP, length 137 - [ns-regression] ~/repos/ns-3-tutorial > + ~/repos/ns-3-dev > tcpdump -r second-0-0.pcap -nn -tt + reading from file second-0-0.pcap, link-type PPP (PPP) + 2.000000 IP 10.1.1.1.49153 > 10.1.2.4.9: UDP, length 1024 + 2.007382 IP 10.1.2.4.9 > 10.1.1.1.49153: UDP, length 1024 + ~/repos/ns-3-dev > @end verbatim -You are encouraged to think through the pcap traces and map them back to the -script. Also, take a look at the @code{star.tr} ASCII trace file (which is -quite large) to make sure you understand what it is telling you. +The first line of the dump indicates that the link type is PPP (point-to-point) +which we should expect. You then see the echo packet leaving node zero on +via the device associated with IP address 10.1.1.1 headed for IP address +10.1.2.4 (the rightmost CSMA node). + +This packet will move over the point-to-point link and be received by the +point-to-point net device on node one. Let's take a look: + +@verbatim + ~/repos/ns-3-dev > tcpdump -r second-1-0.pcap -nn -tt + reading from file second-1-0.pcap, link-type PPP (PPP) + 2.003686 IP 10.1.1.1.49153 > 10.1.2.4.9: UDP, length 1024 + 2.003695 IP 10.1.2.4.9 > 10.1.1.1.49153: UDP, length 1024 + ~/repos/ns-3-dev > +@end verbatim + +Here we see that the link type is also PPP as we would expect. You see the +packet from IP address 10.1.1.1 headed toward 10.1.2.4 appear on this +interface. Now, internally to this node, the packet will be forwarded to the +CSMA interface and we should see it pop out the other device headed for its +ultimate destination. Let's then look at second-1-1.pcap and see if its there. + +@verbatim + ~/repos/ns-3-dev > tcpdump -r second-1-1.pcap -nn -tt + reading from file second-1-1.pcap, link-type EN10MB (Ethernet) + 2.003686 arp who-has 10.1.2.4 (ff:ff:ff:ff:ff:ff) tell 10.1.2.1 + 2.003687 arp reply 10.1.2.4 is-at 00:00:00:00:00:06 + 2.003687 IP 10.1.1.1.49153 > 10.1.2.4.9: UDP, length 1024 + 2.003691 arp who-has 10.1.2.1 (ff:ff:ff:ff:ff:ff) tell 10.1.2.4 + 2.003691 arp reply 10.1.2.1 is-at 00:00:00:00:00:03 + 2.003695 IP 10.1.2.4.9 > 10.1.1.1.49153: UDP, length 1024 + ~/repos/ns-3-dev > +@end verbatim + +As you can see, the link type is now ``Ethernet.'' Something new has appeared, +though. The bus network needs @code{ARP}, the Address Resolution Protocol. +The node knows it needs to send the packet to IP address 10.1.2.4, but it +doesn't know the MAC address of the corresponding node. It broadcasts on the +CSMA network (ff:ff:ff:ff:ff:ff) asking for the device that has IP address +10.1.2.4. In this case, the rightmost node replies saying it is at MAC address +00:00:00:00:00:06. This exchange is seen in the following lines, + +@verbatim + 2.003686 arp who-has 10.1.2.4 (ff:ff:ff:ff:ff:ff) tell 10.1.2.1 + 2.003687 arp reply 10.1.2.4 is-at 00:00:00:00:00:06 +@end verbatim + +Then node one, device one goes ahead and sends the echo packet to the UDP echo +server at IP address 10.1.2.4. We can now look at the pcap trace for the +echo server, + +@verbatim + ~/repos/ns-3-dev > tcpdump -r second-4-0.pcap -nn -tt + reading from file second-4-0.pcap, link-type EN10MB (Ethernet) + 2.003686 arp who-has 10.1.2.4 (ff:ff:ff:ff:ff:ff) tell 10.1.2.1 + 2.003686 arp reply 10.1.2.4 is-at 00:00:00:00:00:06 + 2.003690 IP 10.1.1.1.49153 > 10.1.2.4.9: UDP, length 1024 + 2.003690 arp who-has 10.1.2.1 (ff:ff:ff:ff:ff:ff) tell 10.1.2.4 + 2.003692 arp reply 10.1.2.1 is-at 00:00:00:00:00:03 + 2.003692 IP 10.1.2.4.9 > 10.1.1.1.49153: UDP, length 1024 + ~/repos/ns-3-dev > +@end verbatim + +Again, you see that the link type is ``Ethernet.'' The first two entries are +the ARP exchange we just explained. The third packet is the echo packet +being delivered to its final destination. + +The echo server turns the packet around and needs to send it back to the echo +cleint on 10.1.1.1 but it knows that this address is on another network that +it reaches via IP address 10.1.2.1. This is because we initialized the global +routing and it has figured all of this out for us. But, the echo server node +doesn't know the MAC address of the first CSMA node, so it has to ARP for it +just like the first CSMA node had to do. We leave it as an exercise for you +to find the entries corresponding to the packet returning back on its way to +the client (we have already dumped the traces and you can find them in those +tcpdumps above. + +Finally, let's take a look at one of the CSMA nodes that wasn't involved in +the packet exchange: + +@verbatim + ~/repos/ns-3-dev > tcpdump -r second-2-0.pcap -nn -tt + reading from file second-2-0.pcap, link-type EN10MB (Ethernet) + 2.003686 arp who-has 10.1.2.4 (ff:ff:ff:ff:ff:ff) tell 10.1.2.1 + 2.003691 arp who-has 10.1.2.1 (ff:ff:ff:ff:ff:ff) tell 10.1.2.4 + ~/repos/ns-3-dev > +@end verbatim + +You can see that the CSMA channel is a broadcast medium and so all of the +devices see the ARP requests involved in the packet exchange. The remaining +pcap trace will be identical to this one. + diff --git a/examples/second.cc b/examples/second.cc index 03e77c5fd..817a5e0b9 100644 --- a/examples/second.cc +++ b/examples/second.cc @@ -20,6 +20,15 @@ #include "ns3/helper-module.h" #include "ns3/global-routing-module.h" +// Default Network Topology +// +// 10.1.1.0 +// n0 -------------- n1 n2 n3 n4 +// point-to-point | | | | +// ================ +// LAN 10.1.2.0 + + using namespace ns3; NS_LOG_COMPONENT_DEFINE ("SecondScriptExample"); @@ -30,9 +39,9 @@ main (int argc, char *argv[]) LogComponentEnable("UdpEchoClientApplication", LOG_LEVEL_INFO); LogComponentEnable("UdpEchoServerApplication", LOG_LEVEL_INFO); - uint32_t nCsma = 10; + uint32_t nCsma = 3; CommandLine cmd; - cmd.AddValue ("nCsma", "number of csma devices", nCsma); + cmd.AddValue ("nCsma", "Number of \"extra\" CSMA nodes/devices", nCsma); cmd.Parse (argc,argv); NodeContainer p2pNodes; @@ -70,12 +79,12 @@ main (int argc, char *argv[]) UdpEchoServerHelper echoServer; echoServer.SetPort (9); - ApplicationContainer serverApps = echoServer.Install (csmaNodes.Get (5)); + ApplicationContainer serverApps = echoServer.Install (csmaNodes.Get (nCsma)); serverApps.Start (Seconds (1.0)); serverApps.Stop (Seconds (10.0)); UdpEchoClientHelper echoClient; - echoClient.SetRemote (csmaInterfaces.GetAddress (5), 9); + echoClient.SetRemote (csmaInterfaces.GetAddress (nCsma), 9); echoClient.SetAppAttribute ("MaxPackets", UintegerValue (1)); echoClient.SetAppAttribute ("Interval", TimeValue (Seconds (1.))); echoClient.SetAppAttribute ("PacketSize", UintegerValue (1024)); @@ -86,6 +95,9 @@ main (int argc, char *argv[]) GlobalRouteManager::PopulateRoutingTables (); + PointToPointHelper::EnablePcapAll ("second"); + CsmaHelper::EnablePcapAll ("second"); + Simulator::Run (); Simulator::Destroy (); return 0; diff --git a/examples/wscript b/examples/wscript index cb8f52ae3..7682fecad 100644 --- a/examples/wscript +++ b/examples/wscript @@ -4,12 +4,6 @@ def build(bld): obj = bld.create_ns3_program('hello-simulator') obj.source = 'hello-simulator.cc' - obj = bld.create_ns3_program('second') - obj.source = 'second.cc' - - obj = bld.create_ns3_program('third') - obj.source = 'third.cc' - obj = bld.create_ns3_program('mixed-wireless', ['core', 'simulator', 'mobility', 'wifi', 'point-to-point', 'internet-stack']) obj.source = 'mixed-wireless.cc' From 20865bfde0a300ffccf1d88ec8433939cdab3450 Mon Sep 17 00:00:00 2001 From: Craig Dowell Date: Sun, 29 Jun 2008 10:44:24 -0700 Subject: [PATCH 071/495] finish off csma tutorial example words --- doc/tutorial/building-topologies.texi | 95 ++++++++++++++++++++++++++- 1 file changed, 93 insertions(+), 2 deletions(-) diff --git a/doc/tutorial/building-topologies.texi b/doc/tutorial/building-topologies.texi index 535477b24..81f7dd482 100644 --- a/doc/tutorial/building-topologies.texi +++ b/doc/tutorial/building-topologies.texi @@ -435,8 +435,8 @@ to find the entries corresponding to the packet returning back on its way to the client (we have already dumped the traces and you can find them in those tcpdumps above. -Finally, let's take a look at one of the CSMA nodes that wasn't involved in -the packet exchange: +Let's take a look at one of the CSMA nodes that wasn't involved in the packet +exchange: @verbatim ~/repos/ns-3-dev > tcpdump -r second-2-0.pcap -nn -tt @@ -450,3 +450,94 @@ You can see that the CSMA channel is a broadcast medium and so all of the devices see the ARP requests involved in the packet exchange. The remaining pcap trace will be identical to this one. +Finally, recall that we added the ability to control the number of CSMA devices +in the simulation by command line argument. You can change this argument in +the same way as when we looked at changing the number of packets echoed in the +@code{first.cc} example. Try setting the number of ``extra'' devices to four: + +@verbatim + ~/repos/ns-3-dev > ./waf --run "scratch/second --nCsma=4" + Entering directory `/home/craigdo/repos/ns-3-dev/build' + Compilation finished successfully + Sent 1024 bytes to 10.1.2.5 + Received 1024 bytes from 10.1.1.1 + Received 1024 bytes from 10.1.2.5 + ~/repos/ns-3-dev > +@end verbatim + +Notice that the echo server has now been relocated to the last of the CSMA +nodes, which is 10.1.2.5 instead of the default case, 10.1.2.4. You can +increase the number to your hearts content, but remember that you will get a +pcap trace file for every node in the simulation. One thing you can do to +keep from getting all of those pcap traces with nothing but ARP exchanges in +them is to be more specific about which nodes and devices you want to trace. + +Let's take a look at @code{scratch/second.cc} and be more specific about which +nodes and devices we want to trace. The file we provide uses the +@code{EnablePcapAll} methods of the helpers to enable pcap on all devices. +We want to use the more specific method, @code{EnablePcap}, which takes +a node number and device number as parameters. Go ahead and replace the +@code{EnablePcapAll} calls with the calls below. + +@verbatim + PointToPointHelper::EnablePcap ("second", p2pNodes.Get (0)->GetId (), 0); + CsmaHelper::EnablePcap ("second", csmaNodes.Get (nCsma)->GetId (), 0); +@end verbatim + +We know that we want to create a pcap file with the base name "second" and +we also know that the device of interest in both cases is going to be zero, +so those parameters are not really interesting. In order to get the node +number, you have two choices: first, nodes are numbered in a monotonically +increasing fashion starting from zero in the order in which you created them. +One way to get a node number to pass to the helper is to figure this number +out ``manually.'' If you take a look at the network topology illustration at +the beginning of the file, you can see that the last CSMA node is going to be +node number code{nCsma + 1}. This can become annoyingly difficult in larger +simulations. An alternate way, which we use here, is to realize that the +@code{NodeContainer}s contain pointers to ns-3 @code{Node} Objects. The +@code{Node} Object has a method called @code{GetId} which will return that +node's ID. Let's go take a look at the Doxygen for the @code{Node} and locate +that method, which is further down in the code than we've seen so far. + +Go to the Doxygen documentation for your release (recall that you can find it +on the project web site). You can get to the @code{Node} documentation by +looking through at the ``Classes'' tab in and scrolling down to +@code{ns3::Node} in the list. Select @code{ns3::Node} and you will be taken +to the documentation for the @code{Node} class. If you now scroll down to the +@code{GetId} method and select it, you will be taken to the detailed +documentation for the method. Using the @code{GetId} method can make +determining node numbers much easier in complex topologies. + +Now that we have got some trace filtering in place, it is reasonable to start +increasing the number of CSMA devices in our simulation. If you run the +simulation setting @code{nCsma} to 100, you will see the following: + +@verbatim + ~/repos/ns-3-dev > ./waf --run "scratch/second --nCsma=100" + Entering directory `/home/craigdo/repos/ns-3-dev/build' + Compilation finished successfully + Sent 1024 bytes to 10.1.2.101 + Received 1024 bytes from 10.1.1.1 + Received 1024 bytes from 10.1.2.101 + ~/repos/ns-3-dev > +@end verbatim + +Note that the echo server is now located at 10.1.2.101 which corresponds to +100 ``extra'' CSMA nodes with the echo server on the last one. If you list +the pcap files in the top level directory, + +@verbatim + ~/repos/ns-3-dev > ls *.pcap + second-0-0.pcap second-101-0.pcap + ~/repos/ns-3-dev > +@end verbatim + +you will see that we have, in fact, only created two trace files. The trace +file @code{second-0-0.pcap} is the ``leftmost'' point-to-point device which is +the echo packet source. The file @code{second-101-0.pcap} corresponds to the +rightmost CSMA device which is where the echo server resides. + + + + + From 898ce6b3753860636dfa2e7aa186e9655b56e6f3 Mon Sep 17 00:00:00 2001 From: Craig Dowell Date: Sun, 29 Jun 2008 11:13:27 -0700 Subject: [PATCH 072/495] cleanup tutorial third.cc a bit --- examples/third.cc | 31 ++++++++++++++++++++++++------- 1 file changed, 24 insertions(+), 7 deletions(-) diff --git a/examples/third.cc b/examples/third.cc index 8e79183a2..7f13c2dbb 100644 --- a/examples/third.cc +++ b/examples/third.cc @@ -22,6 +22,17 @@ #include "ns3/wifi-module.h" #include "ns3/mobility-module.h" +// Default Network Topology +// +// Wifi 10.1.3.0 +// AP +// * * * * +// | | | | 10.1.1.0 +// n5 n6 n7 n0 -------------- n1 n2 n3 n4 +// point-to-point | | | | +// ================ +// LAN 10.1.2.0 + using namespace ns3; NS_LOG_COMPONENT_DEFINE ("ThirdScriptExample"); @@ -32,11 +43,11 @@ main (int argc, char *argv[]) LogComponentEnable("UdpEchoClientApplication", LOG_LEVEL_INFO); LogComponentEnable("UdpEchoServerApplication", LOG_LEVEL_INFO); - uint32_t nCsma = 10; - uint32_t nWifi = 10; + uint32_t nCsma = 3; + uint32_t nWifi = 3; CommandLine cmd; - cmd.AddValue ("nCsma", "number of csma devices", nCsma); - cmd.AddValue ("nWifi", "number of wifi devices", nWifi); + cmd.AddValue ("nCsma", "Number of \"extra\" CSMA nodes/devices", nCsma); + cmd.AddValue ("nWifi", "Number of wifi STA devices", nWifi); cmd.Parse (argc,argv); NodeContainer p2pNodes; @@ -124,17 +135,18 @@ main (int argc, char *argv[]) UdpEchoServerHelper echoServer; echoServer.SetPort (9); - ApplicationContainer serverApps = echoServer.Install (csmaNodes.Get (5)); + ApplicationContainer serverApps = echoServer.Install (csmaNodes.Get (nCsma)); serverApps.Start (Seconds (1.0)); serverApps.Stop (Seconds (10.0)); UdpEchoClientHelper echoClient; - echoClient.SetRemote (csmaInterfaces.GetAddress (5), 9); + echoClient.SetRemote (csmaInterfaces.GetAddress (nCsma), 9); echoClient.SetAppAttribute ("MaxPackets", UintegerValue (1)); echoClient.SetAppAttribute ("Interval", TimeValue (Seconds (1.))); echoClient.SetAppAttribute ("PacketSize", UintegerValue (1024)); - ApplicationContainer clientApps = echoClient.Install (wifiStaNodes.Get (3)); + ApplicationContainer clientApps = + echoClient.Install (wifiStaNodes.Get (nWifi - 1)); clientApps.Start (Seconds (2.0)); clientApps.Stop (Seconds (10.0)); @@ -142,6 +154,11 @@ main (int argc, char *argv[]) Simulator::Stop (Seconds (10.0)); + PointToPointHelper::EnablePcap ("third", + wifiStaNodes.Get (nWifi - 1)->GetId (), 0); + CsmaHelper::EnablePcap ("third", + csmaNodes.Get (nCsma)->GetId (), 0); + Simulator::Run (); Simulator::Destroy (); return 0; From d5423b88a2ebb27a38d21e0a18ca0c6c713262bb Mon Sep 17 00:00:00 2001 From: Tom Henderson Date: Sun, 29 Jun 2008 14:20:40 -0700 Subject: [PATCH 073/495] Table of content fixes --- doc/tutorial/conceptual-overview.texi | 4 ++-- doc/tutorial/tutorial.texi | 13 +++++++++---- doc/tutorial/tweaking.texi | 14 +++++++------- 3 files changed, 18 insertions(+), 13 deletions(-) diff --git a/doc/tutorial/conceptual-overview.texi b/doc/tutorial/conceptual-overview.texi index 10130f322..cf88d60ce 100644 --- a/doc/tutorial/conceptual-overview.texi +++ b/doc/tutorial/conceptual-overview.texi @@ -11,7 +11,7 @@ @c ======================================================================== @c Some Conceptual Overview @c ======================================================================== -@node Conceptual Overveiw +@node Conceptual Overview @chapter Conceptual Overview @menu @@ -167,7 +167,7 @@ to compose those distinct operations into an easy to use model. @c A First ns-3 script @c ======================================================================== @node A First ns-3 Script -@chapter A First ns-3 script +@chapter A First ns-3 Script @cindex first script If you downloaded the system as was suggested above, you will have a release of ns-3 in a directory called @code{repos} under your home directory. Change diff --git a/doc/tutorial/tutorial.texi b/doc/tutorial/tutorial.texi index 8869fcab3..72daa948e 100644 --- a/doc/tutorial/tutorial.texi +++ b/doc/tutorial/tutorial.texi @@ -7,10 +7,11 @@ @ifinfo Primary documentation for the @command{ns-3} project is available in -three forms: +four forms: @itemize @bullet @item @uref{http://www.nsnam.org/doxygen/index.html,,ns-3 Doxygen/Manual}: Documentation of the public APIs of the simulator @item Tutorial (this document) +@item @uref{http://www.nsnam.org/docs/manual.html,,Reference Manual}: Reference Manual @item @uref{http://www.nsnam.org/wiki/index.php,, ns-3 wiki} @end itemize @@ -24,10 +25,11 @@ the document should be discussed on the ns-developers@@isi.edu mailing list. This is an @command{ns-3} tutorial. Primary documentation for the @command{ns-3} project is available in -three forms: +four forms: @itemize @bullet @item @uref{http://www.nsnam.org/doxygen/index.html,,ns-3 Doxygen/Manual}: Documentation of the public APIs of the simulator @item Tutorial (this document) +@item @uref{http://www.nsnam.org/docs/manual.html,,Reference Manual}: Reference Manual @item @uref{http://www.nsnam.org/wiki/index.php,, ns-3 wiki} @end itemize @@ -77,9 +79,12 @@ see @uref{http://www.nsnam.org/docs/tutorial.pdf}. @menu * Introduction:: -* Geting Started:: +* Browsing ns-3:: +* Resources:: +* Getting Started:: * Conceptual Overview:: -* Tweaking Ns-3:: +* A First ns-3 Script:: +* Tweaking ns-3:: * Building Topologies:: @end menu diff --git a/doc/tutorial/tweaking.texi b/doc/tutorial/tweaking.texi index 2bfb70505..b10702316 100644 --- a/doc/tutorial/tweaking.texi +++ b/doc/tutorial/tweaking.texi @@ -4,16 +4,16 @@ @c ======================================================================== @c ======================================================================== -@c PART: Tweaking Ns-3 +@c PART: Tweaking ns-3 @c ======================================================================== -@c The below chapters are under the major heading "Tweaking Ns-3" +@c The below chapters are under the major heading "Tweaking ns-3" @c This is similar to the Latex \part command @c @c ======================================================================== -@c Tweaking Ns-3 +@c Tweaking ns-3 @c ======================================================================== -@node Tweaking Ns-3 -@chapter Tweaking Ns-3 +@node Tweaking ns-3 +@chapter Tweaking ns-3 @menu * Using the Logging Module:: @@ -40,7 +40,7 @@ In other systems, warning messages may be output as well as more detailed informational messages. In some cases, logging facilities are used to output debug messages which can quickly turn the output into a blur. -Ns-3 takes the view that all of these verbosity levels are useful and se +ns-3 takes the view that all of these verbosity levels are useful and se provides a selectable, multi-level approach to message logging. Logging can be disabled completely, enabled on a component-by-component basis, enabled globally and has selectable verbosity levels. The ns-3 log module provides @@ -736,7 +736,7 @@ extending the tracing namespace and creating new tracing sources. @cindex tracing @cindex tracing|ASCII @subsection ASCII Tracing -Ns-3 provides an ASCII trace helper that is a wrapper around low-level +ns-3 provides an ASCII trace helper that is a wrapper around low-level tracing system. This helper lets you configure some useful and easily understood packet traces easily. The output of a trace of a simulation run is an ASCII file --- thus the name. For those familiar with @command{ns-2} From 133bf0b651c55ca0db6409fb237a10698a343225 Mon Sep 17 00:00:00 2001 From: Tom Henderson Date: Sun, 29 Jun 2008 14:28:11 -0700 Subject: [PATCH 074/495] nits on Sections 1-4 --- doc/tutorial/getting-started.texi | 6 ++++++ doc/tutorial/introduction.texi | 17 ++++++----------- 2 files changed, 12 insertions(+), 11 deletions(-) diff --git a/doc/tutorial/getting-started.texi b/doc/tutorial/getting-started.texi index 17519e51c..646b7a20e 100644 --- a/doc/tutorial/getting-started.texi +++ b/doc/tutorial/getting-started.texi @@ -17,6 +17,9 @@ @menu * Downloading and Compiling ns-3:: +* Downloading:: +* Building and Testing:: +* Running a Script:: @end menu @c ======================================================================== @@ -40,6 +43,7 @@ We are going to assume that you have Mercurial and Waf installed and running on the target system as described in the Getting Started section of the ns-3 web site: @uref{http://www.nsnam.org/getting_started.html}. +@node Downloading @section Downloading @cindex tarball The ns-3 code is available in Mercurial repositories on the server @@ -107,6 +111,7 @@ look something like the following: You are now ready to build the ns-3 distribution. +@node Building and Testing @section Building and Testing @cindex Waf!build @cindex Waf!configure @@ -249,6 +254,7 @@ If a regression tests fails you will see a FAIL indication along with a pointer to the offending trace file and its associated reference trace file along with a suggestion on how to run diff in order to see what has gone awry. +@node Running a Script @section Running a Script @cindex Waf!run We typically run scripts under the control of Waf. This allows the build diff --git a/doc/tutorial/introduction.texi b/doc/tutorial/introduction.texi index f9233250b..4cdd7c5d5 100644 --- a/doc/tutorial/introduction.texi +++ b/doc/tutorial/introduction.texi @@ -24,14 +24,14 @@ The ns-3 simulator is a discrete-event network simulator targeted primarily for research and educational use. The @uref{http://www.nsnam.org,,ns-3 project}, -started in 2006, is an open-source project. The goal of the project is to -build a new network simulator primarily for research and educational use. +started in 2006, is an open-source project developing ns-3. -Primary documentation for the ns-3 project is available in three forms: +Primary documentation for the ns-3 project is available in four forms: @itemize @bullet @item @uref{http://www.nsnam.org/doxygen/index.html,,ns-3 Doxygen/Manual}: Documentation of the public APIs of the simulator @item Tutorial (this document) +@item @uref{http://www.nsnam.org/docs/manual.html,,Reference Manual}: Reference Manual @item @uref{http://www.nsnam.org/wiki/index.php,, ns-3 wiki} @end itemize @@ -96,7 +96,7 @@ page started with the simulator (please contact @uref{http://www.nsnam.org/people.html,,one of us}) @end itemize -If you are an ns user, please consider providing your feedback, bug fixes, or +If you are an ns-3 user, please consider providing your feedback, bug fixes, or code to the project. @node Tutorial Organization @@ -174,11 +174,6 @@ click on the @code{file} link, you will be sent to the source file for Example scripts are in the @code{examples} directory. The @code{examples} directory is a good place to start browsing the code. -For ns-2 users, who may be familiar with the @code{simple.tcl} example script -in the ns-2 documentation, an analogous script is found in -@code{examples/simple-point-to-point.cc} with a Python equivalent found -in @emph{(pending Python merge)}. - @node Doxygen @section Doxygen @@ -190,7 +185,7 @@ look. @section Other Documentation We provide a large amount of documentation regarding the various components -of ns-2 on our website. See: @uref{http://www.nsnam.org/documents.html}. +of ns-3 on our website. See: @uref{http://www.nsnam.org/documents.html}. @c ======================================================================== @c Resources @@ -284,7 +279,7 @@ only have to understand a tiny and intuitively obvious subset of Python in order to extend the system in most cases. For those interested in the gory details of Waf, the main web site can be -found at @uref{http://freehackers.org/\~tnagy/waf.html}. +found at @uref{http://freehackers.org/~tnagy/waf.html}. @node Environment Idioms Design Patterns @section Environment, Idioms, and Design Patterns From 45f203f09f475bd1d21426907f1c46288eefe4f6 Mon Sep 17 00:00:00 2001 From: Tom Henderson Date: Sun, 29 Jun 2008 14:38:49 -0700 Subject: [PATCH 075/495] formatting nits on the Tweaking chapter --- doc/tutorial/tweaking.texi | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/doc/tutorial/tweaking.texi b/doc/tutorial/tweaking.texi index b10702316..eb2a5f6c8 100644 --- a/doc/tutorial/tweaking.texi +++ b/doc/tutorial/tweaking.texi @@ -32,7 +32,8 @@ We have already taken a brief look at the ns-3 logging module while going over the @code{first.cc} script. We will now take a closer look and see what kind of use-cases the logging subsystem was designed to cover. -@section Logging Overview +@node Logging Overview +@subsection Logging Overview Many large systems support some kind of message logging facility, and ns-3 is not an exception. In some cases, only error messages are logged to the ``operator console'' (which is typically @code{stderr} in Unix-based systems). @@ -83,7 +84,8 @@ Now that you have read the documentation in great detail, we can get some interesting information out of the @code{first.cc} example script you dropped in the scratch directory after the script walkthrough. -@section Enabling Logging Using the NS_LOG Environment Variable +@node Enabling Logging +@subsection Enabling Logging Using the NS_LOG Environment Variable @cindex NS_LOG First, let's use the NS_LOG environment variable to turn on some more logging in the @code{first.cc} script you have already built. Go ahead and run the @@ -323,7 +325,8 @@ transition into a debugger for fine-grained examination of the problem. This output can be especially useful when your script does something completely unexpected. -@section Adding Logging to your Code +@node Adding Logging to your Code +@subsection Adding Logging to your Code @cindex NS_LOG You can add new logging to your simulations by making calls to the log component via several macros. Let's do so in the @code{first.cc} script we @@ -390,7 +393,7 @@ with component name and simulation time. @node Using Command Line Arguments @section Using Command Line Arguments -@section Overriding Default Attributes +@subsection Overriding Default Attributes @cindex arguments|command line Another way you can change the way that ns-3 scripts behave without editing and building scripts is via @emph{command line arguments.} We provide a From 73e368454d3c2603cbd7bdfed31bcb5a7bac23ce Mon Sep 17 00:00:00 2001 From: Craig Dowell Date: Sun, 29 Jun 2008 15:05:22 -0700 Subject: [PATCH 076/495] finish up with a wifi example --- doc/tutorial/building-topologies.texi | 721 +++++++++++++++++++++++++- doc/tutorial/conceptual-overview.texi | 6 +- doc/tutorial/getting-started.texi | 18 +- doc/tutorial/introduction.texi | 5 +- doc/tutorial/tweaking.texi | 16 +- examples/third.cc | 51 +- 6 files changed, 773 insertions(+), 44 deletions(-) diff --git a/doc/tutorial/building-topologies.texi b/doc/tutorial/building-topologies.texi index 81f7dd482..3f2763011 100644 --- a/doc/tutorial/building-topologies.texi +++ b/doc/tutorial/building-topologies.texi @@ -17,6 +17,7 @@ @menu * Building a Bus Network Topology +* Building a Wireless Network Topology @end menu @c ======================================================================== @@ -26,7 +27,7 @@ @section Building a Bus Network Topology @cindex topology -@cindex topology|star +@cindex bus network topology In this section we are going to expand our mastery of ns-3 network devices and channels to cover an example of a bus network. Ns-3 provides a net device and channel we call CSMA (Carrier Sense Multiple Access). @@ -541,3 +542,721 @@ rightmost CSMA device which is where the echo server resides. + + + + + + + + +@menu +* Building a Wireless Network Topology +@end menu + +@c ======================================================================== +@c Building a Wireless Network Topology +@c ======================================================================== +@node Building a Wireless Network Topology +@section Building a Wireless Network Topology + +@cindex topology +@cindex wireless network topology +In this section we are going to further expand our knowledge of ns-3 network +devices and channels to cover an example of a wireless network. Ns-3 provides +a set of 802.11 models that attempt to provide an accurate MAC-level +implementation of the 802.11 specification a ``not-so-slow'' PHY-level model +of the 802.11a specification. + +Just as we have seen both point-to-point and CSMA topology helper objects when +constructing point-to-point topologies, we will see equivalent @code{Wifi} +topology helpers in this section. The appearance and operation of these +helpers should look quite familiar to you. + +We provide an example script in our @code{examples} directory. This script +builds on the @code{second.cc} script and adds a Wifi network. Go ahead and +open @code{examples/third.cc} in your favorite editor. You will have already +seen enough ns-3 code to understand most of what is going on in this example, +but there are a few new things, so we will go over the entire script and +examine some of the output. + +Just as in the @code{second.cc} example (and in all ns-3 examples) the file +begins with an emacs mode line and some GPL boilerplate. + +Lets take a look at the ASCII art that shows the default network topology +constructed in the example. + +In this case, you can see that we are going to further extend our example +by hanging a wireless network off of the left side. Notice that this is the +default network topology since you can actually vary the number of nodes +created on the wired and wireless networks. Just as in the @code{sedond.cc} +case, if you @code{nCsma} will give you a number of ``extra'' CSMA nodes. +Similarly, you can set @code{nWifi} to control how many @code{STA} (station) +nodes are created in the simulation. There will always be one @code{AP} +(access point) node on the wireless network. By default there are +thee ``extra'' CSMA nodes and three wireless @code{STA} nodes as seen below: + +The code begins by loading module include files just as was done in the +@code{second.cc} example. There are a couple of new includes corresponding +to the Wifi module and the mobility module which we will discuss below. + +@verbatim +#include ``ns3/core-module.h'' +#include ``ns3/simulator-module.h'' +#include ``ns3/node-module.h'' +#include ``ns3/helper-module.h'' +#include ``ns3/global-routing-module.h'' +#include ``ns3/wifi-module.h'' +#include ``ns3/mobility-module.h'' +@end verbatim + +The network topology illustration follows: + +@verbatim + // Default Network Topology + // + // Wifi 10.1.3.0 + // AP + // * * * * + // | | | | 10.1.1.0 + // n5 n6 n7 n0 -------------- n1 n2 n3 n4 + // point-to-point | | | | + // ================ + // LAN 10.1.2.0 +@end verbatim + +You can see that we are adding a new network device to the left side of the +point-to-point link that becomes the access point for the wireless network. +A number of wireless STA nodes are created to fill out the new 10.1.3.0 +network as shown on the far left side of the illustration. + +After the illustration, the ns-3 namespace is @code{used} and a logging +component is defined. This should all be quite familiar by now. + +@verbatim + using namespace ns3; + + NS_LOG_COMPONENT_DEFINE ("ThirdScriptExample"); +@end verbatim + +As has become the norm in this tutorial, the main program begins by enabling +the @code{UdpEchoClientApplication} and @code{UdpEchoServerApplication} +logging components at @code{INFO} level so we can see some output when we run +the simulation. + +@verbatim + int + main (int argc, char *argv[]) + { + LogComponentEnable("UdpEchoClientApplication", LOG_LEVEL_INFO); + LogComponentEnable("UdpEchoServerApplication", LOG_LEVEL_INFO); +@end verbatim + +Next, you will see more familiar code that will allow you to change the number +of devices on the CSMA and Wifi networks via command line argument. + +@verbatim + uint32_t nCsma = 3; + uint32_t nWifi = 3; + CommandLine cmd; + cmd.AddValue (``nCsma'', ``Number of \"extra\" CSMA nodes/devices'', nCsma); + cmd.AddValue (``nWifi'', ``Number of wifi STA devices'', nWifi); + cmd.Parse (argc,argv); +@end verbatim + +Just as in all of the previous examples, the next step is to create two nodes +that we will connect via the point-to-point link. + +@verbatim + NodeContainer p2pNodes; + p2pNodes.Create (2); +@end verbatim + +Next, we see an old friend. We instantiate a @code{PointToPointHelper} and +set the associated default attributes so that we create a five megabit per +second transmitter on devices created using the helper and a two millisecond +delay on channels created by the helper. We then @code{Intall} the devices +on the nodes and the channel between them. + +@verbatim + PointToPointHelper pointToPoint; + pointToPoint.SetDeviceParameter ("DataRate", StringValue ("5Mbps")); + pointToPoint.SetChannelParameter ("Delay", StringValue ("2ms")); + + NetDeviceContainer p2pDevices; + p2pDevices = pointToPoint.Install (p2pNodes); +@end verbatim + +Next, we delare another @code{NodeContainer} to hold the nodes that will be +part of the bus (CSMA) network. First we just instantiate the container +object itself. + +@verbatim + NodeContainer csmaNodes; + csmaNodes.Add (p2pNodes.Get (1)); + csmaNodes.Create (nCsma); +@end verbatim + +The next line of code @code{Get}s the first node (as in having an index of one) +from the point-to-point node container and adds it to the container of nodes +that will get CSMA devices. The node in question is going to end up with a +point-to-point device and a CSMA device. We then create a number of ``extra'' +nodes that compose the remainder of the CSMA network. + +We then instantiate a @code{NetDeviceContainer} to keep track of the +point-to-point net devices and we install devices on the point-to-point +nodes. + +The next piece of code creates and connects CSMA devices and channels as we +have previously seen. + +@verbatim + CsmaHelper csma; + + NetDeviceContainer csmaDevices; + csmaDevices = csma.Install (csmaNodes); +@end verbatim + +Next, we are going to create the nodes that will be part of the Wifi network. +We are going to create a number ``station'' nodes as specified by the command +line argument, and we are going to use the ``leftmost'' node of the +point-to-point link as the node for the access point. + +@verbatim + NodeContainer wifiStaNodes; + wifiStaNodes.Create (nWifi); + NodeContainer wifiApNode = p2pNodes.Get (0); +@end verbatim + +The next bit of code is going to be quite different from the helper-based +topology generation we've seen so far, so we're going to take it line-by-line +for a while. The next line of code you will see is: + +@verbatim + Ptr channel = CreateObject (); +@end verbatim + +Now, I'm not going to explain at this stage precisely what this all means, but +hopefully with a very short digression I can give you enough information so +that this makes sense. + +C++ is an object oriented programming language. Ns-3 extends the basic C++ +object model to implement a number of nifty features. We have seen the +@code{Attribute} system which is one of the major extensions we have +implemented. Another extension is to provide for relatively automatic memory +management. Like many systems, ns-3 creates a base class called @code{Object} +that provides our extensions ``for free'' to other classes that inherit from +our @code{class Object}. + +In the code snipped above, the right hand side of the expression is a +call to a templated C++ function called @code{CreateObject}. The +@emph{template parameter} inside the angle brackets basically tells the +compiler what class it is we want to instantiate. Our system returns a +@emph{smart pointer} to the object of the class that was created and assigns +it to the smart pointer called @code{channel} that is declared on the left +hand side of the assignment. + +The ns-3 smart pointer is also template-based. Here you see that we declare +a smart pointer to a @code{WifiChannel} which is the type of object that was +created in the @code{CreateObject} call. The feature of immediate interest +here is that we never delete the underlying C++ object. It is handled +automatically for us. + +The idea to take away from this discussion is that this line of code creates +an ns-3 @code{Object} that will automatically bring you the benefits of the +ns-3 @code{Attribute} system we've seen previously. The resulting smart +pointer works with the @code{Object} to perform memory management automatically +for you. If you are interested in more details about low level ns-3 code and +exactly what it is doing, you are encouraged to explore the ns-3 manual and +our ``how-to'' documents. + +Now, back to the example. The line of code above has created a wireless +@code{Wifi} channel. This channel model requires that we create and attach +other models that describe various behaviors. This provides an accomplished +user with the opportunity to change the way the wireless network behaves +without changing the core code. + +The first opportunity we have to change the behavior of the wireless network is +by providing a propagation delay model. Again, I don't want to devolve this +tutorial into a manual on @code{Wifi}, but this model describes how the EM +signals are going to propagate. We are going to create the simplest model, +the @code{ConstantSpeedPropagationDelayModel} that, by default, has the +signals propagating at a constant speed --- that of the speed of light in a +vacuum. + +Recall that we created the @code{WifiChannel} and assigned it to a smart +pointer. One of the features of a smart pointer is that you can use it +just as you would a ``normal'' C++ pointer. The next line of code will +create a @code{ConstantSpeedPropagationDelayModel} using the +@code{CreateObject} template function and pass the resulting smart pointer +to the model as an unnamed parameter to the +@code{WifiChannel SetPropagationDelayModel} method. + +@verbatim + channel->SetPropagationDelayModel ( + CreateObject ()); +@end verbatim + +The next lines of code use similar low-level ns-3 methods to create and set +a ``propagation loss model'' for the channel. + +@verbatim + Ptr log = + CreateObject (); + + log->SetReferenceModel (CreateObject ()); + + channel->SetPropagationLossModel (log); +@end verbatim + +This snippet tells the channel how it should calculate signal attenuation +of a signal. The details of these calcuations are beyond the scope of a +tutorial. You are encouraged to explore the Doxygen documentation of classes +@code{LogDistancePropagationLossModel} and +@code{FriisPropagationLossModel} if you are interested in the details. You +will find the documentation in the ``Classes'' tab of the Doxygen page. + +Now we will return to more familiar ground. We next create a @code{WifiHelper} +object and set two default atributes taht it will use when creating the actual +devices. + +@verbatim + WifiHelper wifi; + wifi.SetPhy ("ns3::WifiPhy"); + wifi.SetRemoteStationManager ("ns3::ArfWifiManager"); +@end verbatim + +The @code{SetPhy} method tells the helper the type of physical layer class to +instantiate when building @code{Wifi} devices. In this case, it is asking +for physical layer models based on the YANS 802.11a model. Again, details +are avialable in Doxygen. + +The @code{SetRemoteStationManager} method tells the helper the type of +rate control algorithm. Here, it is asking the helper to use the AARF +algorithm --- details are, of course, avialable in Doxygen. + +Just as we could vary attributes describing the physical layer, we can do the +same for the MAC layer. + +@verbatim + Ssid ssid = Ssid ("ns-3-ssid"); + wifi.SetMac ("ns3::NqstaWifiMac", + "Ssid", SsidValue (ssid), + "ActiveProbing", BooleanValue (false)); +@end verbatim + +This code first creates an 802.11 service set identifier (SSID) object that +will be used to set the value of the ``Ssid'' @code{Attribute} of the MAC +layer implementation. The particular kind of MAC layer is specified by +Attribute as being of the "ns3::NqstaWifiMac" type. This means that the MAC +will use a ``non-QoS station'' (nqsta) state machine. Finally, the +``ActiveProbing'' attribute is set to false. This means that probe requests +will not be sent by MACs created by this helper. + +Again, for the next lines of code we are back on familiar ground. This code +will @code{Install} Wifi net devices on the nodes we have created as STA nodes +and will tie them to the @code{WifiChannel} we created manually. + +@verbatim + NetDeviceContainer staDevices; + staDevices = wifi.Install (wifiStaNodes, channel); +@end verbatim + +We have now configured Wifi for all of our STA nodes, and now we need to +configure the AP (access point) node. We begin this process by changing +the default @code{Attributes} to reflect the requirements of the AP. + +@verbatim + wifi.SetMac ("ns3::NqapWifiMac", + "Ssid", SsidValue (ssid), + "BeaconGeneration", BooleanValue (true), + "BeaconInterval", TimeValue (Seconds (2.5))); +@end verbatim + +In this case, the @code{WifiHelper} is going to create MAC layers of the +``ns3::NqapWifiMac'' (Non-Qos Access Point) type. We set the +``BeaconGeneration'' attribute to true and also set an interval between +beacons. + +The next lines create the single AP and connect it to the channel. + +@verbatim + NetDeviceContainer apDevices; + apDevices = wifi.Install (wifiApNode, channel); +@end verbatim + +Now, we are going to add mobility models. We want the STA nodes to be mobile, +wandering around inside a bounding box and we want to make the AP node +stationary. We use a @code{MobilityHelper} to make this easy for us. + +First, we instantiate a @code{MobilityHelper} obejct and set some attributes +controlling the ``position allocator'' functionality. + +@verbatim + MobilityHelper mobility; + + mobility.SetPositionAllocator ("ns3::GridPositionAllocator", + "MinX", DoubleValue (0.0), + "MinY", DoubleValue (0.0), + "DeltaX", DoubleValue (5.0), + "DeltaY", DoubleValue (10.0), + "GridWidth", UintegerValue (3), + "LayoutType", StringValue ("RowFirst")); +@end verbatim + +This code tells the mobility helper to use a two-dimensional grid to initially +place the STA nodes. Feel free to explore the Doxygen for class +@code{ns3::GridPositionAllocator} to see exactly what is being done. + +We have aranged our nodes on an initial grid, but now we need to tell them +how to move. We choose the @code{RandomWalk2dMobilityModel} which has the +nodes move in a random direction at a random speed around the bounding box. + +@verbatim + mobility.SetMobilityModel ("ns3::RandomWalk2dMobilityModel", + "Bounds", RectangleValue (Rectangle (-50, 50, -50, 50))); +@end verbatim + +We now tell the @code{MobilityHelper} to install the mobility models on the +STA nodes. + +@verbatim + mobility.Install (wifiStaNodes); +@end verbatim + +We wanted the access point to remain in a fixed position during the simulation. +We accomplish this by setting the mobility model for this node to be the +@code{ns3::StaticMobilityModel}: + +@verbatim + mobility.SetMobilityModel (``ns3::StaticMobilityModel''); + mobility.Install (wifiApNode); +@end verbatim + +We now have our nodes, devices and channels created, and mobility models +chosen for the Wifi nodes, but we have no protocol stacks present. Just as +previously, we will use the @code{InternetStackHelper} to install these stacks. + +@verbatim + InternetStackHelper stack; + stack.Install (csmaNodes); + stack.Install (wifiApNode); + stack.Install (wifiStaNodes); +@end verbatim + +Just as in the @code{second.cc} example script, we are going to use the +@code{Ipv4AddressHelper} to assign IP addresses to our device interfaces. +First we use the network 10.1.1.0 to create the two addresses needed for our +two point-to-point devices. Then we use network 10.1.2.0 to assign addresses +the the CSMA network and then we assign addresses from network 10.1.3.0 to +both the STA devices and the AP on the wireless network. + +@verbatim + Ipv4AddressHelper address; + + address.SetBase ("10.1.1.0", "255.255.255.0"); + Ipv4InterfaceContainer p2pInterfaces; + p2pInterfaces = address.Assign (p2pDevices); + + address.SetBase ("10.1.2.0", "255.255.255.0"); + Ipv4InterfaceContainer csmaInterfaces; + csmaInterfaces = address.Assign (csmaDevices); + + address.SetBase ("10.1.3.0", "255.255.255.0"); + address.Assign (staDevices); + address.Assign (apDevices); +@end verbatim + +Recall that we save the created interfaces in a container to make it easy to +pull out addressing information later. + +We then need to assign IP addresses to our CSMA device interfaces. The +operation works just as it did for the point-to-point case, except we now +are performing the operation on a container that has a variable number of +CSMA devices --- remember we made that number changeable by command line +argument. So the CSMA devices will be associated with IP addresses from +network number 10.1.2.0 in this case. + +@verbatim + address.SetBase ("10.1.2.0", "255.255.255.0"); + Ipv4InterfaceContainer csmaInterfaces; + csmaInterfaces = address.Assign (csmaDevices); +@end verbatim + +We put the echo server on the ``rightmost'' node in the illustration at the +start of the file: + +@verbatim + UdpEchoServerHelper echoServer; + echoServer.SetPort (9); + + ApplicationContainer serverApps = echoServer.Install (csmaNodes.Get (nCsma)); + serverApps.Start (Seconds (1.0)); + serverApps.Stop (Seconds (10.0)); +@end verbatim + +And we put the echo client on the last STA node we created, pointing it to +the server on the CSMA network. + +@verbatim + UdpEchoClientHelper echoClient; + echoClient.SetRemote (csmaInterfaces.GetAddress (nCsma), 9); + echoClient.SetAppAttribute (``MaxPackets'', UintegerValue (1)); + echoClient.SetAppAttribute (``Interval'', TimeValue (Seconds (1.))); + echoClient.SetAppAttribute (``PacketSize'', UintegerValue (1024)); + + ApplicationContainer clientApps = + echoClient.Install (wifiStaNodes.Get (nWifi - 1)); + clientApps.Start (Seconds (2.0)); + clientApps.Stop (Seconds (10.0)); +@end verbatim + +Since we have built an internetwork here, we need enable internetwork routing. + +@verbatim + GlobalRouteManager::PopulateRoutingTables (); +@end verbatim + +One thing that can surprise some users is the fact that the simulation we just +created will never ``naturally'' stop. This is because we asked the wireless +access point to generate beacons. It will generate beacons forever, so we must +tell the simulator to stop even though it may have beacon generation events +scheduled. The following line of code tells the simulator to stop so that +we don't simulate beacons forever. + +@verbatim + Simulator::Stop (Seconds (10.0)); +@end verbatim + +We use the same trick as in the @code{second.cc} script to only generate +pcap traces from the nodes we find interesting. Note that we use the same +``formula'' to get pcap tracing enabled on Wifi devices: + +@verbatim + WifiHelper::EnablePcap (``third'', + wifiStaNodes.Get (nWifi - 1)->GetId (), 0); + CsmaHelper::EnablePcap (``third'', + csmaNodes.Get (nCsma)->GetId (), 0); +@end verbatim + +Finally, we actually run the simulation call the @code{Simulator::Destroy} +method to clean up and then exit the program. + +@verbatim + Simulator::Run (); + Simulator::Destroy (); + return 0; + } +@end verbatim + +In order to run this example, you have to copy the @code{third.cc} example +script into the scratch directory and use waf to build just as you did with +the @code{second.cc} example. If you are in the top-level directory of the +repository you would type, + +@verbatim + cp examples/third.cc scratch/ + ./waf + ./waf --run scratch/third +@end verbatim + +Since we have set up the UDP echo applications just as we did in the +@code{second.cc} script, you will see similar output. + +@verbatim + ~/repos/ns-3-dev > ./waf --run scratch/third + Entering directory `/home/craigdo/repos/ns-3-dev/build' + Compilation finished successfully + Sent 1024 bytes to 10.1.2.4 + Received 1024 bytes from 10.1.3.3 + Received 1024 bytes from 10.1.2.4 + ~/repos/ns-3-dev > +@end verbatim + +Recall that the first message, @code{Sent 1024 bytes to 10.1.2.4} is the +UDP echo client sending a packet to the server. In this case, the server +is on the wireless network (10.1.3.0). The second message, +@code{Received 1024 bytes from 10.1.3.3}, is from the UDP echo server, +generated when it receives the echo packet. The final message, +@code{Received 1024 bytes from 10.1.2.4} is from the echo client, indicating +that it has received its echo back from the server. + +If you now go and look in the top level directory, you will find two trace +files: + +@verbatim + ~/repos/ns-3-dev > ls *.pcap + third-4-0.pcap third-7-0.pcap + ~/repos/ns-3-dev > +@end verbatim + +The file ``third-4-0.pcap'' corresponds to node four, device zero. This is +the CSMA network node that acted as the echo server. Take a look at the +tcpdump for this device: + +@verbatim + ~/repos/ns-3-dev > tcpdump -r third-4-0.pcap -nn -tt + reading from file third-4-0.pcap, link-type EN10MB (Ethernet) + 2.005855 arp who-has 10.1.2.4 (ff:ff:ff:ff:ff:ff) tell 10.1.2.1 + 2.005855 arp reply 10.1.2.4 is-at 00:00:00:00:00:06 + 2.005859 IP 10.1.3.3.49153 > 10.1.2.4.9: UDP, length 1024 + 2.005859 arp who-has 10.1.2.1 (ff:ff:ff:ff:ff:ff) tell 10.1.2.4 + 2.005861 arp reply 10.1.2.1 is-at 00:00:00:00:00:03 + 2.005861 IP 10.1.2.4.9 > 10.1.3.3.49153: UDP, length 1024 + ~/repos/ns-3-dev > +@end verbatim + +This should be easily understood. If you've forgotten, go back and look at +the discussion in @code{second.cc}. This is the same sequence. + +Now, take a look at the other trace file, ``third-7-0.pcap.'' This is the +trace file for the wireless STA node that acts as the echo client. + +@verbatim + ~/repos/ns-3-dev > tcpdump -r third-7-0.pcap -nn -tt + reading from file third-7-0.pcap, link-type IEEE802_11 (802.11) + 0.000146 Beacon (ns-3-ssid) ... + H: 0 + 0.000180 Assoc Request (ns-3-ssid) ... + 0.000336 Acknowledgment RA:00:00:00:00:00:07 + 0.000454 Assoc Response AID(0) :: Succesful + 0.000514 Acknowledgment RA:00:00:00:00:00:0a + 0.000746 Assoc Request (ns-3-ssid) ... + 0.000902 Acknowledgment RA:00:00:00:00:00:09 + 0.001020 Assoc Response AID(0) :: Succesful + 0.001036 Acknowledgment RA:00:00:00:00:00:0a + 0.001219 Assoc Request (ns-3-ssid) ... + 0.001279 Acknowledgment RA:00:00:00:00:00:08 + 0.001478 Assoc Response AID(0) :: Succesful + 0.001538 Acknowledgment RA:00:00:00:00:00:0a + 2.000000 arp who-has 10.1.3.4 (ff:ff:ff:ff:ff:ff) tell 10.1.3.3 + 2.000172 Acknowledgment RA:00:00:00:00:00:09 + 2.000318 arp who-has 10.1.3.4 (ff:ff:ff:ff:ff:ff) tell 10.1.3.3 + 2.000581 arp reply 10.1.3.4 is-at 00:00:00:00:00:0a + 2.000597 Acknowledgment RA:00:00:00:00:00:0a + 2.000693 IP 10.1.3.3.49153 > 10.1.2.4.9: UDP, length 1024 + 2.002229 Acknowledgment RA:00:00:00:00:00:09 + 2.009663 arp who-has 10.1.3.3 (ff:ff:ff:ff:ff:ff) tell 10.1.3.4 + 2.009697 arp reply 10.1.3.3 is-at 00:00:00:00:00:09 + 2.009869 Acknowledgment RA:00:00:00:00:00:09 + 2.011487 IP 10.1.2.4.9 > 10.1.3.3.49153: UDP, length 1024 + 2.011503 Acknowledgment RA:00:00:00:00:00:0a + 2.500112 Beacon[|802.11] + 5.000112 Beacon[|802.11] + 7.500112 Beacon[|802.11] + ~/repos/ns-3-dev > +@end verbatim + +You can see that the link type is now 802.11 as you would expect. We leave +it as an exercise to parse the dump and trace packets across the internetwork. + +Now, we spent a lot of time setting up mobility models for the wireless network +and so it would be a shame to finish up without even showing that the STA +nodes are actually moving. Let's do this by hooking into the +@code{MobilityModel} course change trace source. This is usually considered +a fairly advanced topic, but let's just go for it. + +As mentioned in the Tweaking Ns-3 section, the ns-3 tracing system is divided +into trace sources and trace sinks, and we provide functions to connect the +two. We will use the mobility model predefined course change trace source +to originate the trace events. We will need to write a trace sink to connect +to that source that will display some pretty information for us. It's really +quite simple. Just before the main program of the @code{scratch/third.cc} +script, add the following function: + +@verbatim + void + CourseChange (std::string context, Ptr model) + { + Vector position = model->GetPosition (); + NS_LOG_UNCOND (context << + " x = " << position.x << ", y = " << position.y); + } +@end verbatim + +This code just unconditionally logs the x and y position of the node. We are +going to arrange for this function to be called every time the wireless +node with the echo client changes its position. We do this using the +@code{Config::Connect} function. Add the following lines of code to the +script just before the @code{Simulator::Run} call. + +@verbatim + std::ostringstream oss; + oss << + ``/NodeList/'' << wifiStaNodes.Get (nWifi - 1)->GetId () << + ``/$ns3::MobilityModel/CourseChange''; + + Config::Connect (oss.str (), MakeCallback (&CourseChange)); +@end verbatim + +What we do here is to create a string containing the tracing namespace path +to the event we want to connect. In the case of the default number of CSMA +and wireless nodes, this turns out to be, + +@verbatim + /NodeList/7/$ns3::MobilityModel/CourseChange +@end verbatim + +From the discussion in the tracing section, you may recall that references the +seventh node in the NodeList and looks for what is called an aggregated object +of type @code{ns3::MobilityModel}. Then we hook into the ``CourseChange'' +event of that model. We actually connect the trace source in node seven with +our trace sink --- the function we just added called @code{CourseChange} --- +by calling @code{Config::Connect}. Once this is done, every course change +event on node seven will be hooked into our trace sink, which will print out +the new position. + +If you now run the simulation, you will see the course changes displayed as +they happen. + +@verbatim + ~/repos/ns-3-dev > ./waf --run scratch/third + Entering directory `/home/craigdo/repos/ns-3-dev/build' + Compilation finished successfully + /NodeList/7/$ns3::MobilityModel/CourseChange x = 10, y = 0 + /NodeList/7/$ns3::MobilityModel/CourseChange x = 9.1304, y = 0.493761 + /NodeList/7/$ns3::MobilityModel/CourseChange x = 8.70417, y = 1.39837 + /NodeList/7/$ns3::MobilityModel/CourseChange x = 7.94799, y = 2.05274 + /NodeList/7/$ns3::MobilityModel/CourseChange x = 8.82597, y = 1.57404 + /NodeList/7/$ns3::MobilityModel/CourseChange x = 8.3003, y = 0.723347 + Sent 1024 bytes to 10.1.2.4 + Received 1024 bytes from 10.1.3.3 + Received 1024 bytes from 10.1.2.4 + /NodeList/7/$ns3::MobilityModel/CourseChange x = 8.74083, y = 1.62109 + /NodeList/7/$ns3::MobilityModel/CourseChange x = 9.00146, y = 0.655647 + /NodeList/7/$ns3::MobilityModel/CourseChange x = 9.98731, y = 0.823279 + /NodeList/7/$ns3::MobilityModel/CourseChange x = 9.50206, y = 1.69766 + /NodeList/7/$ns3::MobilityModel/CourseChange x = 8.68108, y = 2.26862 + /NodeList/7/$ns3::MobilityModel/CourseChange x = 9.25992, y = 1.45317 + /NodeList/7/$ns3::MobilityModel/CourseChange x = 8.55655, y = 0.742346 + /NodeList/7/$ns3::MobilityModel/CourseChange x = 8.21992, y = 1.68398 + /NodeList/7/$ns3::MobilityModel/CourseChange x = 8.81273, y = 0.878638 + /NodeList/7/$ns3::MobilityModel/CourseChange x = 7.83171, y = 1.07256 + /NodeList/7/$ns3::MobilityModel/CourseChange x = 7.60027, y = 0.0997156 + /NodeList/7/$ns3::MobilityModel/CourseChange x = 8.45367, y = 0.620978 + /NodeList/7/$ns3::MobilityModel/CourseChange x = 7.68484, y = 1.26043 + /NodeList/7/$ns3::MobilityModel/CourseChange x = 8.53659, y = 0.736479 + /NodeList/7/$ns3::MobilityModel/CourseChange x = 9.51876, y = 0.548502 + /NodeList/7/$ns3::MobilityModel/CourseChange x = 9.89778, y = 1.47389 + /NodeList/7/$ns3::MobilityModel/CourseChange x = 8.98984, y = 1.893 + /NodeList/7/$ns3::MobilityModel/CourseChange x = 9.91524, y = 1.51402 + /NodeList/7/$ns3::MobilityModel/CourseChange x = 8.98761, y = 1.14054 + /NodeList/7/$ns3::MobilityModel/CourseChange x = 8.16617, y = 0.570239 + /NodeList/7/$ns3::MobilityModel/CourseChange x = 8.02954, y = 1.56086 + /NodeList/7/$ns3::MobilityModel/CourseChange x = 8.09551, y = 2.55868 + ~/repos/ns-3-dev > +@end verbatim + +If you are feeling brave, there is a list of all trace sources in the ns-3 +Doxygen which you can find in the ``NS-3 Modules'' section. Under the +``core'' section, you will find a link to ``The list of all trace sources.'' +You will find a list of all of the trace sources that you can hook to. You +may find it interesting to try and hook some of these traces yourself. +Additionally in the ``NS-3 Modules'' documentation, there is a link to +``The list of all attributes.'' You can set the default value of any of these +atributes via the command line as we have previously discussed. + +We have just scratched the surface of ns-3 in this tutorial, but we hope we +have covered enough to get you started doing useful work. + +-- The ns-3 development team. diff --git a/doc/tutorial/conceptual-overview.texi b/doc/tutorial/conceptual-overview.texi index 10130f322..9c600b9b7 100644 --- a/doc/tutorial/conceptual-overview.texi +++ b/doc/tutorial/conceptual-overview.texi @@ -39,7 +39,7 @@ intentionally do not use the term host since it is closely associated with the Internet and its protocols. Instead, we use a more generic term also used by other simulators that originates in Graph Theory --- the @emph{node}. -@cindex Node!class +@cindex class Node In ns-3 the basic computing device abstraction is called the node. This abstraction is represented in C++ by the class @code{Node}. The @code{Node} class provides methods for managing the representations of @@ -74,7 +74,7 @@ idea of an application. Just as software applications run on computers to perform tasks in the ``real world,'' ns-3 applications run on ns-3 @code{Node}s to drive simulations in the simulated world. -@cindex Application!class +@cindex class Application In ns-3 the basic abstraction for a user program that generates some activity to be simulated is the application. This abstraction is represented in C++ by the class @code{Application}. The @code{Application} class provides @@ -145,7 +145,7 @@ Just as an Ethernet NIC is designed to work with an Ethernet network, the @subsection Topology Helpers @cindex helper @cindex topology -@cindex helper|topology +@cindex topology helper In a real network, you will find host computers with added (or built-in) NICs. In ns-3 we would say that you will find @code{Nodes} with attached @code{NetDevices}. In a large simulated network you will need to diff --git a/doc/tutorial/getting-started.texi b/doc/tutorial/getting-started.texi index 17519e51c..2a49b4fd1 100644 --- a/doc/tutorial/getting-started.texi +++ b/doc/tutorial/getting-started.texi @@ -108,12 +108,12 @@ look something like the following: You are now ready to build the ns-3 distribution. @section Building and Testing -@cindex Waf!build -@cindex Waf!configure -@cindex Waf!debug -@cindex Waf!compile -@cindex Waf!check -@cindex Waf!regression +@cindex building with Waf +@cindex configuring Waf +@cindex building debug version with Waf +@cindex compiling with Waf +@cindex unit tests with Waf +@cindex regression tests with Waf We use Waf to build the ns-3 project. The first thing you will need to do is to configure the build. For reasons that will become clear later, we are going to work with debug builds in the tutorial. To explain to Waf that it @@ -170,7 +170,7 @@ most important is the last one, Compilation finished successfully @end verbatim -@cindex tests|unit +@cindex unit tests You can run the unit tests of the ns-3 distribution by running the ``check'' command, @@ -197,7 +197,7 @@ test has passed. ~/repos/ns-3-dev > @end verbatim -@cindex tests|regression +@cindex regression tests This command is typically run by @code{users} to quickly verify that an ns-3 distribution has built correctly. @@ -250,7 +250,7 @@ pointer to the offending trace file and its associated reference trace file along with a suggestion on how to run diff in order to see what has gone awry. @section Running a Script -@cindex Waf!run +@cindex running a script with Waf We typically run scripts under the control of Waf. This allows the build system to ensure that the shared library paths are set correctly and that the libraries are available at run time. To run a program, simply use the diff --git a/doc/tutorial/introduction.texi b/doc/tutorial/introduction.texi index f9233250b..27578a2a0 100644 --- a/doc/tutorial/introduction.texi +++ b/doc/tutorial/introduction.texi @@ -230,8 +230,9 @@ You will find user and developer FAQs there as well as troubleshooting guides, third-party contributed code, papers, etc. The source code may be found and browsed at @uref{http://code.nsnam.org/}. -@cindex repository!ns-3-dev -@cindex repository!releases +@cindex mercurial repository +@cindex ns-3-dev repository +@cindex release repository There you will find the current development tree in the repository named @code{ns-3-dev}. Past releases and experimental repositories of the core developers may also be found there. diff --git a/doc/tutorial/tweaking.texi b/doc/tutorial/tweaking.texi index 2bfb70505..b2768e1a2 100644 --- a/doc/tutorial/tweaking.texi +++ b/doc/tutorial/tweaking.texi @@ -391,7 +391,7 @@ with component name and simulation time. @section Using Command Line Arguments @section Overriding Default Attributes -@cindex arguments|command line +@cindex command line arguments Another way you can change the way that ns-3 scripts behave without editing and building scripts is via @emph{command line arguments.} We provide a mechanism to parse command line arguments and automatically set local and @@ -734,7 +734,7 @@ or how-to sections for information on advanced tracing configuration including extending the tracing namespace and creating new tracing sources. @cindex tracing -@cindex tracing|ASCII +@cindex ASCII tracing @subsection ASCII Tracing Ns-3 provides an ASCII trace helper that is a wrapper around low-level tracing system. This helper lets you configure some useful and easily @@ -743,7 +743,7 @@ is an ASCII file --- thus the name. For those familiar with @command{ns-2} output, this type of trace is analogous to the @command{out.tr} generated by many scripts. -@cindex tracing|packets +@cindex tracing packets Let's just jump right in and add some ASCII tracing output to our @code{first.cc} script. The first thing you need to do is to add the following code to the script just before the call to @code{Simulator::Run ()}. @@ -801,10 +801,10 @@ every packet destined for a channel must pass --- it is the device lone character (has a space after it). This character will have the following meaning: -@cindex ascii trace|enqueue -@cindex ascii trace|dequeue -@cindex ascii trace|drop -@cindex ascii trace|receive +@cindex ascii trace enqueue operation +@cindex ascii trace dequeue operation +@cindex ascii trace drop operation +@cindex ascii trace receive operation @itemize @bullet @item @code{+}: An enqueue operation occurred on the device queue; @item @code{-}: A dequeue operation occurred on the device queue; @@ -913,7 +913,7 @@ However, there are many traffic trace analyzers that use this packet format. We encourage users to exploit the many tools available for analyzing pcap traces. In this tutorial, we show how tcpdump and Wireshark can be used. -@cindex tracing|pcap +@cindex pcap tracing The code used to enable pcap tracing is a one-liner. @verbatim diff --git a/examples/third.cc b/examples/third.cc index 7f13c2dbb..7660d45a1 100644 --- a/examples/third.cc +++ b/examples/third.cc @@ -73,44 +73,52 @@ main (int argc, char *argv[]) wifiStaNodes.Create (nWifi); NodeContainer wifiApNode = p2pNodes.Get (0); - // setup the wifi channel: this is a log distance propagation model - // with a friis model as reference model for the log distance model. Ptr channel = CreateObject (); - channel->SetPropagationDelayModel (CreateObject ()); - Ptr log = CreateObject (); + + channel->SetPropagationDelayModel ( + CreateObject ()); + + Ptr log = + CreateObject (); + log->SetReferenceModel (CreateObject ()); + channel->SetPropagationLossModel (log); - Ssid ssid = Ssid ("ns-3-ssid"); WifiHelper wifi; wifi.SetPhy ("ns3::WifiPhy"); wifi.SetRemoteStationManager ("ns3::ArfWifiManager"); - // setup stas. + + Ssid ssid = Ssid ("ns-3-ssid"); wifi.SetMac ("ns3::NqstaWifiMac", - "Ssid", SsidValue (ssid), - "ActiveProbing", BooleanValue (false)); + "Ssid", SsidValue (ssid), + "ActiveProbing", BooleanValue (false)); + NetDeviceContainer staDevices; staDevices = wifi.Install (wifiStaNodes, channel); - // setup ap. - wifi.SetMac ("ns3::NqapWifiMac", "Ssid", SsidValue (ssid), - "BeaconGeneration", BooleanValue (true), - "BeaconInterval", TimeValue (Seconds (2.5))); + + wifi.SetMac ("ns3::NqapWifiMac", + "Ssid", SsidValue (ssid), + "BeaconGeneration", BooleanValue (true), + "BeaconInterval", TimeValue (Seconds (2.5))); + NetDeviceContainer apDevices; apDevices = wifi.Install (wifiApNode, channel); MobilityHelper mobility; - // layout the initial position of the nodes. + mobility.SetPositionAllocator ("ns3::GridPositionAllocator", - "MinX", DoubleValue (0.0), - "MinY", DoubleValue (0.0), - "DeltaX", DoubleValue (5.0), - "DeltaY", DoubleValue (10.0), - "GridWidth", UintegerValue (3), - "LayoutType", StringValue ("RowFirst")); + "MinX", DoubleValue (0.0), + "MinY", DoubleValue (0.0), + "DeltaX", DoubleValue (5.0), + "DeltaY", DoubleValue (10.0), + "GridWidth", UintegerValue (3), + "LayoutType", StringValue ("RowFirst")); mobility.SetMobilityModel ("ns3::RandomWalk2dMobilityModel", - "Bounds", RectangleValue (Rectangle (-50, 50, -50, 50))); + "Bounds", RectangleValue (Rectangle (-50, 50, -50, 50))); mobility.Install (wifiStaNodes); + mobility.SetMobilityModel ("ns3::StaticMobilityModel"); mobility.Install (wifiApNode); @@ -120,6 +128,7 @@ main (int argc, char *argv[]) stack.Install (wifiStaNodes); Ipv4AddressHelper address; + address.SetBase ("10.1.1.0", "255.255.255.0"); Ipv4InterfaceContainer p2pInterfaces; p2pInterfaces = address.Assign (p2pDevices); @@ -154,7 +163,7 @@ main (int argc, char *argv[]) Simulator::Stop (Seconds (10.0)); - PointToPointHelper::EnablePcap ("third", + WifiHelper::EnablePcap ("third", wifiStaNodes.Get (nWifi - 1)->GetId (), 0); CsmaHelper::EnablePcap ("third", csmaNodes.Get (nCsma)->GetId (), 0); From c094200ef6c6fedda3729d47b22df7138f78f764 Mon Sep 17 00:00:00 2001 From: Tom Henderson Date: Sun, 29 Jun 2008 20:48:18 -0700 Subject: [PATCH 077/495] a few section 8 nits --- doc/tutorial/building-topologies.texi | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/doc/tutorial/building-topologies.texi b/doc/tutorial/building-topologies.texi index 3f2763011..666e6dde5 100644 --- a/doc/tutorial/building-topologies.texi +++ b/doc/tutorial/building-topologies.texi @@ -16,8 +16,8 @@ @chapter Building Topologies @menu -* Building a Bus Network Topology -* Building a Wireless Network Topology +* Building a Bus Network Topology:: +* Building a Wireless Network Topology:: @end menu @c ======================================================================== @@ -565,8 +565,8 @@ rightmost CSMA device which is where the echo server resides. In this section we are going to further expand our knowledge of ns-3 network devices and channels to cover an example of a wireless network. Ns-3 provides a set of 802.11 models that attempt to provide an accurate MAC-level -implementation of the 802.11 specification a ``not-so-slow'' PHY-level model -of the 802.11a specification. +implementation of the 802.11 specification and a ``not-so-slow'' +PHY-level model of the 802.11a specification. Just as we have seen both point-to-point and CSMA topology helper objects when constructing point-to-point topologies, we will see equivalent @code{Wifi} @@ -748,7 +748,7 @@ management. Like many systems, ns-3 creates a base class called @code{Object} that provides our extensions ``for free'' to other classes that inherit from our @code{class Object}. -In the code snipped above, the right hand side of the expression is a +In the code snippet above, the right hand side of the expression is a call to a templated C++ function called @code{CreateObject}. The @emph{template parameter} inside the angle brackets basically tells the compiler what class it is we want to instantiate. Our system returns a From bdb123bbc45ccef587cc30cfee51abaa6599f91d Mon Sep 17 00:00:00 2001 From: Craig Dowell Date: Sun, 29 Jun 2008 21:16:35 -0700 Subject: [PATCH 078/495] editing pass through the tutorial --- doc/tutorial/conceptual-overview.texi | 517 +++++++++++--------------- doc/tutorial/getting-started.texi | 117 +++--- doc/tutorial/introduction.texi | 125 ++++--- doc/tutorial/tutorial.texi | 16 +- 4 files changed, 364 insertions(+), 411 deletions(-) diff --git a/doc/tutorial/conceptual-overview.texi b/doc/tutorial/conceptual-overview.texi index 9c600b9b7..1ae49814b 100644 --- a/doc/tutorial/conceptual-overview.texi +++ b/doc/tutorial/conceptual-overview.texi @@ -4,56 +4,47 @@ @c ======================================================================== @c ======================================================================== -@c PART: Conceptual Overview -@c ======================================================================== -@c The below chapters are under the major heading "Getting Started" -@c This is similar to the Latex \part command -@c ======================================================================== -@c Some Conceptual Overview +@c Conceptual Overview @c ======================================================================== @node Conceptual Overveiw @chapter Conceptual Overview @menu * Key Abstractions:: +* A First ns-3 script @end menu The first thing we need to do before actually starting to look at or write -ns-3 code is to explain a few core concepts, abstractions and idioms in the +@command{ns-3} code is to explain a few core concepts and abstractions in the system. Much of this may appear transparently obvious to some, but we -recommend taking the time to read through this chapter just to ensure you +recommend taking the time to read through this section just to ensure you are starting on a firm foundation. @node Key Abstractions @section Key Abstractions In this section, we'll review some terms that are commonly used in -networking, but have a specific meaning in ns-3. +networking, but have a specific meaning in @command{ns-3}. @subsection Node @cindex Node In Internet jargon, a computing device that connects to a network is called -a @emph{host} or sometimes an @emph{end system}. Because ns-3 is a +a @emph{host} or sometimes an @emph{end system}. Because @command{ns-3} is a @emph{network} simulator, not specifically an @emph{Internet} simulator, we intentionally do not use the term host since it is closely associated with the Internet and its protocols. Instead, we use a more generic term also used by other simulators that originates in Graph Theory --- the @emph{node}. @cindex class Node -In ns-3 the basic computing device abstraction is called the +In @command{ns-3} the basic computing device abstraction is called the node. This abstraction is represented in C++ by the class @code{Node}. The @code{Node} class provides methods for managing the representations of -computing devices in simulations. Developers are expected to specialize the -@code{Node} in the object-oriented programming sense to create new computing -device models. In this tutorial, we will use a specialization of class -@code{Node} called @code{InternetNode}. As you might expect, the -@code{InternetNode} is a class that represents a host in the Internet sense, -and automatically provides core IPv4 networking protocols. +computing devices in simulations. You should think of a @code{Node} as a computer to which you will add functionality. One adds things like applications, protocol stacks and peripheral cards with their associated drivers to enable the computer to do -useful work. We use the same basic model in ns-3. +useful work. We use the same basic model in @command{ns-3}. @subsection Application @cindex Application @@ -68,23 +59,24 @@ goal. @cindex system call Often, the line of separation between system and application software is made at the privilege level change that happens in operating system traps. -In ns-3 there is no real concept of operating system and especially +In @command{ns-3} there is no real concept of operating system and especially no concept of privilege levels or system calls. We do, however, have the idea of an application. Just as software applications run on computers to -perform tasks in the ``real world,'' ns-3 applications run on -ns-3 @code{Node}s to drive simulations in the simulated world. +perform tasks in the ``real world,'' @command{ns-3} applications run on +@command{ns-3} @code{Node}s to drive simulations in the simulated world. @cindex class Application -In ns-3 the basic abstraction for a user program that generates some +In @command{ns-3} the basic abstraction for a user program that generates some activity to be simulated is the application. This abstraction is represented in C++ by the class @code{Application}. The @code{Application} class provides methods for managing the representations of our version of user-level applications in simulations. Developers are expected to specialize the -@code{Application} in the object-oriented programming sense to create new +@code{Application} class in the object-oriented programming sense to create new applications. In this tutorial, we will use specializations of class -@code{Application} called @code{UdpEchoClient} and @code{UdpEchoServer}. -As you might expect, these applications compose a client/server application set -used to generate and echo simulated network packets +@code{Application} called @code{UdpEchoClientApplication} and +@code{UdpEchoServerApplication}. As you might expect, these applications +compose a client/server application set used to generate and echo simulated +network packets @subsection Channel @cindex Channel @@ -93,7 +85,7 @@ In the real world, one can connect a computer to a network. Often the media over which data flows in these netowrks are called @emph{channels}. When you connect your Ethernet cable to the plug in the wall, you are connecting your computer to an Ethernet communication channel. In the simulated world -of ns-3 one connects a @code{Node} to an object representing a +of @command{ns-3} one connects a @code{Node} to an object representing a communication channel. Here the basic communication subnetwork abstraction is called the channel and is represented in C++ by the class @code{Channel}. @@ -105,10 +97,10 @@ specialization may model something as simple as a wire. The specialized switch, or three-dimensional space in the case of wireless networks. We will use specialized versions of the @code{Channel} called -@code{CsmaChannel} and @code{PointToPointChannel} in this tutorial. The -@code{CsmaChannel}, for example, models a version of a communication subnetwork -that implements a @emph{carrier sense multiple access} communication medium. -This gives us Ethernet-like functionality. +@code{CsmaChannel}, @code{PointToPointChannel} and @code{WifiChannel} in this +tutorial. The @code{CsmaChannel}, for example, models a version of a +communication subnetwork that implements a @emph{carrier sense multiple +access} communication medium. This gives us Ethernet-like functionality. @subsection Net Device @cindex NetDevice @@ -127,8 +119,8 @@ devices (NICs) are controlled using @emph{network device drivers} collectively known as @emph{net devices}. In Unix and Linux you refer to these net devices by names such as @emph{eth0}. -In ns-3 the @emph{net device} abstraction covers both the software -driver and the simulated hardware. A net device is ``attached'' to a +In @command{ns-3} the @emph{net device} abstraction covers both the software +driver and the simulated hardware. A net device is ``installed'' in a @code{Node} in order to enable the @code{Node} to communicate with other @code{Node}s in the simulation via @code{Channel}s. Just as in a real computer, a @code{Node} may be connected to more than one @code{Channel} via @@ -137,55 +129,60 @@ multiple @code{NetDevice}s. The net device abstraction is represented in C++ by the class @code{NetDevice}. The @code{NetDevice} class provides methods for managing connections to @code{Node} and @code{Channel} objects; and may be specialized by developers -in the object-oriented programming sense. We will use the specialized version -of the @code{NetDevice} called the @code{CsmaNetDevice} in this tutorial. +in the object-oriented programming sense. We will use the several specialized +versions of the @code{NetDevice} called @code{CsmaNetDevice}, +@code{PointToPointNetDevice}, and @code{WifiNetDevice} in this tutorial. Just as an Ethernet NIC is designed to work with an Ethernet network, the -@code{CsmaNetDevice} is designed to work with a @code{CsmaChannel}. +@code{CsmaNetDevice} is designed to work with a @code{CsmaChannel}; the +@code{PointToPointNetDevice} is designed to work with a +@code{PointToPointChannel} and a @code{WifiNetNevice} is designed to work with +a @code{WifiChannel}. @subsection Topology Helpers @cindex helper @cindex topology @cindex topology helper In a real network, you will find host computers with added (or built-in) -NICs. In ns-3 we would say that you will find @code{Nodes} with +NICs. In @command{ns-3} we would say that you will find @code{Nodes} with attached @code{NetDevices}. In a large simulated network you will need to arrange many connections between @code{Node}s, @code{NetDevice}s and @code{Channel}s. Since connecting @code{NetDevice}s to @code{Node}s, @code{NetDevice}s to @code{Channel}s, assigning IP addresses, etc., are such common tasks -in ns-3 we provide what we call @emph{topology helpers} to make this as easy -as possible. For example, will take several distinct ns-3 core operations -to create a NetDevice, add a MAC address, connect the net device to a -@code{Node}, configure the protocol stack, and then connect the -@code{NetDevice} to a @code{Channel}. More higher level operations would be -required to connect multiple devices onto multipoint channels and then to +in @command{ns-3}, we provide what we call @emph{topology helpers} to make +this as easy as possible. For example, will take several distinct +@command{ns-3} core operations to create a NetDevice, add a MAC address, +connect the net device to a @code{Node}, configure the protocol stack, and +then connect the @code{NetDevice} to a @code{Channel}. More operations would +be required to connect multiple devices onto multipoint channels and then to connect networks together into internetworks. We use topology helper objects -to compose those distinct operations into an easy to use model. +to combine those many distinct operations into an easy to use model. @c ======================================================================== @c A First ns-3 script @c ======================================================================== @node A First ns-3 Script -@chapter A First ns-3 script +@section A First ns-3 script @cindex first script If you downloaded the system as was suggested above, you will have a release -of ns-3 in a directory called @code{repos} under your home directory. Change -into that release directory, and you should find a directory structure -something like the following: +of @command{ns-3} in a directory called @code{repos} under your home +directory. Change into that release directory, and you should find a +directory structure something like the following: @verbatim - AUTHORS examples/ README samples/ tutorial/ waf* - build/ LICENSE regression/ scratch/ utils/ waf.bat* - doc/ ns3/ RELEASE_NOTES src/ VERSION wscript + AUTHORS examples/ README samples/ utils/ waf.bat* + build/ LICENSE regression/ scratch/ VERSION wscript + doc/ ns3/ RELEASE_NOTES src/ waf* @end verbatim @cindex first.cc Change into the examples directory. You should see a file named @code{first.cc} located there. This is a script that will create a simple point-to-point link between two nodes and echo a single packet between the -nodes. Let's take a look at the script line by line. +nodes. Let's take a look at that script line by line. +@subsection Boilerplate The first line in the file is an emacs mode line. This tells emacs about the formatting conventions (coding style) we use in our source code. @@ -194,16 +191,21 @@ formatting conventions (coding style) we use in our source code. @end verbatim This is always a somewhat controversial subject, so we might as well get it -out of the way immediately. The ns-3 project, like most large projects, has -adopted a coding style to which all contributed code must adhere. If you want -to contribute your code to the project, you will eventually have to conform to -the ns-3 coding style as described in INSERT LINK TO CODING STYLE PAGE ON WEB. +out of the way immediately. The @code{ns-3} project, like most large +projects, has adopted a coding style to which all contributed code must +adhere. If you want to contribute your code to the project, you will +eventually have to conform to the @command{ns-3} coding standard as described +in the file @code{doc/codingstd.txt}. We recommend that you, well, just get +used to the look and feel of @code{ns-3} code and adopt this standard whenever +you are working with our code. All of the development team have done so. The emacs mode line above makes it easier to get the formatting correct if you use the emacs editor. -The ns-3 simulator is licentsed using the GNU General Public License. You -will see the appropriate GNU legalese at the head of every file in the ns-3 -distribution. +The @command{ns-3} simulator is licentsed using the GNU General Public +License. You will see the appropriate GNU legalese at the head of every file +in the @command{ns-3} distribution. Often you will see a copyright notice for +one of the institutions involved in the @code{ns-3} project and an author +listed. @verbatim /* @@ -222,7 +224,7 @@ distribution. */ @end verbatim -@section Module Includes +@subsection Module Includes The code proper starts with a number of include statements. To help our high level users deal with the large number of include files present in the system, we group includes according to relatively large modules. We provide a single @@ -230,9 +232,9 @@ include file that, in turn, includes all of the include files used in each module. Rather than having to look up exactly what header you need, and possibly have to get dependencies right, we give you the ability to load a group of files at a large granularity. This is not the most efficient approach -but it certainly makes writing scripts much easier. Each of the ns-3 files -is placed in a directory called @code{ns3} to help with include file name -collisions. +but it certainly makes writing scripts much easier. Each of the +@command{ns-3} files is placed in a directory called @code{ns3} (under the +build directory) to help avoid include file name collisions. @verbatim #include "ns3/core-module.h" @@ -248,39 +250,43 @@ you do a build, Waf will place public header files in an @code{ns3} directory under the appropriate @code{build/debug} or @code{build/optimized} directory depending on your configuration. Waf will also automatically generate a module include file to load all of the public header files. Since you are following -this tutorial perfectly, you will have done a +this tutorial religiously, you will already have done a @verbatim ./waf -d debug configure @end verbatim -to configure the project to perform debug builds. You will also have done a, +to configure the project to perform debug builds. You will also have done a @verbatim ./waf @end verbatim -to build the project. So if you look in the directory @code{build/debug/ns-3} -you will find the four module includes shown above. +to build the project. So now if you look in the directory +@code{build/debug/ns-3} you will find the four module include files shown +above. You can take a look at the contents to find that these files will +include all of the public includes in the respective modules. -@section Ns3 Namespace -The next line in the @code{first.cc} script is a namespace statement: +@subsection Ns3 Namespace +The next line in the @code{first.cc} script is a namespace declaration. @verbatim using namespace ns3; @end verbatim -The ns-3 project is implemented in a C++ namespace called @code{ns3}. This -groups all ns-3-related declarations in a scope outside the global namespace -which we hope will help with integration with other code. The C++ @code{using} -statement introduces the ns-3 namespace into the current (global) declarative -region. This is a fancy way of saying that after this declaration, you will -not have to type @code{ns3::} before all of the ns-3 code in order to use it. -If you are unfamiliar with namespaces, please consult almost any C++ tutorial -and compare the ns3 namespace and usage here with the std namespace and -a @code{using namespace std;} statement. +The @command{ns-3} project is implemented in a C++ namespace called +@code{ns3}. This groups all @command{ns-3}-related declarations in a scope +outside the global namespace, which we hope will help with integration with +other code. The C++ @code{using} statement introduces the @code{ns-3} +namespace into the current (global) declarative region. This is a fancy way +of saying that after this declaration, you will not have to type @code{ns3::} +scope resolution operator before all of the @code{ns-3} code in order to use +it. If you are unfamiliar with namespaces, please consult almost any C++ +tutorial and compare the @code{ns3} namespace and usage here with instances of +the @code{std} namespace and the @code{using namespace std;} statements you +will often find in discussions of @code{cout} and streams. -@section Logging +@subsection Logging The next line of the script is the following, @verbatim @@ -298,11 +304,12 @@ that version. Along the left side, you will find a graphical representation of the structure of the documentation. A good place to start is the @code{NS-3 Modules} -``book.'' If you expand @code{Modules} you will see a list of ns-3 module -documentation. The concept of module here ties directly into the module -include files discussed above. It turns out that the ns-3 logging subsystem -is part of the @code{core} module, so go ahead and expand that node. Now, -open the @code{Debugging} book and then select the @code{Logging} page. +``book.'' If you expand @code{Modules} you will see a list of @command{ns-3} +module documentation. The concept of module here ties directly into the +module include files discussed above. It turns out that the @command{ns-3} +logging subsystem is part of the @code{core} module, so go ahead and expand +that documentation node. Now, open the @code{Debugging} book and then select +the @code{Logging} page. You should now be looking at the Doxygen documentation for the Logging module. In the list of @code{#define}s you will see @code{NS_LOG_COMPONENT_DEFINE}. @@ -313,6 +320,7 @@ the documentation here, but to summarize, this line declares a logging component called @code{FirstScriptExample} that allows you to enable and disable console message logging by reference to the name. +@subsection Main Function The next lines of the script you will find are: @verbatim @@ -323,8 +331,8 @@ The next lines of the script you will find are: This is just the declaration of the main function of your program. Just as in any C++ program, you need to define a main function that will be the first -function run. There is nothing at all special here. Your ns-3 script is just -a C++ program. +function run. There is nothing at all special here. Your @command{ns-3} +script is just a C++ program. The next two lines of the script are used to enable two logging components that are built into the Echo Client and Echo Server applications: @@ -335,64 +343,66 @@ are built into the Echo Client and Echo Server applications: @end verbatim If you have read over the Logging component documentation you will see that -there are a number of levels of detail that you enable on each component. +there are a number of levels of detail that you can enable on each component. These two lines of code enable debug logging at the INFO level for echo clients and servers. This will result in the application printing out -a message as packets are sent and received. +messages as packets are sent and received. Now we will get directly to the business of creating a topology and running a simulation. We will use the topology helper objects to make this job as easy as possible. -@section Topology Helpers -@subsection NodeContainer -The next two lines of code in our script will actually create the ns-3 objects -that will represent the computers in the simulation. +@subsection Topology Helpers +@subsubsection NodeContainer +The next two lines of code in our script will actually create the +@command{ns-3} @code{Node} objects that will represent the computers in the +simulation. @verbatim NodeContainer nodes; nodes.Create (2); @end verbatim -Let's find the documentation for the first object before we continue. Another -way to get into the documentation system is via the @code{Classes} tab in the -HTML pages. If you still have the Doxygen handy, just scroll up to the top -of the page and select the @code{Classes} tab. You should see a new set of -tabs appear, one of which is @code{Class List}. Under that tab you will see -a list of all of the ns-3 classes. Scroll down, looking for -@code{ns3::NodeContainer}. When you find the class, go ahead and select it to -go to the Doxygen. +Let's find the documentation for the @code{NodeContainer} class before we +continue. Another way to get into the documentation for a given class is via +the @code{Classes} tab in the Doxygen pages. If you still have the Doxygen +handy, just scroll up to the top of the page and select the @code{Classes} +tab. You should see a new set of tabs appear, one of which is +@code{Class List}. Under that tab you will see a list of all of the +@command{ns-3} classes. Scroll down, looking for @code{ns3::NodeContainer}. +When you find the class, go ahead and select it to go to the documentation for +the class. You may recall that one of our key abstractions is the @code{Node}. This represents a computer to which we are going to add things like protocol stacks, applications and peripheral cards. The @code{NodeContainer} topology helper provides a convenient way to create, manage and access any @code{Node} objects -that we create in order to run a simulation. The first line just declares a -NodeContainer which we call @code{nodes}. The second line calls the -@code{Create} method on the @code{nodes} object and asks the container to +that we create in order to run a simulation. The first line above just +declares a NodeContainer which we call @code{nodes}. The second line calls the +@code{Create} method on the @code{nodes} object that asks the container to create two nodes. As described in the Doxygen, the container calls down into -the ns-3 system to create two @code{Node} objects and stores the pointers -internally. +the @command{ns-3} system proper to create two @code{Node} objects and stores +pointers to those objects internally. -The nodes as they stand at this point in the script do nothing. The next step -in constructing a topology is to connect our nodes together into a network. -The simplest form of network is a single point-to-point link between two nodes -so we'll construct one here. +The nodes as they stand in the script do nothing. The next step in +constructing a topology is to connect our nodes together into a network. +The simplest form of network we support is a single point-to-point link +between two nodes. We'll construct one of those links here. -@subsection PointToPointHelper -We are constructing a point to point link, and in a pattern which will become +@subsubsection PointToPointHelper +We are constructing a point to point link, and, in a pattern which will become quite familiar to you, we use a topology helper object to do the low-level work required to put the link together. Recall that two of our key abstractions are the @code{NetDevice} and the @code{Channel}. In the real -world, this corresponds roughly to peripheral cards and network cables. +world, these terms correspond roughly to peripheral cards and network cables. Typically these two things are intimately tied together and one cannot expect -to interchange Ethernet devices and wireless channels, for example. Our +to interchange, for example, Ethernet devices and wireless channels. Our Topology Helpers follow this intimate coupling and therefore you will use a -single @code{PointToPointHelper} to configure and connect ns-3 +single @code{PointToPointHelper} to configure and connect @command{ns-3} @code{PointToPointNetDevice} and @code{PointToPointChannel} objects in this script. -The next three lines in the @code{first.cc} script are +The next three lines in the script are, @verbatim PointToPointHelper pointToPoint; @@ -406,9 +416,8 @@ The first line PointToPointHelper pointToPoint; @end verbatim -creates a @code{PointToPointHelper} object on the stack. - -From a high-level perspective the next line, +creates a @code{PointToPointHelper} object on the stack. From a high-level +perspective the next line, @verbatim pointToPoint.SetDeviceParameter ("DataRate", StringValue ("5Mbps")); @@ -423,23 +432,23 @@ to what we call an @code{Attribute} of the @code{PointToPointNetDevice}. If you look at the Doxygen for class @code{ns3::PointToPointNetDevice} and find the documentation for the @code{GetTypeId} method, you will find a list of @code{Attributes} defined for the device. Among these is the ``DataRate'' -attribute. Most user-visible ns-3 objects have similar lists of attributes. -We use this mechanism to easily configure simulations without recompiling -as you will see in a following section. +attribute. Most user-visible @command{ns-3} objects have similar lists of +attributes. We use this mechanism to easily configure simulations without +recompiling as you will see in a following section. Similar to the ``DataRate'' on the @code{PointToPointNetDevice} we find a -``Delay'' attribute associated with the @code{PointToPointChannel}. THe +``Delay'' attribute associated with the @code{PointToPointChannel}. The final line, @verbatim pointToPoint.SetChannelParameter ("Delay", StringValue ("2ms")); @end verbatim -Tells the @code{PointToPointHelper} to use the value ``2ms'' (two milliseconds) +tells the @code{PointToPointHelper} to use the value ``2ms'' (two milliseconds) as the value of the transmission delay of every point to point channel it creates. -@subsection NetDeviceContainer +@subsubsection NetDeviceContainer At this point in the script, we have a @code{NodeContainer} that contains two nodes. We have a @code{PointToPointHelper} that is primed and ready to make @code{PointToPointNetDevices} and wire @code{PoiintToPointChannel} objects @@ -464,18 +473,18 @@ is created. For each node in the @code{NodeContainer} (there must be exactly two for a point-to-point link) a @code{PointToPointNetDevice} is created and saved in the device container. A @code{PointToPointChannel} is created and the two @code{PointToPointNetDevices} are attached. When objects are created -by the @code{PointToPointHelper} the attributes previously set in the helper +by the @code{PointToPointHelper}, the attributes previously set in the helper are used to initialize the corresponding attributes in the created objects. After executing the the @code{pointToPoint.Install (nodes)} call we will have two nodes, each with an installed point-to-point net device and a -point-to-point channel between them. Both devices will send data at five -megabits per second over the channel which has a two millisecond transmission -delay. +point-to-point channel between them. Both devices will be configured to +transmit data at five megabits per second over the channel which has a two +millisecond transmission delay. -@subsection InternetStackHelper -We have nodes and devices configured, but we don't have any protocol stacks -installed on our nodes. The next two lines of code take care of that. +@subsubsection InternetStackHelper +We now have nodes and devices configured, but we don't have any protocol stacks +installed on our nodes. The next two lines of code will take care of that. @verbatim InternetStackHelper stack; @@ -488,12 +497,12 @@ what the @code{PointToPointHelper} is to point-to-point net devices. The executed, it will install an Internet Stack (TCP, UDP, IP, etc.) on each of the nodes in the node container. -@subsection Ipv4AddressHelper +@subsubsection Ipv4AddressHelper Next we need to associate the devices on our nodes with IP addresses. We provide a topology helper to manage the allocation of IP addresses. The only user-visible API is to set the base IP address and network mask to use when -performing the actual address allocation (which is done at a lower level in the -code). +performing the actual address allocation (which is done at a lower level +inside the helper). The next two lines of code in our example script, @code{first.cc}, @@ -504,7 +513,12 @@ The next two lines of code in our example script, @code{first.cc}, declare an address helper object and tell it that it should begin allocating IP addresses from the network 10.1.1.0 using the mask 255.255.255.0 to define -the allocatable bits. +the allocatable bits. By default the addresses allocated will start at one +and increase monotonically, so the first address allocated from this base will +be 10.1.1.1, followed by 10.1.1.2, etc. The low level @command{ns-3} system +actually remembers all of the IP addresses allocated and will generate a +fatal error if you accidentally cause the same address to be generated twice +(which is a very hard to find error, by the way). The next line of code, @@ -512,25 +526,26 @@ The next line of code, Ipv4InterfaceContainer interfaces = address.Assign (devices); @end verbatim -performs the actual address assignment. In ns-3 we make the association -between an IP address and a device using an @code{Ipv4Interface} object. -Just as we sometimes need a list of net devices created by a helper for future -reference we sometimes need a list of @code{Ipv4Interface} objects. The -@code{Ipv4InterfaceContainer} provides this functionality. +performs the actual address assignment. In @command{ns-3} we make the +association between an IP address and a device using an @code{Ipv4Interface} +object. Just as we sometimes need a list of net devices created by a helper +for future reference we sometimes need a list of @code{Ipv4Interface} objects. +The @code{Ipv4InterfaceContainer} provides this functionality. -Now we have a point-to-point network made with IP addresses assigned. What -we need at this point are applications to generate traffic. +Now we have a point-to-point network built, with stacks installed and IP +addresses assigned. What we need at this point are applications to generate +traffic. -@section Applications +@subsection Applications Another one of the core abstractions of the ns-3 system is the @code{Application}. In this script we use two specializations of the core -ns-3 class @code{Application} called @code{UdpEchoServerApplication} and -@code{UdpEchoClientApplication}. Just as in the previous instances of ns-3 -objects, we use helper objects to help configure and manage the underlying -objects. Here, we use @code{UdpEchoServerHelper} and +@command{ns-3} class @code{Application} called @code{UdpEchoServerApplication} +and @code{UdpEchoClientApplication}. Just as we have in our previous +explanations, we use helper objects to help configure and manage the +underlying objects. Here, we use @code{UdpEchoServerHelper} and @code{UdpEchoClientHelper} objects to make our lives easier. -@subsection UdpEchoServerHelper +@subsubsection UdpEchoServerHelper The following lines of code in our example script, @code{first.cc}, are used to set up a UDP echo server application on one of the nodes we have previously created and connected using a point-to-point link. @@ -546,7 +561,7 @@ created and connected using a point-to-point link. The first line of code in the above snippet declares the @code{UdpEchoServerHelper}. As usual, this isn't the application itself, it -is an object to help us create the actual applications. The second line +is an object used to help us create the actual applications. The second line that has the @code{SetPort} call, is used to tell the helper to assign the value nine to the ``Port'' attribute when creating @code{UdpEchoServerApplication} objects. @@ -557,103 +572,21 @@ causes the underlying echo server application to be instantiated and attached to a node. Interestingly, the @code{Install} method takes a @code{NodeContainter} as a parameter just as the other @code{Install} methods we have seen. This is actually what is passed to the method even though it -doesn't look so in this case. It will be worth a slight digression -to undersand what is going on here. +doesn't look so in this case. There is a C++ @emph{implicit conversion} at +work here. -@subsubsection Implicit Conversions -This is an example of a C++ @code{implicit conversion} at work. Many -programmers use implicit conversions without even realizing it since they are -sometimes so intuitive. For example, in the following code, - -@verbatim - int i = 1; - double d = 2.; - if (n == d) ... -@end verbatim - -@cindex standard conversion -the integer (1) is implicitly converted to a double (1.) before the comparison -takes place. This conversion is performed using what is known as a C++ -@emph{standard conversion}. - -C++ will try to determine a sequence of type conversions to use in order to -convert an argument in a function call to the type of a corresponding paramter -in a method declaration. The method call in this case is, - -@verbatim - ApplicationContainer serverApps = echoServer.Install (nodes.Get (1)); -@end verbatim - -If you look at the declaration of the Install method in the source (or the -Doxygen) you will see, - -@verbatim - ApplicationContainer - UdpEchoServerHelper::Install (NodeContainer c) - { - ... - } -@end verbatim - -Now, the @code{Get} method of the @code{NodeContainer} returns a smart pointer -to a node object: - -@verbatim - Ptr - NodeContainer::Get (uint32_t i) const - { - ... - } -@end verbatim - -C++ notices that it needs to convert a type @code{Ptr} into a type -@code{NodeContainer}. It turns out that @code{NodeContainer} has a -constructor that takes a @code{Ptr} as a parameter. - -@verbatim - NodeContainer::NodeContainer (Ptr node) - { - ... - } -@end verbatim - -The C++ compiler implicitly provides the @code{Ptr} returned from the -@code{NodeContainer::Get} to the above constructor for @code{NodeContainer} to -make a new @code{NodeContainer} to pass to the @code{Install} method of the -@code{UdpEchoServerHelper} object. - -Taking advantage of these implicit conversion sequences can allow you to -avoid doing a lot of typing. The result is also fairly intuitive if you -don't pay close attention to the called method signatures. If you are -one of those folks that pays close attention, it does have the downside of -sometimes being surprising when you, for example, look for the method -in @code{UdpEchoServerHelper} named @code{Install} that takes a parameter -@code{Ptr} and cannot find it. - -@subsection UdpEchoServerHelper Continued -Returning to the example script, we are looking at the following code snippet. - -@verbatim - UdpEchoServerHelper echoServer; - echoServer.SetPort (9); - - ApplicationContainer serverApps = echoServer.Install (nodes.Get (1)); - serverApps.Start (Seconds (1.0)); - serverApps.Stop (Seconds (10.0)); -@end verbatim - -We now see that @code{echoServer.Install} is going to install an +We now see that @code{echoServer.Install} is going to install a @code{UdpEchoServerApplication} on the node found at index number one of the -@code{NodeContainer} we use to manage our nodes. @code{Install} will return +@code{NodeContainer} we used to manage our nodes. @code{Install} will return a container that has all of the applications (one in this case since we passed a @code{NodeContainer} containing one node) made by the helper. Applications require a time to ``start'' generating traffic and a time to ``stop.'' These times are set using @code{ApplicationContainer} methods @code{Start} and @code{Stop}. These methods take @code{Time} parameters. -In this case, we use an explicit conversion sequence to take a c++ double -1.0 and convert it to a @code{Time} object using a @code{Seconds ()} cast. -The two lines, +In this case, we use an explicit conversion sequence to take the C++ double +1.0 and convert it to an @command{ns-3} @code{Time} object using a +@code{Seconds ()} cast. The two lines, @verbatim serverApps.Start (Seconds (1.0)); @@ -666,11 +599,11 @@ into the simulation. By virtue of the fact that we have implicilty declared a simulation event at ten seconds, the simulation will last at least ten seconds. -@subsection UdpEchoClientHelper +@subsubsection UdpEchoClientHelper -The echo client application is set up in a method similar to the server. -There is an underlying @code{UdpEchoClientApplication} that is managed by an -@code{UdpEchoClientHelper}. +The echo client application is set up in a substantially method similar to the +server. There is an underlying @code{UdpEchoClientApplication} that is +managed by an @code{UdpEchoClientHelper}. @verbatim UdpEchoClientHelper echoClient; @@ -684,32 +617,27 @@ There is an underlying @code{UdpEchoClientApplication} that is managed by an clientApps.Stop (Seconds (10.0)); @end verbatim -For the echo client, we need to set four different attributes. The first -attribute is set using the @code{SetRemote} method. Here we refer back to -the @code{Ipv4InterfaceContainer} we created to keep track of the IP addresses -we assigned to our devices. - -@verbatim - Ipv4InterfaceContainer interfaces = address.Assign (devices); -@end verbatim - -In this case, the zeroth interface in the @code{interfaces} container -cooresponds to the IP address of the zeroth node in the @code{nodes} container. -The first interface in the @code{interfaces} container cooresponds to the IP -address of the first node in the @code{nodes} container. So, in the following -line of code, we are setting the remote address of the client to be the IP -address assigned to the node on which the server resides. We tell it to send -to port nine. +For the echo client, however, we need to set four different attributes. The +first attribute is set using the @code{SetRemote} method. Recall that +we used an @code{Ipv4InterfaceContainer} to keep track of the IP addresses we +assigned to our devices. As a result of the allocation, the zeroth interface +in the @code{interfaces} container cooresponds to the IP address of the +zeroth node in the @code{nodes} container. The first interface in the +@code{interfaces} container cooresponds to the IP address of the first node in +the @code{nodes} container. So, in the following line of code (reproduced +from above), we are setting the remote address of the client to be the IP +address assigned to the node on which the server resides, and we tell it to +send packets to port nine. @verbatim echoClient.SetRemote (interfaces.GetAddress (1), 9); @end verbatim The ``MaxPackets'' attribute tells the client the maximum number of packets -it can send. The ``Interval'' attribute tells the cleint how long to wait -between packets and the ``PacketSize'' attribute tells the client how large -its packets should be. In this case we are telling the client to send one -1024-byte packet. +it can send. The ``Interval'' attribute tells the client how long to wait +between packets, and the ``PacketSize'' attribute tells the client how large +its packets should be. With this combination of attributes, we are telling +the client to send one 1024-byte packet. Just as in the case of the echo server, we tell the echo client to @code{Start} and @code{Stop}, but here we start the client one second after the server is @@ -717,14 +645,13 @@ enabled (at two seconds into the simulation). @subsection Simulator What we need to do at this point is to actually run the simulation. This is -done using the @code{Simulator} singleton which is accessed via the global -function @code{Simulator::Run} +done using the global function @code{Simulator::Run}. @verbatim Simulator::Run (); @end verbatim -When we called the methods, +When we previously called the methods, @verbatim serverApps.Start (Seconds (1.0)); @@ -735,32 +662,34 @@ When we called the methods, @end verbatim we actually scheduled events in the simulator at 1.0 seconds, 2.0 seconds and -10.0 seconds. When @code{Simulator::Run} is called, it will begin looking -through the list of scheduled events and executing them. First it will run -the event at 1.0 seconds, which will enable the echo server application. Then -it will run the event scheduled for t=2.0 seconds which will start the echo -client application. The start event implementation in the echo cleint will -begin the data transfer phase of the simulation by sending a packet to the -server. +10.0 seconds. When @code{Simulator::Run} is called, the ssytem will begin +looking through the list of scheduled events and executing them. First it +will run the event at 1.0 seconds, which will enable the echo server +application. Then it will run the event scheduled for t=2.0 seconds which +will start the echo client application. The start event implementation in +the echo client will begin the data transfer phase of the simulation by +sending a packet to the server. The act of sending the packet to the server will trigger a chain of events -which will be automatically scheduled and which will perform the packet echo -according to the various timing parameters that we have set in the script. +which will be automatically scheduled and which will perform the mechanics of +the packet echo according to the various timing parameters that we have set +in the script. -Eventually, since we only sent one packet, the chain of events triggered by -the single client echo request will taper off and the simulation will go -idle. Once this happens, the remaining events are the @code{Stop} events +Eventually, since we only send one packet, the chain of events triggered by +that single client echo request will taper off and the simulation will go +idle. Once this happens, the remaining events will be the @code{Stop} events for the server and the client. When these events are executed, there are no further events to process and @code{Simulator::Run} returns. The simulation is complete. -All that remains is to clean up after ourselves. This is done by calling the -global function @code{Simulator::Destroy}. As the helper functions (or low -level ns-3 code) executed they arranged it so that hooks were inserted in the -simulator to destruct all of the objects that were created. You do not have -to keep track of all of these objects yourself --- all you have to do is to -call @code{Simulator::Destroy} and exit. The remaining lines of our first -ns-3 script, @code{first.cc}, do just that +All that remains is to clean up. This is done by calling the global function +@code{Simulator::Destroy}. As the helper functions (or low level +@command{ns-3} code) executed, they arranged it so that hooks were inserted in +the simulator to destroy all of the objects that were created. You did not +have to keep track of any of these objects yourself --- all you had to do +was to call @code{Simulator::Destroy} and exit. The @command{ns-3} system +took care of the hard part for you. The remaining lines of our first +@command{ns-3} script, @code{first.cc}, do just that: @verbatim Simulator::Destroy (); @@ -768,12 +697,14 @@ ns-3 script, @code{first.cc}, do just that } @end verbatim -@section Building Your Script +@subsection Building Your Script We have made it trivial to build your simple scripts. All you have to do is -to drop your script into the scratch directory and it will automatically be built. Let's try it. Copy @code{examples/first.cc} into @code{scratch}: +to drop your script into the scratch directory and it will automatically be +built if you run Waf. Let's try it. Copy @code{examples/first.cc} into +the @code{scratch} directory. @verbatim - ~/repos/ns-3-tutorial > cp examples/first.cc scratch + ~/repos/ns-3-tutorial > cp examples/first.cc scratch/ @end verbatim and then build it using waf, @@ -782,8 +713,7 @@ and then build it using waf, ~/repos/ns-3-tutorial > ./waf Entering directory `/home/craigdo/repos/ns-3-tutorial/build' [432/477] cxx: scratch/first.cc -> build/debug/scratch/first_2.o - [433/477] cxx: scratch/simple.cc -> build/debug/scratch/simple_3.o - [475/477] cxx_link: build/debug/scratch/first_2.o -> build/debug/scratch/first + [475/477] cxx_link: build/debug/scratch/first_2.o ... Compilation finished successfully ~/repos/ns-3-tutorial > @end verbatim @@ -803,7 +733,8 @@ directory you must run it out of the scratch direcory): Here you see that the build system checks to make sure that the file has been build and then runs it. You see the logging component on the echo client -note that it has sent one 1024 byte packet to the Echo Server on 10.1.1.2. -You also see the logging component on the echo server receive the 1024 bytes -from 10.1.1.1. The echo server silently echoes the packet and you see the -echo client note that it has received its packet back from the server. +indicate that it has sent one 1024 byte packet to the Echo Server on +10.1.1.2. You also see the logging component on the echo server say that +it has received the 1024 bytes from 10.1.1.1. The echo server silently +echoes the packet and you see the echo client log that it has received its +packet back from the server. diff --git a/doc/tutorial/getting-started.texi b/doc/tutorial/getting-started.texi index 2a49b4fd1..9921aeefb 100644 --- a/doc/tutorial/getting-started.texi +++ b/doc/tutorial/getting-started.texi @@ -16,15 +16,18 @@ @chapter Getting Started @menu -* Downloading and Compiling ns-3:: +* Downloading ns-3:: +* Building ns-3:: +* Testing ns-3:: +* Running a Script:: @end menu @c ======================================================================== -@c Downloading and Compiling ns-3 +@c Downloading ns-3 @c ======================================================================== -@node Downloading and Compiling ns-3 -@section Downloading and Compiling ns-3 +@node Downloading ns-3 +@section Downloading ns-3 @cindex Linux @cindex Cygwin @@ -38,29 +41,29 @@ toolchain installed and verified. @cindex Waf We are going to assume that you have Mercurial and Waf installed and running on the target system as described in the Getting Started section of the -ns-3 web site: @uref{http://www.nsnam.org/getting_started.html}. +@command{ns-3} web site: @uref{http://www.nsnam.org/getting_started.html}. -@section Downloading @cindex tarball -The ns-3 code is available in Mercurial repositories on the server +The @command{ns-3} code is available in Mercurial repositories on the server code.nsnam.org. You can download a tarball, but we recommend working with Mercurial --- it will make your life easier in the long run. @cindex repository If you go to the following link: @uref{http://code.nsnam.org/}, you will see a number of repositories. Many are the private repositories of -the ns-3 development team. The repositories of interest to you will be -prefixed with ``ns-3''. The current development snapshot (unreleased) -of ns-3 may be found at: @uref{http://code.nsnam.org/ns-3-dev/}. Official -releases of ns-3 will be numbered as @code{ns-3.} with any requred -hotfixes added as minor release numbers. For example, a second hotfix to a -hypothetical release nine of ns-3 would be numbered @code{ns-3.9.2}. +the @comamnd{ns-3} development team. The repositories of interest to you will +be prefixed with ``ns-3''. The current development snapshot (unreleased) +of @command{ns-3} may be found at: @uref{http://code.nsnam.org/ns-3-dev/}. +Official releases of @command{ns-3} will be numbered as @code{ns-3.} +with any requred hotfixes added as minor release numbers. For example, a +second hotfix to a hypothetical release nine of @command{ns-3} would be +numbered @code{ns-3.9.2}. -The current development snapshot (unreleased) of ns-3 may be found at: -@uref{http://code.nsnam.org/ns-3-dev/}. The developers attempt to keep this -repository in a consistent, working state but it is a development area with -unreleased code present, so you may want to consider staying with an official -release. +The current development snapshot (unreleased) of @command{ns-3} may be found +at: @uref{http://code.nsnam.org/ns-3-dev/}. The developers attempt to keep +this repository in a consistent, working state but it is a development area +with unreleased code present, so you may want to consider staying with an +official release. Since the release numbers are going to be changing, I will stick with the more constant ns-3-dev here in the tutorial, but you can replace the @@ -72,14 +75,14 @@ for the latest release identifier. One practice is to create a directory called @code{repos} in one's home directory under which one can keep local Mercurial repositories. @emph{Hint: we will assume you do this later in the tutorial.} If you adopt -that approach, you can get a copy of any of the development versions of ns-3 -by typing the following into your Linux shell (assuming you have installed -Mercurial): +that approach, you can get a copy of any of the development versions of +@command{ns-3} by typing the following into your Linux shell (assuming you +have installed Mercurial): @verbatim cd mkdir repos - cd !$ + cd repos hg clone http://code.nanam.org/ns-3-dev @end verbatim @@ -100,32 +103,38 @@ ns-3-dev under your @code{~/repos} directory, the contents of which should look something like the following: @verbatim - AUTHORS LICENSE regression/ scratch/ utils/ waf.bat* - doc/ ns3/ RELEASE_NOTES src/ VERSION wscript - examples/ README samples/ tutorial/ waf* + AUTHORS examples/ README samples/ utils/ waf.bat* + build/ LICENSE regression/ scratch/ VERSION wscript + doc/ ns3/ RELEASE_NOTES src/ waf* @end verbatim -You are now ready to build the ns-3 distribution. +You are now ready to build the @command{ns-3} distribution. + +@c ======================================================================== +@c Building ns-3 +@c ======================================================================== + +@node Building ns-3 +@section Building ns-3 -@section Building and Testing @cindex building with Waf @cindex configuring Waf @cindex building debug version with Waf @cindex compiling with Waf @cindex unit tests with Waf @cindex regression tests with Waf -We use Waf to build the ns-3 project. The first thing you will need to do is -to configure the build. For reasons that will become clear later, we are -going to work with debug builds in the tutorial. To explain to Waf that it -should do debug builds you will need to execute the following command, +We use Waf to build the @command{ns-3} project. The first thing you will need +to do is to configure the build. For reasons that will become clear later, +we are going to work with debug builds in the tutorial. To explain to Waf +that it should do debug builds you will need to execute the following command, @verbatim ./waf -d debug configure @end verbatim -This runs the copy of Waf in the local directory (which is provided as a -convenience for you). As the build system checks for various dependencies -you should see output that looks similar to the following, +This runs Waf out of the local directory (which is provided as a convenience +for you). As the build system checks for various dependencies you should see +output that looks similar to the following, @verbatim ~/repos/ns-3-dev >./waf -d debug configure @@ -157,7 +166,7 @@ you should see output that looks similar to the following, @end verbatim The build system is now configured and you can build the debug versions of -the ns-3 programs by simply typing, +the @command{ns-3} programs by simply typing, @verbatim ./waf check @@ -170,8 +179,15 @@ most important is the last one, Compilation finished successfully @end verbatim +@c ======================================================================== +@c Testing ns-3 +@c ======================================================================== + +@node Testing ns-3 +@section Testing ns-3 + @cindex unit tests -You can run the unit tests of the ns-3 distribution by running the ``check'' +You can run the unit tests of the @command{ns-3} distribution by running the ``check'' command, @verbatim @@ -198,8 +214,8 @@ test has passed. @end verbatim @cindex regression tests -This command is typically run by @code{users} to quickly verify that an ns-3 -distribution has built correctly. +This command is typically run by @code{users} to quickly verify that an +@command{ns-3} distribution has built correctly. You can also run @code{regression tests} to ensure that your distribution and tool chain have produced binaries that generate trace files which are @@ -210,14 +226,15 @@ regression tests you run Waf with the regression flag. ./waf --regression @end verbatim -Waf will verify that the current files in the ns-3 distribution are built and -will then look for trace files in the aforementioned centralized location. If -your tool chain includes Mercurial, the regression tests will be downloaded -from a repository at @code{code.nsnam.org}. If you do not have Mercurial -installed, the reference traces will be downloaded from a tarball located in -the @code{releases} section of @code{www.nsnam.org}. The particular name of -the reference trace location is built from the ns-3 version located in the -VERSION file, so don't change that string. +Waf will verify that the current files in the @command{ns-3} distribution are +built and will then look for trace files in the aforementioned centralized +location. If your tool chain includes Mercurial, the regression tests will +be downloaded from a repository at @code{code.nsnam.org}. If you do not have +Mercurial installed, the reference traces will be downloaded from a tarball +located in the @code{releases} section of @code{www.nsnam.org}. The +particular name of the reference trace location is built from the +@command{ns-3} version located in the VERSION file, so don't change that +string yourself unless you know what you are doing. Once the reference traces are downloaded to your local machine, Waf will run a number of tests that generate trace files. The content of these trace @@ -249,13 +266,17 @@ If a regression tests fails you will see a FAIL indication along with a pointer to the offending trace file and its associated reference trace file along with a suggestion on how to run diff in order to see what has gone awry. +@c ======================================================================== +@c Testing ns-3 +@c ======================================================================== + @section Running a Script @cindex running a script with Waf We typically run scripts under the control of Waf. This allows the build system to ensure that the shared library paths are set correctly and that the libraries are available at run time. To run a program, simply use the -@code{run} option in Waf. Let's run the ns-3 equivalent of the hello -world program by typing the following: +@code{run} option in Waf. Let's run the @command{ns-3} equivalent of the +ubiquitous hello world program by typing the following: @verbatim ./waf --run hello-simulator diff --git a/doc/tutorial/introduction.texi b/doc/tutorial/introduction.texi index 27578a2a0..9fa03c447 100644 --- a/doc/tutorial/introduction.texi +++ b/doc/tutorial/introduction.texi @@ -21,13 +21,14 @@ * Tutorial Organization:: @end menu -The ns-3 simulator is a discrete-event network simulator targeted primarily -for research and educational use. The +The @command{ns-3} simulator is a discrete-event network simulator targeted +primarily for research and educational use. The @uref{http://www.nsnam.org,,ns-3 project}, started in 2006, is an open-source project. The goal of the project is to build a new network simulator primarily for research and educational use. -Primary documentation for the ns-3 project is available in three forms: +Primary documentation for the @command{ns-3} project is available in three +forms: @itemize @bullet @item @uref{http://www.nsnam.org/doxygen/index.html,,ns-3 Doxygen/Manual}: Documentation of the public APIs of the simulator @@ -35,7 +36,7 @@ Documentation of the public APIs of the simulator @item @uref{http://www.nsnam.org/wiki/index.php,, ns-3 wiki} @end itemize -The purpose of this tutorial is to introduce new ns-3 users to the +The purpose of this tutorial is to introduce new @command{ns-3} users to the system in a structured way. It is sometimes difficult for new users to glean essential information from detailed manuals and to convert this information into working simulations. In this tutorial, we will build @@ -48,52 +49,52 @@ into the workings of the system. A few key points are worth noting at the onset: @itemize @bullet -@item ns-3 is not an extension of @uref{http://www.isi.edu/nsnam/ns,,ns-2}; -it is a new simulator. The two simulators are both written in C++ but ns-3 -is a new simulator that does not support the ns-2 APIs. Some models from ns-2 -have already been ported from ns-2 to ns-3. The project will continue to -maintain ns-2 while ns-3 is being built, and will study transition and -integration mechanisms. -@item ns-3 is open-source, and the project strives to maintain an open -environment for researchers to contribute and share their software. +@item Ns-3 is not an extension of @uref{http://www.isi.edu/nsnam/ns,,ns-2}; +it is a new simulator. The two simulators are both written in C++ but +@command{ns-3} is a new simulator that does not support the ns-2 APIs. Some +models from ns-2 have already been ported from ns-2 to ns-3. The project will +continue to maintain ns-2 while ns-3 is being built, and will study transition +and integration mechanisms. +@item @command{Ns-3} is open-source, and the project strives to maintain an +open environment for researchers to contribute and share their software. @end itemize @node For ns-2 Users @section For ns-2 Users For those familiar with ns-2, the most visible outward change when moving to -ns-3 is the choice of scripting language. ns-2 is typically scripted in Tcl -and results of simulations can be visualized using the Network Animator -@command{nam}. In ns-3 there is currently no visualization module, and Python -bindings have been developed (Tcl bindings have been prototyped -using @uref{http://www.swig.org,,SWIG}, but are not supported by the -current development team). In this tutorial, we will concentrate on -scripting directly in C++ and interpreting results via trace files. +@command{ns-3} is the choice of scripting language. Ns-2 is typically +scripted in Tcl and results of simulations can be visualized using the +Network Animator @command{nam}. In @command{ns-3} there is currently no +visualization module, and Python bindings have been developed (Tcl bindings +have been prototyped using @uref{http://www.swig.org,,SWIG}, but are not +currently supported). In this tutorial, we will concentrate on scripting +directly in C++ and interpreting results via trace files. -But there are similarities as well (both, for example, are based -on C++ objects, and some code from ns-2 has already been ported -to ns-3). We will try to highlight differences between ns-2 and ns-3 +But there are similarities as well (both, for example, are based on C++ +objects, and some code from ns-2 has already been ported to @command{ns-3}). +We will try to highlight differences between ns-2 and @command{ns-3} as we proceed in this tutorial. @node Contributing @section Contributing @cindex contributing -ns-3 is a research and educational simulator, by and for the research -community. It will rely on the ongoing contributions of the community to -develop new models, debug or maintain existing ones, and share results. There -are a few policies that we hope will encourage people to contribute to ns-3 -like they have for ns-2: +@command{Ns-3} is a research and educational simulator, by and for the +research community. It will rely on the ongoing contributions of the +community to develop new models, debug or maintain existing ones, and share +results. There are a few policies that we hope will encourage people to +contribute to @command{ns-3} like they have for ns-2: @itemize @bullet -@item open source licensing based on GNU GPLv2 compatibility -@item @uref{http://www.nsnam.org/wiki/index.php,,wiki} +@item Open source licensing based on GNU GPLv2 compatibility; +@item @uref{http://www.nsnam.org/wiki/index.php,,wiki}; @item @uref{http://www.nsnam.org/wiki/index.php/Contributed_Code,,Contributed Code} page, similar to ns-2's popular @uref{http://nsnam.isi.edu/nsnam/index.php/Contributed_Code,,Contributed Code} -page -@item @code{src/contrib} directory (we will host your contributed code) -@item open @uref{http://www.nsnam.org/bugzilla,,bug tracker} -@item ns-3 developers will gladly help potential contributors to get -started with the simulator (please contact @uref{http://www.nsnam.org/people.html,,one of us}) +page; +@item @code{src/contrib} directory (we will host your contributed code); +@item Open @uref{http://www.nsnam.org/bugzilla,,bug tracker}; +@item @command{Ns-3} developers will gladly help potential contributors to get +started with the simulator (please contact @uref{http://www.nsnam.org/people.html,,one of us}). @end itemize If you are an ns user, please consider providing your feedback, bug fixes, or @@ -110,7 +111,7 @@ following: the simulator and what it might be like to use; @item Try to download and build a copy; @item Try to run a few sample programs, and perhaps change some configurations; -@item Look at simulation output, and try to adjust it +@item Look at simulation output, and try to adjust it. @end itemize As a result, we have tried to organize the tutorial along the above @@ -138,7 +139,8 @@ repository names on the left of the page, you will see @emph{changelogs} for these repositories, and links to the @emph{manifest}. From the manifest links, one can browse the source tree. -The top-level directory will look something like: +The top-level directory for one of our @emph{repositories} will look +something like: @verbatim drwxr-xr-x [up] drwxr-xr-x doc manifest @@ -175,9 +177,9 @@ Example scripts are in the @code{examples} directory. The @code{examples} directory is a good place to start browsing the code. For ns-2 users, who may be familiar with the @code{simple.tcl} example script -in the ns-2 documentation, an analogous script is found in -@code{examples/simple-point-to-point.cc} with a Python equivalent found -in @emph{(pending Python merge)}. +in the ns-2 documentation, a roughly analogous script is found in +@code{examples/first.cc} with a Python equivalent found in +@emph{(pending Python merge)}. @node Doxygen @section Doxygen @@ -190,7 +192,8 @@ look. @section Other Documentation We provide a large amount of documentation regarding the various components -of ns-2 on our website. See: @uref{http://www.nsnam.org/documents.html}. +of @command{ns-3} on our website. See: +@uref{http://www.nsnam.org/documents.html}. @c ======================================================================== @c Resources @@ -211,28 +214,26 @@ of ns-2 on our website. See: @uref{http://www.nsnam.org/documents.html}. @section The Web @cindex www.nsnam.org -There are several important resources of which any ns-3 user must be -aware. The main web site is located at @uref{http://www.nsnam.org} -and provides access to basic information about the ns-3 system. -Detailed documentation is available through the main web site at +There are several important resources of which any @command{ns-3} user must be +aware. The main web site is located at @uref{http://www.nsnam.org} and +provides access to basic information about the ns-3 system. Detailed +documentation is available through the main web site at @uref{http://www.nsnam.org/documents.html}. @cindex documentation @cindex architecture You can find documents relating to the system architecture from this page, -and also gain access to the detailed software documentation. The software -system is documented in great detail using -@uref{http://www.stack.nl/~dimitri/doxygen/,,Doxygen}. There is a Wiki that -complements the main ns-3 web site which you will find at +and also gain access to the detailed software documentation. There is a Wiki +that complements the main ns-3 web site which you will find at @uref{http://www.nsnam.org/wiki/}. -You will find user and developer FAQs there as well as troubleshooting guides, -third-party contributed code, papers, etc. The source code may be found -and browsed at @uref{http://code.nsnam.org/}. +You will find user and developer FAQs there, as well as troubleshooting +guides, third-party contributed code, papers, etc. @cindex mercurial repository @cindex ns-3-dev repository @cindex release repository +The source code may be found and browsed at @uref{http://code.nsnam.org/}. There you will find the current development tree in the repository named @code{ns-3-dev}. Past releases and experimental repositories of the core developers may also be found there. @@ -248,7 +249,7 @@ the most well known. @cindex software configuration management @cindex Mercurial -The ns-3 project uses Mercurial as its source code management system. +The @command{ns-3} project uses Mercurial as its source code management system. Although you do not need to know much about Mercurial in order to complete this tutorial, we recommend becoming familiar with Mercurial and using it to access the source code. Mercurial has a web site at @@ -260,8 +261,8 @@ also provides a tutorial at and a QuickStart guide at @uref{http://www.selenic.com/mercurial/wiki/index.cgi/QuickStart/}. -You can also find vital information about using Mercurial and ns-3 -on the main ns-3 web site. +You can also find vital information about using Mercurial and @command{ns-3} +on the main @command{ns-3} web site. @node Waf @section Waf @@ -278,7 +279,7 @@ use in a very large and highly configurable system. Because of this, many alternatives have been developed. Recently these systems have been developed using the Python language. -The build system @code{Waf} is used on the ns-3 project. It is one +The build system @code{Waf} is used on the @command{ns-3} project. It is one of the new generation of Python-based build systems. You will not need to understand any Python to build the existing ns-3 system, and will only have to understand a tiny and intuitively obvious subset of Python in @@ -308,15 +309,15 @@ before proceeding. @cindex toolchain @cindex GNU -The ns-3 system uses the GNU ``toolchain'' for development. -A software toolchain is the set of programming tools available in the given +The @command{ns-3} system uses the GNU ``toolchain'' for development. A +software toolchain is the set of programming tools available in the given environment. For a quick review of what is included in the GNU toolchain see, @uref{http://en.wikipedia.org/wiki/GNU_toolchain}. @cindex Linux -Typically an ns-3 author will work in Linux or a Linux-like +Typically an @command{ns-3} author will work in Linux or a Linux-like environment. For those running under Windows, there do exist environments -which simulate the Linux environment to various degrees. The ns-3 +which simulate the Linux environment to various degrees. The @command{ns-3} project supports development in the Cygwin and the MinGW environments for these users. See @uref{http://www.cygwin.com/} and @uref{http://www.mingw.org/} for details on downloading and using these @@ -337,7 +338,7 @@ crash creating a sh.exe.stackdump file when I try to compile my source code.'' Believe it or not, the @code{Logitech Process Monitor} insinuates itself into every DLL in the system when it is running. It can cause your Cygwin or MinGW DLLs to die in mysterious ways and often prevents debuggers from -running. Beware of Logitech. +running. Beware of Logitech software. @node Socket Programming @section Socket Programming @@ -357,5 +358,5 @@ not have access to a copy of the book, the echo clients and servers shown in the website above) you will be in good shape to understand the tutorial. There is a similar book on Multicast Sockets, @uref{http://www.elsevier.com/wps/product/cws_home/700736,,Multicast Sockets, Makofske and Almeroth}. -that covers material you may need to understand for the multicast examples. - +that covers material you may need to understand for the multicast examples in +the distribution. diff --git a/doc/tutorial/tutorial.texi b/doc/tutorial/tutorial.texi index 8869fcab3..dcacae9ea 100644 --- a/doc/tutorial/tutorial.texi +++ b/doc/tutorial/tutorial.texi @@ -14,10 +14,10 @@ three forms: @item @uref{http://www.nsnam.org/wiki/index.php,, ns-3 wiki} @end itemize -This document is written in GNU Texinfo and is to be maintained in -revision control on the @command{ns-3} code server. Both PDF and HTML versions -should be available on the server. Changes to -the document should be discussed on the ns-developers@@isi.edu mailing list. +This document is written in GNU Texinfo and is to be maintained in revision +control on the @command{ns-3} code server. Both PDF and HTML versions should +be available on the server. Changes to the document should be discussed on +the ns-developers@@isi.edu mailing list. @end ifinfo @copying @@ -31,10 +31,10 @@ three forms: @item @uref{http://www.nsnam.org/wiki/index.php,, ns-3 wiki} @end itemize -This document is written in GNU Texinfo and is to be maintained in -revision control on the @command{ns-3} code server. Both PDF and HTML -versions should be available on the server. Changes to -the document should be discussed on the ns-developers@@isi.edu mailing list. +This document is written in GNU Texinfo and is to be maintained in revision +control on the @command{ns-3} code server. Both PDF and HTML versions should +be available on the server. Changes to the document should be discussed on +the ns-developers@@isi.edu mailing list. This software is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by From df2984b28caa98223db5fa979b04015ad35553de Mon Sep 17 00:00:00 2001 From: Craig Dowell Date: Sun, 29 Jun 2008 21:26:04 -0700 Subject: [PATCH 079/495] mispeeling in tutorial command sequence --- doc/tutorial/getting-started.texi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/tutorial/getting-started.texi b/doc/tutorial/getting-started.texi index 282a21b15..d5ae09ffb 100644 --- a/doc/tutorial/getting-started.texi +++ b/doc/tutorial/getting-started.texi @@ -51,7 +51,7 @@ Mercurial --- it will make your life easier in the long run. @cindex repository If you go to the following link: @uref{http://code.nsnam.org/}, you will see a number of repositories. Many are the private repositories of -the @comamnd{ns-3} development team. The repositories of interest to you will +the @command{ns-3} development team. The repositories of interest to you will be prefixed with ``ns-3''. The current development snapshot (unreleased) of @command{ns-3} may be found at: @uref{http://code.nsnam.org/ns-3-dev/}. Official releases of @command{ns-3} will be numbered as @code{ns-3.} From 2f840a4f542afb613a3c1b005752c98bcc256d40 Mon Sep 17 00:00:00 2001 From: Craig Dowell Date: Sun, 29 Jun 2008 22:14:22 -0700 Subject: [PATCH 080/495] cleaning up tutorial --- doc/tutorial/conceptual-overview.texi | 2 +- doc/tutorial/tweaking.texi | 367 +++++++++++++------------- 2 files changed, 189 insertions(+), 180 deletions(-) diff --git a/doc/tutorial/conceptual-overview.texi b/doc/tutorial/conceptual-overview.texi index 3367559bb..d060ad176 100644 --- a/doc/tutorial/conceptual-overview.texi +++ b/doc/tutorial/conceptual-overview.texi @@ -11,7 +11,7 @@ @menu * Key Abstractions:: -* A First ns-3 script +* A First ns-3 script:: @end menu The first thing we need to do before actually starting to look at or write diff --git a/doc/tutorial/tweaking.texi b/doc/tutorial/tweaking.texi index c01f5b2ec..600aed662 100644 --- a/doc/tutorial/tweaking.texi +++ b/doc/tutorial/tweaking.texi @@ -28,25 +28,25 @@ @section Using the Logging Module @cindex logging -We have already taken a brief look at the ns-3 logging module while going -over the @code{first.cc} script. We will now take a closer look and see what -kind of use-cases the logging subsystem was designed to cover. +We have already taken a brief look at the @command{ns-3} logging module while +going over the @code{first.cc} script. We will now take a closer look and +see what kind of use-cases the logging subsystem was designed to cover. @node Logging Overview @subsection Logging Overview -Many large systems support some kind of message logging facility, and ns-3 -is not an exception. In some cases, only error messages are logged to the -``operator console'' (which is typically @code{stderr} in Unix-based systems). -In other systems, warning messages may be output as well as more detailed -informational messages. In some cases, logging facilities are used to output -debug messages which can quickly turn the output into a blur. +Many large systems support some kind of message logging facility, and +@command{ns-3} is not an exception. In some cases, only error messages are +logged to the ``operator console'' (which is typically @code{stderr} in Unix- +based systems). In other systems, warning messages may be output as well as +more detailed informational messages. In some cases, logging facilities are +used to output debug messages which can quickly turn the output into a blur. -ns-3 takes the view that all of these verbosity levels are useful and se -provides a selectable, multi-level approach to message logging. Logging can -be disabled completely, enabled on a component-by-component basis, enabled -globally and has selectable verbosity levels. The ns-3 log module provides -a straightforward, relatively easy to use way to get some kinds of information -out of your simulation. +@command{Ns-3} takes the view that all of these verbosity levels are useful +and we provide a selectable, multi-level approach to message logging. Logging +can be disabled completely, enabled on a component-by-component basis, enabled +globally and has selectable verbosity levels. The @command{ns-3} log module +provides a straightforward, relatively easy to use way to get some kinds of +information out of your simulation. You should understand that we do provide a general purpose mechanism --- tracing --- to get data out of your models which should be preferred for @@ -64,7 +64,7 @@ defined in the system. @item NS_LOG_DEBUG --- Log relatively rare, ad-hoc debugging messages; @item NS_LOG_INFO --- Log informational messages about program progress; @item NS_LOG_FUNCTION --- Log a message describing each function called; -@item NS_LOG_LOGIC -- Log messages describing logical flow in a function; +@item NS_LOG_LOGIC -- Log messages describing logical flow within a function; @item NS_LOG_ALL --- Log everything. @end itemize @@ -72,13 +72,14 @@ We also provide an unconditional logging level that is always displayed, irrespective of logging levels or component selection. @itemize @bullet -NS_LOG_UNCOND -- Log the associated message unconditionally. +@item NS_LOG_UNCOND -- Log the associated message unconditionally. @end itemize -Each level can be requested singly or cumulatively; and can be set using a -shell environment variable (NS_LOG) or by logging system function call. As -was seen earlier in the tutorial, the logging system has Doxygen documentation -so now would be a good time to peruse the Logging Module documentation. +Each level can be requested singly or cumulatively; and logging can be set +up using a shell environment variable (NS_LOG) or by logging system function +call. As was seen earlier in the tutorial, the logging system has Doxygen +documentation so now would be a good time to peruse the Logging Module +documentation. Now that you have read the documentation in great detail, we can get some interesting information out of the @code{first.cc} example script you dropped @@ -107,7 +108,7 @@ ask the client application, for example, to print more information by setting its logging level via the NS_LOG environment variable. I am going to assume from here on that are using an sh-like shell that uses the``VARIABLE=value'' syntax. If you are using a csh-like shell, then you will have to convert to -``setenv VARIABLE value'' syntax. +the ``setenv VARIABLE value'' syntax required by those shells. Let's ask the UDP echo client application to print a little more information. Right now, it is responding to the following line of code in @code{first.cc}, @@ -158,19 +159,26 @@ output: @end verbatim The only additional debug information provided by the application is from -the NS_LOG_FUNCTION level. You can now see a log of the function calls that -were made to the application. If you look closely you will notice a single -colon between the string @code{UdpEchoClientApplication} and the method name -where you might have expected a C++ scope operator (@code{::}). This is -intentional. The name is not actually a class name, it is a logging component -name. When there is a one-to-one correspondence between a source file and a -class, this will generally be the class name but you should understand that -it is not actually a class name, and there is a single colon to separate the -logging component name from the function name that is printed. +the NS_LOG_FUNCTION level. Note that there are no requirements in the +@command{ns-3} system that logging components must support any particular +logging functionality. The decision regarding how much information is logged +is left to the individual developer. + +You can now see a log of the function calls that were made to the application. +If you look closely you will notice a single colon between the string +@code{UdpEchoClientApplication} and the method name where you might have +expected a C++ scope operator (@code{::}). This is intentional. + +The name is not actually a class name, it is a logging component name. When +there is a one-to-one correspondence between a source file and a class, this +will generally be the class name but you should understand that it is not +actually a class name, and there is a single colon there instead of a double +colon to remind you in a relatively subtle way to conceptually separate the +logging component name from the class name. It turns out that in come cases, it can be hard to determine which method actually generates a log message. If you look in the text above, you may -wonder where the string ``@code{Received 1024 bytes from 10.1.1.1}'' comes +wonder where the string ``@code{Received 1024 bytes from 10.1.1.2}'' comes from. You can resolve this by ORing the @code{prefix_func} level into the @code{NS_LOG} environment variable. Try doing the following, @@ -178,8 +186,8 @@ from. You can resolve this by ORing the @code{prefix_func} level into the export 'NS_LOG=UdpEchoClientApplication=level_all|prefix_func' @end verbatim -Note that the single quotes are required since the vertical bar is a Unix -pipe connector. +Note that the quotes are required since the vertical bar we use to indicate an +OR operation is also a Unix pipe connector. Now, if you run the script you will see that the logging system makes sure that every message from the given log component is prefixed with the component @@ -204,9 +212,11 @@ name. @end verbatim You can now see all of the messages coming from the UDP echo client application -are identified as such. The remaining message must be coming from the UDP -echo server application. We can enable that component by entering a colon -separated list of components in the NS_LOG environment variable. +are identified as such. The message ``Received 1024 bytes from 10.1.1.2'' is +now clearly identified as coming from the echo client application. The +remaining message must be coming from the UDP echo server application. We +can enable that component by entering a colon separated list of components in +the NS_LOG environment variable. @verbatim export 'NS_LOG=UdpEchoClientApplication=level_all|prefix_func: @@ -307,11 +317,11 @@ turning on all of the logging components in the system. Try setting the export 'NS_LOG=*=level_all|prefix_func|prefix_time' @end verbatim -The asterisk is the logging component wildcard. This will turn on all of the -logging in all of the components in the system. I won't reproduce the output -here (as of this writing it produces 772 lines of output for the single packet -echo) but you can redirect this information into a file and look through it -with your favorite editor if you like, +The asterisk above is the logging component wildcard. This will turn on all +of the logging in all of the components used in the simulation. I won't +reproduce the output here (as of this writing it produces 772 lines of output +for the single packet echo) but you can redirect this information into a file +and look through it with your favorite editor if you like, @verbatim ~/repos/ns-3-tutorial > ./waf --run scratch/first >& log.out @@ -322,8 +332,10 @@ have no idea where things are going wrong. I can follow the progress of the code quite easily without having to set breakpoints and step through code in a debugger. When I have a general idea about what is going wrong, I transition into a debugger for fine-grained examination of the problem. This -output can be especially useful when your script does something completely -unexpected. +kind of output can be especially useful when your script does something +completely unexpected. If you are stepping using a debugger you may miss an +unexpected excursion completely. Logging the excursion makes it quickly +visible. @node Adding Logging to your Code @subsection Adding Logging to your Code @@ -332,7 +344,7 @@ You can add new logging to your simulations by making calls to the log component via several macros. Let's do so in the @code{first.cc} script we have in the @code{scratch} directory. -Recall that we have defined a logging component in that script. +Recall that we have defined a logging component in that script: @verbatim NS_LOG_COMPONENT_DEFINE ("FirstScriptExample"); @@ -340,10 +352,10 @@ Recall that we have defined a logging component in that script. You now know that you can enable all of the logging for this component by setting the @code{NS_LOG} environment variable to the various levels. Let's -add some logging. The macro to add an informational level log message is -@code{NS_LOG_INFO}. Add one just before we start creating the nodes that -tells you that the script is ``Creating Topology.'' This is done as in this -code snippet, +go ahead add some logging to the script. The macro used to add an +informational level log message is @code{NS_LOG_INFO}. Go ahead and add one +just before we start creating the nodes that tells you that the script is +``Creating Topology.'' This is done as in this code snippet, @verbatim NS_LOG_INFO ("Creating Topology"); @@ -357,17 +369,18 @@ off the torrent of logging we previously enabled: @end verbatim Now, if you run the script, you will not see your new message since its -associated logging component has not been enabled. In order to see your -message you will have to enable the @code{FirstScriptExample} logging -component with a level greater than or equal to @code{NS_LOG_INFO}. If -you just want to see this particular level of logging, you can enable that -by, +associated logging component (@code{FirstScriptExample}) has not been enabled. +In order to see your message you will have to enable the +@code{FirstScriptExample} logging component with a level greater than or equal +to @code{NS_LOG_INFO}. If you just want to see this particular level of +logging, you can enable it by, @verbatim ~/repos/ns-3-tutorial > export NS_LOG=FirstScriptExample=info @end verbatim -If you now run the script you will see your new logging message, +If you now run the script you will see your new ``Creating Topology'' log +message, @verbatim ~/repos/ns-3-tutorial > ./waf --run scratch/first @@ -380,13 +393,6 @@ If you now run the script you will see your new logging message, ~/repos/ns-3-tutorial > @end verbatim -As previously described, this does not also enable the lower levels of logging -but selects out the single infomational level. - -As we outlined in the Logging Overview, there are currently seven levels of -logging verbosity you can use and you can also prefix your various log messages -with component name and simulation time. - @c ======================================================================== @c Using Command Line Arguments @c ======================================================================== @@ -395,10 +401,10 @@ with component name and simulation time. @subsection Overriding Default Attributes @cindex command line arguments -Another way you can change the way that ns-3 scripts behave without editing -and building scripts is via @emph{command line arguments.} We provide a -mechanism to parse command line arguments and automatically set local and -global variables based on those arguments. +Another way you can change how @command}ns-3} scripts behave without editing +and building is via @emph{command line arguments.} We provide a mechanism to +parse command line arguments and automatically set local and global variables +based on those arguments. The first step in using the command line argument system is to declare the command line parser. This is done quite simply (in your main program) as @@ -418,18 +424,19 @@ in the following code, @end verbatim This simple two line snippet is actually very useful by itself. It opens the -door to the ns-3 global variable and attribute systems. Go ahead and add that -two lines of code to the @code{first.cc} script at the start of @code{main}. -Go ahead and build the script and run it, but ask the script for help in the -following way, +door to the @command{ns-3} global variable and attribute systems. Go ahead +and add that two lines of code to the @code{first.cc} script at the start of +@code{main}. Go ahead and build the script and run it, but ask the script +for help in the following way, @verbatim ~/repos/ns-3-tutorial > ./waf --run "scratch/first --PrintHelp" @end verbatim -This will ask way to run the @code{scratch/first} script and pass the command -line argument @code{--PrintHelp} to the script. The command line parser will -now see the @code{PrintHelp} argument and respond with, +This will ask Waf to run the @code{scratch/first} script and pass the command +line argument @code{--PrintHelp} to the script. The quotes are required to +sort out which program gets which argument. The command line parser will +now see the @code{--PrintHelp} argument and respond with, @verbatim ~/repos/ns-3-tutorial > ./waf --run ``scratch/first --PrintHelp'' @@ -445,8 +452,8 @@ now see the @code{PrintHelp} argument and respond with, @end verbatim Let's focus on the @code{--PrintAttributes} option. We have already hinted -at the attribute system while walking through the @code{first.cc} script. We -looked at the following lines of code, +at the @command{ns-3} attribute system while walking through the +@code{first.cc} script. We looked at the following lines of code, @verbatim PointToPointHelper pointToPoint; @@ -457,9 +464,9 @@ looked at the following lines of code, and mentioned that @code{DataRate} was actually an @code{Attribute} of the @code{PointToPointNetDevice}. Let's use the command line argument parser to take a look at the attributes of the PointToPointNetDevice. The help -listing says that we should provide a typeid. This corresponds to the class -name of the class to which the attributes belong. In this case it will be -@code{ns3::PointToPointNetDevice}. Let's go ahead and type in, +listing says that we should provide a @code{TypeId}. This corresponds to the +class name of the class to which the attributes belong. In this case it will +be @code{ns3::PointToPointNetDevice}. Let's go ahead and type in, @verbatim ./waf --run "scratch/first --PrintAttributes=ns3::PointToPointNetDevice" @@ -470,18 +477,18 @@ Among the attributes you will see listed is, @verbatim --ns3::PointToPointNetDevice::DataRate=[32768bps]: - The default data rate fo r point to point links + The default data rate for point to point links @end verbatim -This is the default value that will be used when a PointToPointNetDevice is -created in the system. We overrode this default with the parameter setting -in the PointToPointHelper above. Let's use the default values for the -PointToPoint devices and channels by deleting the SetDeviceParameter call and -the SetChannelParameter call from the @code{first.cc} we have in the scratch -directory. +This is the default value that will be used when a @code{PointToPointNetDevice} +is created in the system. We overrode this default with the ``parameter'' +setting in the @code{PointToPointHelper} above. Let's use the default values +for the point-to-point devices and channels by deleting the +@code{SetDeviceParameter} call and the @code{SetChannelParameter} call from +the @code{first.cc} we have in the scratch directory. -Your script should now just declare the PointToPointHelper and not do any -sets as in the following example, +Your script should now just declare the @code{PointToPointHelper} and not do +any @code{set} operations as in the following example, @verbatim ... @@ -497,8 +504,9 @@ sets as in the following example, ... @end verbatim -Go ahead and build the new script with waf. Now let's go back and enable some -logging from the UDP echo server application and turn on the time prefix. +Go ahead and build the new script with Waf (@code{./waf}) and let's go back +and enable some logging from the UDP echo server application and turn on the +time prefix. @verbatim export 'NS_LOG=UdpEchoServerApplication=level_all|prefix_time' @@ -529,23 +537,25 @@ the data rate of the @code{PointToPointNetDevice} down to its default of 32768 bits per second from five megabits per second. If we were to provide a new @code{DataRate} using the command line, we could -speed our simulation up again, +speed our simulation up again. We do this in the following way, according to +the formula implied by the help item: @verbatim ./waf --run "scratch/first --ns3::PointToPointNetDevice::DataRate=5Mbps" @end verbatim This will set the default value of the @code{DataRate} attribute back to -five megabits per second. To get the old behavior back, we will have to set -the speed-of-light delay of the channel. We can ask the command line system -to print out the @code{Attributes} of the channel just like we did the net -device: +five megabits per second. To get the original behavior of the script back, +we will have to set the speed-of-light delay of the channel. We can ask the +command line system to print out the @code{Attributes} of the channel just +like we did the net device: @verbatim ./waf --run "scratch/first --PrintAttributes=ns3::PointToPointChannel" @end verbatim -and we discover the @code{Delay} attribute. +We discover the @code{Delay} attribute of the channel is set in the following +way: @verbatim --ns3::PointToPointChannel::Delay=[0ns]: @@ -560,7 +570,7 @@ We can then set both of these default values through the command line system, --ns3::PointToPointChannel::Delay=2ms" @end verbatim -In which case we recover the timing we had when we explicitly set the +in which case we recover the timing we had when we explicitly set the @code{DataRate} and @code{Delay} in the script: @verbatim @@ -576,7 +586,7 @@ In which case we recover the timing we had when we explicitly set the UdpEchoServerApplication:~UdpEchoServer() @end verbatim -Note that the packet is received by the server at 2.0036864 seconds. We +Note that the packet is again received by the server at 2.0036864 seconds. We could actually set any of the attributes used in the script in this way. In particular we could set the @code{UdpEchoClient} attribute @code{MaxPackets} to some other value than one. @@ -603,9 +613,9 @@ quite simply by using the @code{AddValue} method to the command line parser. Let's use this facility to specify the number of packets to echo in a completely different way. Let's add a local variable called @code{nPackets} -to the main function. We'll initialize it to one to match our previous +to the @code{main} function. We'll initialize it to one to match our previous default behavior. To allow the command line parser to change this value, we -need to hook the value into the parser. Do this by adding a call to +need to hook the value into the parser. We do this by adding a call to @code{AddValue}. Go ahead and change the @code{scratch/first.cc} script to start with the following code, @@ -624,7 +634,7 @@ start with the following code, Scroll down to the point in the script where we set the @code{MaxPackets} attribute and change it so that it is set to the variable @code{nPackets} -instead of the constant @code{1} as below. +instead of the constant @code{1} as is shown below. @verbatim echoClient.SetAppAttribute ("MaxPackets", UintegerValue (nPackets)); @@ -649,7 +659,7 @@ should see your new @code{User Argument} listed in the help. @end verbatim If you want to specify the number of packets to echo, you can now do so by -setting the @code{nPackets} argument, +setting the @code{--nPackets} argument in the command line, @verbatim ~/repos/ns-3-tutorial > ./waf --run "scratch/first --nPackets=2" @@ -664,12 +674,14 @@ setting the @code{nPackets} argument, ~/repos/ns-3-tutorial > @end verbatim -If you are an ns-3 user, you can use the command line argument system to -control global values and attributes. If you are a model author, you can -add new attributes to your Objects and they will automatically be available -for setting by your users through the command line system. If you are a -script author, you can add new variables to your scripts and hook them into -the command line system quite painlessly. +You have now echoed two packets. + +If you are an @command{ns-3} user, you can use the command line argument +system to control global values and attributes. If you are a model author, +you can add new attributes to your Objects and they will automatically be +available for setting by your users through the command line system. If you +are a script author, you can add new variables to your scripts and hook them +into the command line system quite painlessly. @c ======================================================================== @c Using the Tracing System @@ -707,17 +719,17 @@ and sinks. @end itemize The @command{ns-3} tracing system is built on the concepts of independent -tracing sources and tracing sinks and a uniform mechanism for connecting +tracing sources and tracing sinks, and a uniform mechanism for connecting sources to sinks. Trace sources are entities that can signal events that happen in a simulation and provide access to interesting underlying data. For example, a trace source could indicate when a packet is received by a net -device and provide access to the packet for interested trace sinks. +device and provide access to the packet contents for interested trace sinks. Trace sources are not useful by themselves, they must be ``connected'' to other pieces of code that actually do something useful with the information provided by the sink. Trace sinks are consumers of the events and data -provided by the trace sources. For example, one could create a trace sink t -hat would (when connected to the trace source of the previous example) print +provided by the trace sources. For example, one could create a trace sink +that would (when connected to the trace source of the previous example) print out interesting parts of the received packet. The rationale for this explicit division is to allow users to attach new @@ -727,10 +739,6 @@ a user could define a new tracing sink in her script and attach it to an existing tracing source defined in the simulation core editing only the user script. -What remains to be defined is a way for users to find these hooks (tracing -sources) and attach sinks to them. A tracing namespace is defined for -this purpose. - In this tutorial, we will walk through some pre-defined sources and sinks and show how they may be customized with little user effort. See the ns-3 manual or how-to sections for information on advanced tracing configuration including @@ -739,12 +747,12 @@ extending the tracing namespace and creating new tracing sources. @cindex tracing @cindex ASCII tracing @subsection ASCII Tracing -ns-3 provides an ASCII trace helper that is a wrapper around low-level -tracing system. This helper lets you configure some useful and easily -understood packet traces easily. The output of a trace of a simulation run -is an ASCII file --- thus the name. For those familiar with @command{ns-2} -output, this type of trace is analogous to the @command{out.tr} generated -by many scripts. +@command{Ns-3} provides an ASCII trace helper that is a wrapper around the +low-level tracing system. This helper lets you configure some useful and +easily understood packet traces easily. The output of a trace of a simulation +run is an ASCII file --- thus the name. For those familiar with +@command{ns-2} output, this type of trace is analogous to the @command{out.tr} +generated by many scripts. @cindex tracing packets Let's just jump right in and add some ASCII tracing output to our @@ -760,11 +768,11 @@ following code to the script just before the call to @code{Simulator::Run ()}. The first two lines are just vanilla C++ code to open a stream that will be written to a file named ``first.tr.'' See your favorite C++ tutorial if you are unfamiliar with this code. The last line of code in the snippet above -tells ns-3 that you want to enable ASCII tracing on all point-to-point devices -in your simulation; and you want the (provided) trace sinks to write out -information about packet movement in ASCII format to the stream provided. -For those familiar with @command{ns-2}, the traced events are equivalent -to the popular trace points that log "+", "-", "d", and "r" events. +tells @command{ns-3} that you want to enable ASCII tracing on all +point-to-point devices in your simulation; and you want the (provided) trace +sinks to write out information about packet movement in ASCII format to the +stream provided. For those familiar with @command{ns-2}, the traced events are +equivalent to the popular trace points that log "+", "-", "d", and "r" events. Since we have used a @code{std::ofstream} object, we also need to include the appropriate header. Add the following line to the script (I typically add it @@ -783,26 +791,28 @@ You can now build the script and run it from the command line: @cindex first.tr Just as you have seen previously, you may see some messages from Waf and then the ``Compilation finished successfully'' message. The following messages are -from the running program. When it ran, the program will have created a file -named @code{first.tr}. Because of the way that Waf works, the file is not -created in the local directory, it is created at the top-level directory of -the repository by default. If you want to control where the traces are saved -you can use the @code{--cwd} option of Waf to specify this. We have not done -so, thus we need to change into the top level directory of our repo and take a -look at the file @code{first.tr} in your favorite editor. +from the running program. + +When it ran, the program will have created a file named @code{first.tr}. +Because of the way that Waf works, the file is not created in the local +directory, it is created at the top-level directory of the repository by +default. If you want to control where the traces are saved you can use the +@code{--cwd} option of Waf to specify this. We have not done so, thus we +need to change into the top level directory of our repo and take a look at +the file @code{first.tr} in your favorite editor. @subsubsection Parsing Ascii Traces @cindex parsing ascii traces There's a lot of information there in a pretty dense form, but the first thing to notice is that there are a number of distinct lines in this file. It may -be difficult to see this clearly unless you widen your windows considerably. +be difficult to see this clearly unless you widen your window considerably. + Each line in the file corresponds to a @emph{trace event}. In this case -we are tracing events on the @emph{device queue} present in every net device -on every node in the simulation. The device queue is a queue through which -every packet destined for a channel must pass --- it is the device -@emph{transmit} queue. Note that each line in the trace file begins with a -lone character (has a space after it). This character will have the following -meaning: +we are tracing events on the @emph{transmit queue} present in every net device +on every node in the simulation. The transmit queue is a queue through which +every packet destined for a channel must pass. Note that each line in the +trace file begins with a lone character (has a space after it). This +character will have the following meaning: @cindex ascii trace enqueue operation @cindex ascii trace dequeue operation @@ -815,9 +825,9 @@ meaning: @item @code{r}: A packet was received by the net device. @end itemize -Let's take a more detailed view of the first line. I'll break it down into -sections (indented for clarity) with a two digit reference number on the -left side: +Let's take a more detailed view of the first line in the trace file. I'll +break it down into sections (indented for clarity) with a two digit reference +number on the left side: @verbatim 00 + @@ -836,40 +846,40 @@ left side: @cindex trace event @cindex simulation time The first line of this expanded trace event (reference number 00) is the -queue operation. We have a @code{+} character, so this corresponds to an -@emph{enqueue} operation. The second line (reference 01) is the simulation -time expressed in seconds. You may recall that we asked the -@code{UdpEchoClient} to start sending packets at two seconds. Here we again -see confirmation that this is, indeed, happening. +operation. We have a @code{+} character, so this corresponds to an +@emph{enqueue} operation on the transmit queue. The second line (reference 01) +is the simulation time expressed in seconds. You may recall that we asked the +@code{UdpEchoClientApplication} to start sending packets at two seconds. Here +we see confirmation that this is, indeed, happening. @cindex node number @cindex net device number @cindex smart pointer -The next line of the example listing (reference 02) tell us the trace source +The next line of the example trace (reference 02) tell us the trace source that originated this even expressed in the tracing namespace. You can think -of the tracing womewhat like you would a filesystem namespace. The root of -the namespace is the @code{NodeList}. This corresponds to a container in the -ns-3 code that contains all of the nodes that were created in the system. -Just as a filesystem has may have directories under the root, we have node -numbers in the @code{NodeList}. The string @code{/NodeList/0} therefore -refers to the zeroth node in the @code{NodeList} which we can think of as -``node 0.'' In each node there is a list of devices that have been installed. -This list appears next. You can see that this trace event comes from -@code{DeviceList/0} which is the zeroth device installed in the node. +of the tracing namespace somewhat like you would a filesystem namespace. The +root of the namespace is the @code{NodeList}. This corresponds to a container +managed in the @command{ns-3} core code that contains all of the nodes that are +created in a script. Just as a filesystem may have directories under the +root, we may have node numbers in the @code{NodeList}. The string +@code{/NodeList/0} therefore refers to the zeroth node in the @code{NodeList} +which we typically think of as ``node 0.'' In each node there is a list of +devices that have been installed. This list appears next in the namespace. +You can see that this trace event comes from @code{DeviceList/0} which is the +zeroth device installed in the node. The next string, @code{$ns3::PointToPointNetDevice} tells you what kind of device it is that is in the zeroth position of the device list for node zero. -This should by now be completely expected. Recall that the operation @code{+} -found at reference 00 means an enqueue operation on the transmit queue of the -device. This is reflected in the final segments of the ``trace path'' which -are @code{TxQueue/Enqueue}. +Recall that the operation @code{+} found at reference 00 means an enqueue +operation happened on the transmit queue of the device. This is reflected in +the final segments of the ``trace path'' which are @code{TxQueue/Enqueue}. The remaining lines in the trace should be fairly intuitive. References 03-04 indicate that the packet is encapulated in the point-to-point protocol. References 05-07 show that the packet has an IP version four header and has originated from IP address 10.1.1.1 and is destined for 10.1.1.2. References -08-09 show that this is a UDP packet from and finally reference 10 shows that -the payload is the expected 1024 bytes. +08-09 show that this packet has a UDP header and, finally, reference 10 shows +that the payload is the expected 1024 bytes. The next line in the trace file shows the same packet being dequeued from the transmit queue on the same node. @@ -894,9 +904,8 @@ device on the node with the echo server. I have reproduced that event below. Notice that the trace operation is now @code{r} and the simulation time has increased to 2.25732 seconds. If you have been following the tutorial steps closely this means that you have left the @code{DataRate} of the net devices -set to their default value of 32768 bps with a channel @code{Delay} of two -milliseconds. This time should be familiar as you have seen it before in a -previous section. +and the channel @code{Delay} set to their default values. This time should +be familiar as you have seen it before in a previous section. The trace source namespace entry (reference 02) has changed to reflect that this event is coming from node 1 (@code{/NodeList/1}) and the packet reception @@ -904,17 +913,17 @@ trace source (@code{/Rx}). It should be quite easy for you to follow the progress of the packet through the topology by looking at the rest of the traces in the file. -@subsection PCAP Trace Helper +@subsection PCAP Tracing @cindex pcap @cindex Wireshark -The @command{ns-3} @emph{pcap trace helper} is used to create trace files in +The @command{ns-3} device helpers can be used to create trace files in the @code{.pcap} format. The acronym pcap (usually written in lower case) stands for @emph{p}acket @emph{cap}ture, and is actually an API that includes the definition of a @code{.pcap} file format. The most popular program that can read and display this format is Wireshark (formerly called Ethereal). However, there are many traffic trace analyzers that use this packet format. We encourage users to exploit the many tools available for analyzing pcap -traces. In this tutorial, we show how tcpdump and Wireshark can be used. +traces. In this tutorial, we concentrate on viewing pcap traces with tcpdump. @cindex pcap tracing The code used to enable pcap tracing is a one-liner. @@ -924,18 +933,18 @@ The code used to enable pcap tracing is a one-liner. @end verbatim Go ahead and insert this line of code after the ASCII tracing code we just -added to @code{scratch/first.cc}. Notice that we only gave the pcap trace -helper call the string, ``first,'' and not ``first.pcap'' or something -similar. This is because the parameter is a prefix, not a complete file name. -The pcap trace helper will actually create a trace file for every device in -the simulation that generates a traced event. The file names will be built -using the prefix, the node number, the device number and a ``.pcap'' suffix. +added to @code{scratch/first.cc}. Notice that we only passed the string +``first,'' and not ``first.pcap'' or something similar. This is because the +parameter is a prefix, not a complete file name. The helper will actually +create a trace file for every point-to-point device in the simulation. The +file names will be built using the prefix, the node number, the device number + and a ``.pcap'' suffix. In our example script, we will see a files named ``first-0-0.pcap'' and -``first.1-0.pcap'' which are the pcap traces for node 0, device 0 and node 1, -device 1, respectively. +``first.1-0.pcap'' which are the pcap traces for node 0-device 0 and +node 1-device 1, respectively. -You can now run the script as you have been: +You can now run the script in the usual way: @verbatim ./waf --run scratch/first From 24e907d03603ace0deb5e65a8dbdf2685f1422f5 Mon Sep 17 00:00:00 2001 From: Craig Dowell Date: Sun, 29 Jun 2008 23:11:25 -0700 Subject: [PATCH 081/495] more editing passes through tutorial --- doc/tutorial/building-topologies.texi | 435 ++++++++++++-------------- doc/tutorial/tweaking.texi | 2 +- 2 files changed, 206 insertions(+), 231 deletions(-) diff --git a/doc/tutorial/building-topologies.texi b/doc/tutorial/building-topologies.texi index 666e6dde5..7880d656e 100644 --- a/doc/tutorial/building-topologies.texi +++ b/doc/tutorial/building-topologies.texi @@ -28,15 +28,15 @@ @cindex topology @cindex bus network topology -In this section we are going to expand our mastery of ns-3 network devices and -channels to cover an example of a bus network. Ns-3 provides a net device and -channel we call CSMA (Carrier Sense Multiple Access). +In this section we are going to expand our mastery of @command{ns-3} network +devices and channels to cover an example of a bus network. @command{Ns-3} +provides a net device and channel we call CSMA (Carrier Sense Multiple Access). -The ns-3 CSMA device models a simple network in the spirit of Ethernet. A real -Ethernet uses CSMA/CD (Carrier Sense Multiple Access with Collision Detection) -scheme with exponentially increasing backoff to contend for the shared -transmission medium. The ns-3 CSMA device and channel models only a -subset of this. +The @command{ns-3} CSMA device models a simple network in the spirit of +Ethernet. A real Ethernet uses CSMA/CD (Carrier Sense Multiple Access with +Collision Detection) scheme with exponentially increasing backoff to contend +for the shared transmission medium. The @command{ns-3} CSMA device and +channel models only a subset of this. Just as we have seen point-to-point topology helper objects when constructing point-to-point topologies, we will see equivalent CSMA topology helpers in @@ -47,8 +47,8 @@ We provide an example script in our @code{examples} directory. This script builds on the @code{first.cc} script and adds a CSMA network to the point-to-point simulation we've already considered. Go ahead and open @code{examples/second.cc} in your favorite editor. You will have already seen -enough ns-3 code to understand most of what is going on in this example, but -we will go over the entire script and examine some of the output. +enough @command{ns-3} code to understand most of what is going on in this +example, but we will go over the entire script and examine some of the output. Just as in the @code{first.cc} example (and in all ns-3 examples) the file begins with an emacs mode line and some GPL boilerplate. @@ -127,7 +127,7 @@ done in @code{first.cc}. @end verbatim Next, we delare another @code{NodeContainer} to hold the nodes that will be -part of the bus (CSMA) network. First we just instantiate the container +part of the bus (CSMA) network. First, we just instantiate the container object itself. @verbatim @@ -139,8 +139,8 @@ object itself. The next line of code @code{Get}s the first node (as in having an index of one) from the point-to-point node container and adds it to the container of nodes that will get CSMA devices. The node in question is going to end up with a -point-to-point device and a CSMA device. We then create a number of ``extra'' -nodes that compose the remainder of the CSMA network. +point-to-point device @emph{and} a CSMA device. We then create a number of +``extra'' nodes that compose the remainder of the CSMA network. The next bit of code should be quite familiar by now. We instantiate a @code{PointToPointHelper} and set the associated default attributes so that @@ -157,8 +157,8 @@ helper and a two millisecond delay on channels created by the helper. @end verbatim We then instantiate a @code{NetDeviceContainer} to keep track of the -point-to-point net devices and we install devices on the ``point-to-point -nodes. +point-to-point net devices and we @code{Install} devices on the +point-to-point nodes. We mentioned above that you were going to see a helper for CSMA devices and channels, and the next lines introduce them. The @code{CsmaHelper} works just @@ -191,7 +191,7 @@ stacks present. Just as in the @code{first.cc} script, we will use the Recall that we took one of the nodes from the @code{p2pNodes} container and added it to the @code{csmaNodes} container. Thus we only need to install the stacks on the remaining @code{p2pNodes} node, and all of the nodes in the -@code{csmaNodes} container. +@code{csmaNodes} container to cover all of the nodes in the simulation. Just as in the @code{first.cc} example script, we are going to use the @code{Ipv4AddressHelper} to assign IP addresses to our device interfaces. @@ -206,14 +206,14 @@ two point-to-point devices. @end verbatim Recall that we save the created interfaces in a container to make it easy to -pull out addressing information later. +pull out addressing information later for use in setting up the applications. -We then need to assign IP addresses to our CSMA device interfaces. The +We now need to assign IP addresses to our CSMA device interfaces. The operation works just as it did for the point-to-point case, except we now are performing the operation on a container that has a variable number of -CSMA devices --- remember we made that number changeable by command line -argument. So the CSMA devices will be associated with IP addresses from -network number 10.1.2.0 in this case. +CSMA devices --- remember we made the number of CSMA devices changeable by +command line argument. The CSMA devices will be associated with IP addresses +from network number 10.1.2.0 in this case, as seen below. @verbatim address.SetBase ("10.1.2.0", "255.255.255.0"); @@ -221,14 +221,13 @@ network number 10.1.2.0 in this case. csmaInterfaces = address.Assign (csmaDevices); @end verbatim -Now, we have a topology built, but we need applications. This section is +Now we have a topology built, but we need applications. This section is going to be fundamentally similar to the applications section of @code{first.cc} but we are going to instantiate the server on one of the nodes that has a CSMA node and the client on the node having only a point-to-point device. -You should completely understand the code for setting up the server since we -have seen this before. +First, we set up the echo server. @verbatim ApplicationContainer serverApps = echoServer.Install (csmaNodes.Get (nCsma)); @@ -237,17 +236,18 @@ have seen this before. @end verbatim Recall that the @code{csmaNodes NodeContainer} contains one of the -nodes created for the point-to-point network and @code{nCsma} extra nodes. -What we want to get is the last of the ``extra'' nodes. The zeroth entry of +nodes created for the point-to-point network and @code{nCsma} ``extra'' nodes. +What we want to get at is the last of the ``extra'' nodes. The zeroth entry of the @code{csmaNodes} container will the the point-to-point node. The easy way to think of this, then, is if we create one ``extra'' CSMA node, then it -will be be at index one of the @code{csmaNodes} container and, by induction, +will be be at index one of the @code{csmaNodes} container. By induction, if we create @code{nCsma} ``extra'' nodes the last one will be at index -@code{nCsma}. You see this exhibited in the first line of code. +@code{nCsma}. You see this exhibited in the @code{Get} of the first line of +code. The client application is set up exactly as we did in the @code{first.cc} -example script. We point the client to the server we set up on the last of -the ``extra'' CSMA nodes and install the client onto the point-to-point node +example script. We point the client to the server we just set up on the last +of the ``extra'' CSMA nodes and install the client onto the point-to-point node that is not associated with any CSMA device. @verbatim @@ -263,16 +263,17 @@ that is not associated with any CSMA device. @end verbatim Since we have actually built an internetwork here, we need some form of -internetwork routing. Ns-3 provides what we call a global route manager to -set up the routing tables on nodes. This route manager has a global function - that runs though the nodes created for the simulation and does the hard work -of setting up routing for you. +internetwork routing. @command{Ns-3} provides what we call a global route +manager to set up the routing tables on nodes. This route manager has a +global function that runs though the nodes created for the simulation and does +the hard work of setting up routing for you. Basically, what happens is that each node behaves as if it were an OSPF router -that communicates instantly and magically with all other routers. Each node -generates link advertisements and communicates them directly to a global route - manager, which uses this global information to construct the routing tables -for each node. Setting up this form of routing is a one-liner: +that communicates instantly and magically with all other routers behind the +scenes. Each node generates link advertisements and communicates them +directly to a global route manager which uses this global information to +construct the routing tables for each node. Setting up this form of routing +is a one-liner: @verbatim GlobalRouteManager::PopulateRoutingTables (); @@ -294,7 +295,7 @@ tracing with the point-to-point helper. @end verbatim In order to run this example, you have to copy the @code{second.cc} example -script into the scratch directory and use waf to build just as you did with +script into the scratch directory and use Waf to build just as you did with the @code{first.cc} example. If you are in the top-level directory of the repository you would type, @@ -304,7 +305,7 @@ repository you would type, ./waf --run scratch/second @end verbatim -Since we have set up the UDP echo applications just as we did in the +Since we have set up the UDP echo applications to log just as we did in the @code{first.cc} script, you will see similar output. @verbatim @@ -336,14 +337,14 @@ trace files: @end verbatim Let's take a moment to look at the naming of these files. They all have the -same form --- @code{--.pcap}. For example, the first file +same form, @code{--.pcap}. For example, the first file in the listing is @code{second-0-0.pcap} which is the pcap trace from node -zero, device zero. There are no other devices on node zero so this is the +zero - device zero. There are no other devices on node zero so this is the only trace from that node. Now look at @code{second-1-0.pcap} and @code{second-1-1.pcap}. The former is the pcap trace for device zero on node one and the latter is the trace file -for device one on node one. If you refer back to the topology cartoon at +for device one on node one. If you refer back to the topology illustrration at the start of the section, you will see that node one is the node that has both a point-to-point device and a CSMA device, so we should expect two pcap traces for that node. @@ -360,12 +361,11 @@ tcpdump of the trace file for the leftmost point-to-point node --- node zero. @end verbatim The first line of the dump indicates that the link type is PPP (point-to-point) -which we should expect. You then see the echo packet leaving node zero on -via the device associated with IP address 10.1.1.1 headed for IP address -10.1.2.4 (the rightmost CSMA node). - -This packet will move over the point-to-point link and be received by the -point-to-point net device on node one. Let's take a look: +which we expect. You then see the echo packet leaving node zero via the +device associated with IP address 10.1.1.1 headed for IP address +10.1.2.4 (the rightmost CSMA node). This packet will move over the +point-to-point link and be received by the point-to-point net device on node +one. Let's take a look: @verbatim ~/repos/ns-3-dev > tcpdump -r second-1-0.pcap -nn -tt @@ -427,8 +427,8 @@ the ARP exchange we just explained. The third packet is the echo packet being delivered to its final destination. The echo server turns the packet around and needs to send it back to the echo -cleint on 10.1.1.1 but it knows that this address is on another network that -it reaches via IP address 10.1.2.1. This is because we initialized the global +client on 10.1.1.1 but it knows that this address is on another network that +it reaches via IP address 10.1.2.1. This is because we initialized global routing and it has figured all of this out for us. But, the echo server node doesn't know the MAC address of the first CSMA node, so it has to ARP for it just like the first CSMA node had to do. We leave it as an exercise for you @@ -494,9 +494,11 @@ One way to get a node number to pass to the helper is to figure this number out ``manually.'' If you take a look at the network topology illustration at the beginning of the file, you can see that the last CSMA node is going to be node number code{nCsma + 1}. This can become annoyingly difficult in larger -simulations. An alternate way, which we use here, is to realize that the -@code{NodeContainer}s contain pointers to ns-3 @code{Node} Objects. The -@code{Node} Object has a method called @code{GetId} which will return that +simulations. + +An alternate way, which we use here, is to realize that the +@code{NodeContainer}s contain pointers to @command{ns-3} @code{Node} Objects. +The @code{Node} Object has a method called @code{GetId} which will return that node's ID. Let's go take a look at the Doxygen for the @code{Node} and locate that method, which is further down in the code than we've seen so far. @@ -538,22 +540,6 @@ file @code{second-0-0.pcap} is the ``leftmost'' point-to-point device which is the echo packet source. The file @code{second-101-0.pcap} corresponds to the rightmost CSMA device which is where the echo server resides. - - - - - - - - - - - - -@menu -* Building a Wireless Network Topology -@end menu - @c ======================================================================== @c Building a Wireless Network Topology @c ======================================================================== @@ -562,11 +548,11 @@ rightmost CSMA device which is where the echo server resides. @cindex topology @cindex wireless network topology -In this section we are going to further expand our knowledge of ns-3 network -devices and channels to cover an example of a wireless network. Ns-3 provides -a set of 802.11 models that attempt to provide an accurate MAC-level -implementation of the 802.11 specification and a ``not-so-slow'' -PHY-level model of the 802.11a specification. +In this section we are going to further expand our knowledge of @command{ns-3} +network devices and channels to cover an example of a wireless network. +@command{Ns-3} provides a set of 802.11 models that attempt to provide an +accurate MAC-level implementation of the 802.11 specification and a +``not-so-slow'' PHY-level model of the 802.11a specification. Just as we have seen both point-to-point and CSMA topology helper objects when constructing point-to-point topologies, we will see equivalent @code{Wifi} @@ -576,38 +562,37 @@ helpers should look quite familiar to you. We provide an example script in our @code{examples} directory. This script builds on the @code{second.cc} script and adds a Wifi network. Go ahead and open @code{examples/third.cc} in your favorite editor. You will have already -seen enough ns-3 code to understand most of what is going on in this example, -but there are a few new things, so we will go over the entire script and -examine some of the output. +seen enough @command{ns-3} code to understand most of what is going on in +this example, but there are a few new things, so we will go over the entire +script and examine some of the output. -Just as in the @code{second.cc} example (and in all ns-3 examples) the file -begins with an emacs mode line and some GPL boilerplate. +Just as in the @code{second.cc} example (and in all @command{ns-3} examples) +the file begins with an emacs mode line and some GPL boilerplate. Lets take a look at the ASCII art that shows the default network topology -constructed in the example. - -In this case, you can see that we are going to further extend our example -by hanging a wireless network off of the left side. Notice that this is the -default network topology since you can actually vary the number of nodes -created on the wired and wireless networks. Just as in the @code{sedond.cc} -case, if you @code{nCsma} will give you a number of ``extra'' CSMA nodes. -Similarly, you can set @code{nWifi} to control how many @code{STA} (station) -nodes are created in the simulation. There will always be one @code{AP} -(access point) node on the wireless network. By default there are -thee ``extra'' CSMA nodes and three wireless @code{STA} nodes as seen below: +constructed in the example. In this case, you can see that we are going to +further extend our example by hanging a wireless network off of the left side. +Notice that this is a default network topology since you can actually vary the +number of nodes created on the wired and wireless networks. Just as in the +@code{second.cc} script case, if you change @code{nCsma}, it will give you a +number of ``extra'' CSMA nodes. Similarly, you can set @code{nWifi} to +control how many @code{STA} (station) nodes are created in the simulation. +There will always be one @code{AP} (access point) node on the wireless +network. By default there are thee ``extra'' CSMA nodes and three wireless +@code{STA} nodes. The code begins by loading module include files just as was done in the @code{second.cc} example. There are a couple of new includes corresponding to the Wifi module and the mobility module which we will discuss below. @verbatim -#include ``ns3/core-module.h'' -#include ``ns3/simulator-module.h'' -#include ``ns3/node-module.h'' -#include ``ns3/helper-module.h'' -#include ``ns3/global-routing-module.h'' -#include ``ns3/wifi-module.h'' -#include ``ns3/mobility-module.h'' +#include "ns3/core-module.h" +#include "ns3/simulator-module.h" +#include "ns3/node-module.h" +#include "ns3/helper-module.h" +#include "ns3/global-routing-module.h" +#include "ns3/wifi-module.h" +#include "ns3/mobility-module.h" @end verbatim The network topology illustration follows: @@ -625,12 +610,12 @@ The network topology illustration follows: // LAN 10.1.2.0 @end verbatim -You can see that we are adding a new network device to the left side of the -point-to-point link that becomes the access point for the wireless network. -A number of wireless STA nodes are created to fill out the new 10.1.3.0 -network as shown on the far left side of the illustration. +You can see that we are adding a new network device to the node on the left +side of the point-to-point link that becomes the access point for the wireless +network. A number of wireless STA nodes are created to fill out the new +10.1.3.0 network as shown on the left side of the illustration. -After the illustration, the ns-3 namespace is @code{used} and a logging +After the illustration, the @code{ns-3} namespace is @code{used} and a logging component is defined. This should all be quite familiar by now. @verbatim @@ -659,8 +644,8 @@ of devices on the CSMA and Wifi networks via command line argument. uint32_t nCsma = 3; uint32_t nWifi = 3; CommandLine cmd; - cmd.AddValue (``nCsma'', ``Number of \"extra\" CSMA nodes/devices'', nCsma); - cmd.AddValue (``nWifi'', ``Number of wifi STA devices'', nWifi); + cmd.AddValue ("nCsma", "Number of \"extra\" CSMA nodes/devices", nCsma); + cmd.AddValue ("nWifi", "Number of wifi STA devices", nWifi); cmd.Parse (argc,argv); @end verbatim @@ -688,8 +673,7 @@ on the nodes and the channel between them. @end verbatim Next, we delare another @code{NodeContainer} to hold the nodes that will be -part of the bus (CSMA) network. First we just instantiate the container -object itself. +part of the bus (CSMA) network. @verbatim NodeContainer csmaNodes; @@ -703,12 +687,9 @@ that will get CSMA devices. The node in question is going to end up with a point-to-point device and a CSMA device. We then create a number of ``extra'' nodes that compose the remainder of the CSMA network. -We then instantiate a @code{NetDeviceContainer} to keep track of the -point-to-point net devices and we install devices on the point-to-point -nodes. - -The next piece of code creates and connects CSMA devices and channels as we -have previously seen. +We then instantiate a @code{CsmaHelper} and a @code{NetDeviceContainer} to +keep track of the CSMA net devices. Then we @code{Install} CSMA devices on +the selected nodes. @verbatim CsmaHelper csma; @@ -718,8 +699,8 @@ have previously seen. @end verbatim Next, we are going to create the nodes that will be part of the Wifi network. -We are going to create a number ``station'' nodes as specified by the command -line argument, and we are going to use the ``leftmost'' node of the +We are going to create a number of ``station'' nodes as specified by the +command line argument, and we are going to use the ``leftmost'' node of the point-to-point link as the node for the access point. @verbatim @@ -736,60 +717,60 @@ for a while. The next line of code you will see is: Ptr channel = CreateObject (); @end verbatim -Now, I'm not going to explain at this stage precisely what this all means, but -hopefully with a very short digression I can give you enough information so -that this makes sense. +Now, I'm not going to explain at this stage @emph{precisely} what this all +means, but hopefully with a very short digression I can give you enough +information so that this makes sense. -C++ is an object oriented programming language. Ns-3 extends the basic C++ -object model to implement a number of nifty features. We have seen the -@code{Attribute} system which is one of the major extensions we have +C++ is an object oriented programming language. @command{Ns-3} extends the +basic C++ object model to implement a number of nifty features. We have seen +the @code{Attribute} system which is one of the major extensions we have implemented. Another extension is to provide for relatively automatic memory -management. Like many systems, ns-3 creates a base class called @code{Object} -that provides our extensions ``for free'' to other classes that inherit from -our @code{class Object}. +management. Like many systems, @command{ns-3} creates a base class called +@code{Object} that provides our extensions ``for free'' to other classes that + inherit from our @code{class Object}. In the code snippet above, the right hand side of the expression is a call to a templated C++ function called @code{CreateObject}. The @emph{template parameter} inside the angle brackets basically tells the compiler what class it is we want to instantiate. Our system returns a @emph{smart pointer} to the object of the class that was created and assigns -it to the smart pointer called @code{channel} that is declared on the left +it to the smart pointer named @code{channel} that is declared on the left hand side of the assignment. -The ns-3 smart pointer is also template-based. Here you see that we declare -a smart pointer to a @code{WifiChannel} which is the type of object that was -created in the @code{CreateObject} call. The feature of immediate interest -here is that we never delete the underlying C++ object. It is handled -automatically for us. +The @command{ns-3} smart pointer is also template-based. Here you see that +we declare a smart pointer to a @code{WifiChannel} which is the type of object +that was created in the @code{CreateObject} call. The feature of immediate +interest here is that we are never going to have to delete the underlying C++ +object. It is handled automatically for us. Nice, eh? The idea to take away from this discussion is that this line of code creates -an ns-3 @code{Object} that will automatically bring you the benefits of the -ns-3 @code{Attribute} system we've seen previously. The resulting smart -pointer works with the @code{Object} to perform memory management automatically -for you. If you are interested in more details about low level ns-3 code and -exactly what it is doing, you are encouraged to explore the ns-3 manual and -our ``how-to'' documents. +an @command{ns-3} @code{Object} that will automatically bring you the benefits +of the @command{ns-3} @code{Attribute} system we've seen previously. The +resulting smart pointer works with the @code{Object} to perform memory +management automatically for you. If you are interested in more details about +low level ns-3 code and exactly what it is doing, you are encouraged to +explore the ns-3 manual and our ``how-to'' documents. Now, back to the example. The line of code above has created a wireless @code{Wifi} channel. This channel model requires that we create and attach other models that describe various behaviors. This provides an accomplished -user with the opportunity to change the way the wireless network behaves +user with even more opportunity to change the way the wireless network behaves without changing the core code. The first opportunity we have to change the behavior of the wireless network is by providing a propagation delay model. Again, I don't want to devolve this -tutorial into a manual on @code{Wifi}, but this model describes how the EM -signals are going to propagate. We are going to create the simplest model, -the @code{ConstantSpeedPropagationDelayModel} that, by default, has the -signals propagating at a constant speed --- that of the speed of light in a -vacuum. +tutorial into a manual on @code{Wifi}, but this model describes how the +electromagnetic signals are going to propagate. We are going to create the +simplest model, the @code{ConstantSpeedPropagationDelayModel} that, by default, +has the signals propagating at a constant speed --- that of the speed of light +in a vacuum. Recall that we created the @code{WifiChannel} and assigned it to a smart pointer. One of the features of a smart pointer is that you can use it just as you would a ``normal'' C++ pointer. The next line of code will create a @code{ConstantSpeedPropagationDelayModel} using the @code{CreateObject} template function and pass the resulting smart pointer -to the model as an unnamed parameter to the +to the chanel model as an unnamed parameter of the @code{WifiChannel SetPropagationDelayModel} method. @verbatim @@ -797,8 +778,8 @@ to the model as an unnamed parameter to the CreateObject ()); @end verbatim -The next lines of code use similar low-level ns-3 methods to create and set -a ``propagation loss model'' for the channel. +The next lines of code use similar low-level @command{ns-3} methods to create +and set a ``propagation loss model'' for the channel. @verbatim Ptr log = @@ -817,7 +798,7 @@ tutorial. You are encouraged to explore the Doxygen documentation of classes will find the documentation in the ``Classes'' tab of the Doxygen page. Now we will return to more familiar ground. We next create a @code{WifiHelper} -object and set two default atributes taht it will use when creating the actual +object and set two default atributes that it will use when creating the actual devices. @verbatim @@ -826,16 +807,16 @@ devices. wifi.SetRemoteStationManager ("ns3::ArfWifiManager"); @end verbatim -The @code{SetPhy} method tells the helper the type of physical layer class to -instantiate when building @code{Wifi} devices. In this case, it is asking -for physical layer models based on the YANS 802.11a model. Again, details -are avialable in Doxygen. +The @code{SetPhy} method tells the helper the type of physical layer class +we want to instantiate when building @code{Wifi} devices. In this case, it +is asking for physical layer models based on the YANS 802.11a model. Again, +details are avialable in Doxygen. The @code{SetRemoteStationManager} method tells the helper the type of -rate control algorithm. Here, it is asking the helper to use the AARF +rate control algorithm to use. Here, it is asking the helper to use the AARF algorithm --- details are, of course, avialable in Doxygen. -Just as we could vary attributes describing the physical layer, we can do the +Just as we can vary attributes describing the physical layer, we can do the same for the MAC layer. @verbatim @@ -848,21 +829,22 @@ same for the MAC layer. This code first creates an 802.11 service set identifier (SSID) object that will be used to set the value of the ``Ssid'' @code{Attribute} of the MAC layer implementation. The particular kind of MAC layer is specified by -Attribute as being of the "ns3::NqstaWifiMac" type. This means that the MAC -will use a ``non-QoS station'' (nqsta) state machine. Finally, the +@code{Attribute} as being of the "ns3::NqstaWifiMac" type. This means that +the MAC will use a ``non-QoS station'' (nqsta) state machine. Finally, the ``ActiveProbing'' attribute is set to false. This means that probe requests will not be sent by MACs created by this helper. Again, for the next lines of code we are back on familiar ground. This code will @code{Install} Wifi net devices on the nodes we have created as STA nodes -and will tie them to the @code{WifiChannel} we created manually. +and will tie them to the @code{WifiChannel} we created manually by passing +in the @code{channel} to the @code{Install} method. @verbatim NetDeviceContainer staDevices; staDevices = wifi.Install (wifiStaNodes, channel); @end verbatim -We have now configured Wifi for all of our STA nodes, and now we need to +We have configured Wifi for all of our STA nodes, and now we need to configure the AP (access point) node. We begin this process by changing the default @code{Attributes} to reflect the requirements of the AP. @@ -876,9 +858,10 @@ the default @code{Attributes} to reflect the requirements of the AP. In this case, the @code{WifiHelper} is going to create MAC layers of the ``ns3::NqapWifiMac'' (Non-Qos Access Point) type. We set the ``BeaconGeneration'' attribute to true and also set an interval between -beacons. +beacons of 2.5 seconds. -The next lines create the single AP and connect it to the channel. +The next lines create the single AP and connect it to the channel in a +familiar way. @verbatim NetDeviceContainer apDevices; @@ -887,8 +870,7 @@ The next lines create the single AP and connect it to the channel. Now, we are going to add mobility models. We want the STA nodes to be mobile, wandering around inside a bounding box and we want to make the AP node -stationary. We use a @code{MobilityHelper} to make this easy for us. - +stationary. We use the @code{MobilityHelper} to make this easy for us. First, we instantiate a @code{MobilityHelper} obejct and set some attributes controlling the ``position allocator'' functionality. @@ -910,7 +892,8 @@ place the STA nodes. Feel free to explore the Doxygen for class We have aranged our nodes on an initial grid, but now we need to tell them how to move. We choose the @code{RandomWalk2dMobilityModel} which has the -nodes move in a random direction at a random speed around the bounding box. +nodes move in a random direction at a random speed around inside a bounding +box. @verbatim mobility.SetMobilityModel ("ns3::RandomWalk2dMobilityModel", @@ -929,13 +912,14 @@ We accomplish this by setting the mobility model for this node to be the @code{ns3::StaticMobilityModel}: @verbatim - mobility.SetMobilityModel (``ns3::StaticMobilityModel''); + mobility.SetMobilityModel ("ns3::StaticMobilityModel"); mobility.Install (wifiApNode); @end verbatim We now have our nodes, devices and channels created, and mobility models chosen for the Wifi nodes, but we have no protocol stacks present. Just as -previously, we will use the @code{InternetStackHelper} to install these stacks. +we have done previously many times, we will use the @code{InternetStackHelper} +to install these stacks. @verbatim InternetStackHelper stack; @@ -967,24 +951,8 @@ both the STA devices and the AP on the wireless network. address.Assign (apDevices); @end verbatim -Recall that we save the created interfaces in a container to make it easy to -pull out addressing information later. - -We then need to assign IP addresses to our CSMA device interfaces. The -operation works just as it did for the point-to-point case, except we now -are performing the operation on a container that has a variable number of -CSMA devices --- remember we made that number changeable by command line -argument. So the CSMA devices will be associated with IP addresses from -network number 10.1.2.0 in this case. - -@verbatim - address.SetBase ("10.1.2.0", "255.255.255.0"); - Ipv4InterfaceContainer csmaInterfaces; - csmaInterfaces = address.Assign (csmaDevices); -@end verbatim - We put the echo server on the ``rightmost'' node in the illustration at the -start of the file: +start of the file. We have done this before. @verbatim UdpEchoServerHelper echoServer; @@ -996,14 +964,14 @@ start of the file: @end verbatim And we put the echo client on the last STA node we created, pointing it to -the server on the CSMA network. +the server on the CSMA network. We have also seen similar operations before. @verbatim UdpEchoClientHelper echoClient; echoClient.SetRemote (csmaInterfaces.GetAddress (nCsma), 9); - echoClient.SetAppAttribute (``MaxPackets'', UintegerValue (1)); - echoClient.SetAppAttribute (``Interval'', TimeValue (Seconds (1.))); - echoClient.SetAppAttribute (``PacketSize'', UintegerValue (1024)); + echoClient.SetAppAttribute ("MaxPackets", UintegerValue (1)); + echoClient.SetAppAttribute ("Interval", TimeValue (Seconds (1.))); + echoClient.SetAppAttribute ("PacketSize", UintegerValue (1024)); ApplicationContainer clientApps = echoClient.Install (wifiStaNodes.Get (nWifi - 1)); @@ -1011,7 +979,8 @@ the server on the CSMA network. clientApps.Stop (Seconds (10.0)); @end verbatim -Since we have built an internetwork here, we need enable internetwork routing. +Since we have built an internetwork here, we need enable internetwork routing +just as we did in the @code{second.cc} example script. @verbatim GlobalRouteManager::PopulateRoutingTables (); @@ -1022,7 +991,8 @@ created will never ``naturally'' stop. This is because we asked the wireless access point to generate beacons. It will generate beacons forever, so we must tell the simulator to stop even though it may have beacon generation events scheduled. The following line of code tells the simulator to stop so that -we don't simulate beacons forever. +we don't simulate beacons forever and enter what is essentially an endless +loop. @verbatim Simulator::Stop (Seconds (10.0)); @@ -1030,17 +1000,17 @@ we don't simulate beacons forever. We use the same trick as in the @code{second.cc} script to only generate pcap traces from the nodes we find interesting. Note that we use the same -``formula'' to get pcap tracing enabled on Wifi devices: +``formula'' to get pcap tracing enabled on Wifi devices as we did on the +CSMA and point-to-point devices. @verbatim - WifiHelper::EnablePcap (``third'', + WifiHelper::EnablePcap ("third", wifiStaNodes.Get (nWifi - 1)->GetId (), 0); - CsmaHelper::EnablePcap (``third'', + CsmaHelper::EnablePcap ("third", csmaNodes.Get (nCsma)->GetId (), 0); @end verbatim -Finally, we actually run the simulation call the @code{Simulator::Destroy} -method to clean up and then exit the program. +Finally, we actually run the simulation, clean up and then exit the program. @verbatim Simulator::Run (); @@ -1050,7 +1020,7 @@ method to clean up and then exit the program. @end verbatim In order to run this example, you have to copy the @code{third.cc} example -script into the scratch directory and use waf to build just as you did with +script into the scratch directory and use Waf to build just as you did with the @code{second.cc} example. If you are in the top-level directory of the repository you would type, @@ -1074,7 +1044,7 @@ Since we have set up the UDP echo applications just as we did in the @end verbatim Recall that the first message, @code{Sent 1024 bytes to 10.1.2.4} is the -UDP echo client sending a packet to the server. In this case, the server +UDP echo client sending a packet to the server. In this case, the client is on the wireless network (10.1.3.0). The second message, @code{Received 1024 bytes from 10.1.3.3}, is from the UDP echo server, generated when it receives the echo packet. The final message, @@ -1090,9 +1060,9 @@ files: ~/repos/ns-3-dev > @end verbatim -The file ``third-4-0.pcap'' corresponds to node four, device zero. This is -the CSMA network node that acted as the echo server. Take a look at the -tcpdump for this device: +The file ``third-4-0.pcap'' corresponds to the pcap trace for node four - +device zero. This is the CSMA network node that acted as the echo server. +Take a look at the tcpdump for this device: @verbatim ~/repos/ns-3-dev > tcpdump -r third-4-0.pcap -nn -tt @@ -1106,8 +1076,8 @@ tcpdump for this device: ~/repos/ns-3-dev > @end verbatim -This should be easily understood. If you've forgotten, go back and look at -the discussion in @code{second.cc}. This is the same sequence. +This should be familiar and easily understood. If you've forgotten, go back +and look at the discussion in @code{second.cc}. This is the same sequence. Now, take a look at the other trace file, ``third-7-0.pcap.'' This is the trace file for the wireless STA node that acts as the echo client. @@ -1152,17 +1122,18 @@ it as an exercise to parse the dump and trace packets across the internetwork. Now, we spent a lot of time setting up mobility models for the wireless network and so it would be a shame to finish up without even showing that the STA -nodes are actually moving. Let's do this by hooking into the +nodes are actually moving around. Let's do this by hooking into the @code{MobilityModel} course change trace source. This is usually considered a fairly advanced topic, but let's just go for it. -As mentioned in the Tweaking Ns-3 section, the ns-3 tracing system is divided -into trace sources and trace sinks, and we provide functions to connect the -two. We will use the mobility model predefined course change trace source -to originate the trace events. We will need to write a trace sink to connect -to that source that will display some pretty information for us. It's really -quite simple. Just before the main program of the @code{scratch/third.cc} -script, add the following function: +As mentioned in the Tweaking Ns-3 section, the @command{ns-3} tracing system +is divided into trace sources and trace sinks, and we provide functions to +connect the two. We will use the mobility model predefined course change +trace source to originate the trace events. We will need to write a trace +sink to connect to that source that will display some pretty information for +us. Despite its reputation as being difficult, it's really quite simple. +Just before the main program of the @code{scratch/third.cc} script, add the +following function: @verbatim void @@ -1174,7 +1145,8 @@ script, add the following function: } @end verbatim -This code just unconditionally logs the x and y position of the node. We are +This code just unconditionally pulls the position information from the +mobility model and logs the x and y position of the node. We are going to arrange for this function to be called every time the wireless node with the echo client changes its position. We do this using the @code{Config::Connect} function. Add the following lines of code to the @@ -1183,28 +1155,31 @@ script just before the @code{Simulator::Run} call. @verbatim std::ostringstream oss; oss << - ``/NodeList/'' << wifiStaNodes.Get (nWifi - 1)->GetId () << - ``/$ns3::MobilityModel/CourseChange''; + "/NodeList/" << wifiStaNodes.Get (nWifi - 1)->GetId () << + "/$ns3::MobilityModel/CourseChange"; Config::Connect (oss.str (), MakeCallback (&CourseChange)); @end verbatim What we do here is to create a string containing the tracing namespace path -to the event we want to connect. In the case of the default number of CSMA -and wireless nodes, this turns out to be, +to the event we want to connect. We have to figure out which node it is we +want to connect to. In the case of the default number of CSMA and wireless +nodes, this turns out to be node seven and the tracing namespace path to the +mobility model is, @verbatim /NodeList/7/$ns3::MobilityModel/CourseChange @end verbatim -From the discussion in the tracing section, you may recall that references the -seventh node in the NodeList and looks for what is called an aggregated object -of type @code{ns3::MobilityModel}. Then we hook into the ``CourseChange'' -event of that model. We actually connect the trace source in node seven with -our trace sink --- the function we just added called @code{CourseChange} --- -by calling @code{Config::Connect}. Once this is done, every course change -event on node seven will be hooked into our trace sink, which will print out -the new position. +Based on the discussion in the tracing section, you may easily infer that +this string references the seventh node in the NodeList and looks for what is +called an aggregated object of type @code{ns3::MobilityModel}. The dollar +sign prefix implies that the MobilityModel is aggregated to node seven. The +last component of the path means that we are hooking into the ``CourseChange'' +event of that model. We have made a connection between the trace source in +node seven with our trace sink by calling @code{Config::Connect}. Once this +is done, every course change event on node seven will be hooked into our trace +sink, which will in turn print out the new position. If you now run the simulation, you will see the course changes displayed as they happen. @@ -1247,16 +1222,16 @@ they happen. ~/repos/ns-3-dev > @end verbatim -If you are feeling brave, there is a list of all trace sources in the ns-3 -Doxygen which you can find in the ``NS-3 Modules'' section. Under the -``core'' section, you will find a link to ``The list of all trace sources.'' -You will find a list of all of the trace sources that you can hook to. You -may find it interesting to try and hook some of these traces yourself. -Additionally in the ``NS-3 Modules'' documentation, there is a link to -``The list of all attributes.'' You can set the default value of any of these -atributes via the command line as we have previously discussed. +If you are feeling brave, there is a list of all trace sources in the +@command{ns-3} Doxygen which you can find in the ``NS-3 Modules'' section. +Under the ``core'' section, you will find a link to ``The list of all trace +sources.'' In that link you will find a list of all of the trace sources that + you can hook to. You may find it interesting to try and hook some of these +traces yourself. Additionally in the ``NS-3 Modules'' documentation, there is +a link to ``The list of all attributes.'' You can set the default value of +any of these atributes via the command line as we have previously discussed. -We have just scratched the surface of ns-3 in this tutorial, but we hope we -have covered enough to get you started doing useful work. +We have just scratched the surface of @command{ns-3} in this tutorial, but we +hope we have covered enough to get you started doing useful work. --- The ns-3 development team. +-- The @command{ns-3} development team. diff --git a/doc/tutorial/tweaking.texi b/doc/tutorial/tweaking.texi index 600aed662..a476e0827 100644 --- a/doc/tutorial/tweaking.texi +++ b/doc/tutorial/tweaking.texi @@ -401,7 +401,7 @@ message, @subsection Overriding Default Attributes @cindex command line arguments -Another way you can change how @command}ns-3} scripts behave without editing +Another way you can change how @command{ns-3} scripts behave without editing and building is via @emph{command line arguments.} We provide a mechanism to parse command line arguments and automatically set local and global variables based on those arguments. From 1d5803e8f30d4c28a2520ff40f7a601d86ff43d6 Mon Sep 17 00:00:00 2001 From: Craig Dowell Date: Sun, 29 Jun 2008 23:14:16 -0700 Subject: [PATCH 082/495] minor tweaks for menus on tutorial --- doc/tutorial/conceptual-overview.texi | 2 +- doc/tutorial/tutorial.texi | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/doc/tutorial/conceptual-overview.texi b/doc/tutorial/conceptual-overview.texi index d060ad176..5054d7eba 100644 --- a/doc/tutorial/conceptual-overview.texi +++ b/doc/tutorial/conceptual-overview.texi @@ -11,7 +11,7 @@ @menu * Key Abstractions:: -* A First ns-3 script:: +* A First ns-3 Script:: @end menu The first thing we need to do before actually starting to look at or write diff --git a/doc/tutorial/tutorial.texi b/doc/tutorial/tutorial.texi index bc1ea2029..fb205f91e 100644 --- a/doc/tutorial/tutorial.texi +++ b/doc/tutorial/tutorial.texi @@ -83,7 +83,6 @@ see @uref{http://www.nsnam.org/docs/tutorial.pdf}. * Resources:: * Getting Started:: * Conceptual Overview:: -* A First ns-3 Script:: * Tweaking ns-3:: * Building Topologies:: @end menu From 26972f3917cb7dd949e1b157f103c322b33b3f47 Mon Sep 17 00:00:00 2001 From: Craig Dowell Date: Sun, 29 Jun 2008 23:25:32 -0700 Subject: [PATCH 083/495] address helpful tutorial comments by reviewers --- doc/tutorial/conceptual-overview.texi | 4 ++-- doc/tutorial/tweaking.texi | 12 ++++++------ 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/doc/tutorial/conceptual-overview.texi b/doc/tutorial/conceptual-overview.texi index 5054d7eba..2c243708a 100644 --- a/doc/tutorial/conceptual-overview.texi +++ b/doc/tutorial/conceptual-overview.texi @@ -201,7 +201,7 @@ you are working with our code. All of the development team have done so. The emacs mode line above makes it easier to get the formatting correct if you use the emacs editor. -The @command{ns-3} simulator is licentsed using the GNU General Public +The @command{ns-3} simulator is licensed using the GNU General Public License. You will see the appropriate GNU legalese at the head of every file in the @command{ns-3} distribution. Often you will see a copyright notice for one of the institutions involved in the @code{ns-3} project and an author @@ -451,7 +451,7 @@ creates. @subsubsection NetDeviceContainer At this point in the script, we have a @code{NodeContainer} that contains two nodes. We have a @code{PointToPointHelper} that is primed and ready to -make @code{PointToPointNetDevices} and wire @code{PoiintToPointChannel} objects +make @code{PointToPointNetDevices} and wire @code{PointToPointChannel} objects between them. Just as we used the @code{NodeContainer} topology helper object to create the @code{Node}s for our simulation, we will ask the @code{PointToPointHelper} to do the work involved in creating, configuring and diff --git a/doc/tutorial/tweaking.texi b/doc/tutorial/tweaking.texi index a476e0827..510f5ee42 100644 --- a/doc/tutorial/tweaking.texi +++ b/doc/tutorial/tweaking.texi @@ -747,12 +747,12 @@ extending the tracing namespace and creating new tracing sources. @cindex tracing @cindex ASCII tracing @subsection ASCII Tracing -@command{Ns-3} provides an ASCII trace helper that is a wrapper around the -low-level tracing system. This helper lets you configure some useful and -easily understood packet traces easily. The output of a trace of a simulation -run is an ASCII file --- thus the name. For those familiar with -@command{ns-2} output, this type of trace is analogous to the @command{out.tr} -generated by many scripts. +@command{Ns-3} provides functionality wrapping the low-level tracing system +to help you with the details involved in configuring some easily +understood packe traces. If you enable this functionality, you will see +output of a trace of a simulation appear in an ASCII file --- thus the name. +For those familiar with @command{ns-2} output, this type of trace is +analogous to the @command{out.tr} generated by many scripts. @cindex tracing packets Let's just jump right in and add some ASCII tracing output to our From 03975f8102f1843b33920c612bcb25e35576dc1b Mon Sep 17 00:00:00 2001 From: Craig Dowell Date: Mon, 30 Jun 2008 10:23:04 -0700 Subject: [PATCH 084/495] remove section in tutorial, move browsing part to where it makes more sense. --- doc/tutorial/conceptual-overview.texi | 53 ++++++++++++++++++ doc/tutorial/introduction.texi | 77 +-------------------------- 2 files changed, 54 insertions(+), 76 deletions(-) diff --git a/doc/tutorial/conceptual-overview.texi b/doc/tutorial/conceptual-overview.texi index 2c243708a..0b3a3592e 100644 --- a/doc/tutorial/conceptual-overview.texi +++ b/doc/tutorial/conceptual-overview.texi @@ -738,3 +738,56 @@ indicate that it has sent one 1024 byte packet to the Echo Server on it has received the 1024 bytes from 10.1.1.1. The echo server silently echoes the packet and you see the echo client log that it has received its packet back from the server. + +@c ======================================================================== +@c Browsing ns-3 +@c ======================================================================== + +@node Ns-3 Source Code +@section Ns-3 Source Code + +Now that you have used some of the @command{ns-3} helpers you may want to +have a look at some of the source code that implements that functionality. +The most recent code can be browsed on our web server at the following link: +@uref{http://code.nsnam.org/?sort=lastchange}. If you click on the bold +repository names on the left of the page, you will see @emph{changelogs} for +these repositories, and links to the @emph{manifest}. From the manifest +links, one can browse the source tree. + +The top-level directory for one of our @emph{repositories} will look +something like: +@verbatim +drwxr-xr-x [up] +drwxr-xr-x doc manifest +drwxr-xr-x examples manifest +drwxr-xr-x ns3 manifest +drwxr-xr-x regression manifest +drwxr-xr-x samples manifest +drwxr-xr-x scratch manifest +drwxr-xr-x src manifest +drwxr-xr-x tutorial manifest +drwxr-xr-x utils manifest +-rw-r--r-- 135 .hgignore file | revisions | annotate +-rw-r--r-- 891 .hgtags file | revisions | annotate +-rw-r--r-- 441 AUTHORS file | revisions | annotate +-rw-r--r-- 17987 LICENSE file | revisions | annotate +-rw-r--r-- 4948 README file | revisions | annotate +-rw-r--r-- 4917 RELEASE_NOTES file | revisions | annotate +-rw-r--r-- 7 VERSION file | revisions | annotate +-rwxr-xr-x 99143 waf file | revisions | annotate +-rwxr-xr-x 28 waf.bat file | revisions | annotate +-rw-r--r-- 30584 wscript file | revisions | annotate +@end verbatim + +The source code is mainly in the @code{src} directory. You can view source +code by clicking on the @code{manifest} link to the right of the directory +name. If you click on the @code{manifest} link to the right of the src +directory you will find a subdirectory. If you click on the @code{manifest} +link next to the @code{core} subdirectory in under @code{src}, you will find +a list of files. The first file you will find is @code{assert.h}. If you +click on the @code{file} link, you will be sent to the source file for +@code{assert.h}. + +Our example scripts are in the @code{examples} directory. The source code for +the helpers we have used in this chapter can be found in the +@code{src/helpers} directory. diff --git a/doc/tutorial/introduction.texi b/doc/tutorial/introduction.texi index 8793c5881..d15653da1 100644 --- a/doc/tutorial/introduction.texi +++ b/doc/tutorial/introduction.texi @@ -107,89 +107,14 @@ The tutorial assumes that new users might initially follow a path such as the following: @itemize @bullet -@item Browse the source code and documentation, to get a feel for -the simulator and what it might be like to use; @item Try to download and build a copy; -@item Try to run a few sample programs, and perhaps change some configurations; +@item Try to run a few sample programs; @item Look at simulation output, and try to adjust it. @end itemize As a result, we have tried to organize the tutorial along the above broad sequences of events. -@c ======================================================================== -@c Browsing ns-3 -@c ======================================================================== - -@node Browsing ns-3 -@chapter Browsing ns-3 - -@menu -* Source Code:: -* Doxygen:: -* Other Documentation:: -@end menu - -@node Source Code -@section Source Code - -The most recent code can be browsed on our web server at the following link: -@uref{http://code.nsnam.org/?sort=lastchange}. If you click on the bold -repository names on the left of the page, you will see @emph{changelogs} for -these repositories, and links to the @emph{manifest}. From the manifest -links, one can browse the source tree. - -The top-level directory for one of our @emph{repositories} will look -something like: -@verbatim -drwxr-xr-x [up] -drwxr-xr-x doc manifest -drwxr-xr-x examples manifest -drwxr-xr-x ns3 manifest -drwxr-xr-x regression manifest -drwxr-xr-x samples manifest -drwxr-xr-x scratch manifest -drwxr-xr-x src manifest -drwxr-xr-x tutorial manifest -drwxr-xr-x utils manifest --rw-r--r-- 135 .hgignore file | revisions | annotate --rw-r--r-- 891 .hgtags file | revisions | annotate --rw-r--r-- 441 AUTHORS file | revisions | annotate --rw-r--r-- 17987 LICENSE file | revisions | annotate --rw-r--r-- 4948 README file | revisions | annotate --rw-r--r-- 4917 RELEASE_NOTES file | revisions | annotate --rw-r--r-- 7 VERSION file | revisions | annotate --rwxr-xr-x 99143 waf file | revisions | annotate --rwxr-xr-x 28 waf.bat file | revisions | annotate --rw-r--r-- 30584 wscript file | revisions | annotate -@end verbatim - -The source code is mainly in the @code{src} directory. You can view source -code by clicking on the @code{manifest} link to the right of the directory -name. If you click on the @code{manifest} link to the right of the src -directory you will find a subdirectory. If you click on the @code{manifest} -link next to the @code{core} subdirectory in under @code{src}, you will find -a list of files. The first file you will find is @code{assert.h}. If you -click on the @code{file} link, you will be sent to the source file for -@code{assert.h}. - -Example scripts are in the @code{examples} directory. The @code{examples} -directory is a good place to start browsing the code. - -@node Doxygen -@section Doxygen - -We document all of our APIs using @uref{http://www.stack.nl/~dimitri/doxygen/,,Doxygen}. Current builds of this documentation are available at: -@uref{http://www.nsnam.org/doxygen/index.html}, which are worth an initial -look. - -@node Other Documentation -@section Other Documentation - -We provide a large amount of documentation regarding the various components -of @command{ns-3} on our website. See: -@uref{http://www.nsnam.org/documents.html}. - @c ======================================================================== @c Resources @c ======================================================================== From 8a6ed9603ee91872fff8e17cc47393774b96073d Mon Sep 17 00:00:00 2001 From: Craig Dowell Date: Mon, 30 Jun 2008 10:25:46 -0700 Subject: [PATCH 085/495] remote browsing from tutorial menus --- doc/tutorial/tutorial.texi | 1 - 1 file changed, 1 deletion(-) diff --git a/doc/tutorial/tutorial.texi b/doc/tutorial/tutorial.texi index fb205f91e..f3517b3d6 100644 --- a/doc/tutorial/tutorial.texi +++ b/doc/tutorial/tutorial.texi @@ -79,7 +79,6 @@ see @uref{http://www.nsnam.org/docs/tutorial.pdf}. @menu * Introduction:: -* Browsing ns-3:: * Resources:: * Getting Started:: * Conceptual Overview:: From bf513e45d2422dbcecd45f293c41fc75d50d831f Mon Sep 17 00:00:00 2001 From: "Gustavo J. A. M. Carneiro" Date: Mon, 30 Jun 2008 19:25:58 +0100 Subject: [PATCH 086/495] Sketching a new promiscuous mode protocol handlers API; Netdevices implementation missing, though. --- src/devices/csma/csma-net-device.cc | 6 ++ src/devices/csma/csma-net-device.h | 1 + .../point-to-point-net-device.cc | 6 ++ .../point-to-point-net-device.h | 1 + src/devices/wifi/wifi-net-device.cc | 6 ++ src/devices/wifi/wifi-net-device.h | 1 + src/node/net-device.h | 24 ++++++++ src/node/node.cc | 55 +++++++++++++++++++ src/node/node.h | 40 ++++++++++++++ src/node/simple-net-device.cc | 4 ++ src/node/simple-net-device.h | 1 + 11 files changed, 145 insertions(+) diff --git a/src/devices/csma/csma-net-device.cc b/src/devices/csma/csma-net-device.cc index 09734519b..05dde61b3 100644 --- a/src/devices/csma/csma-net-device.cc +++ b/src/devices/csma/csma-net-device.cc @@ -806,4 +806,10 @@ CsmaNetDevice::SetReceiveCallback (NetDevice::ReceiveCallback cb) m_rxCallback = cb; } +void +CsmaNetDevice::SetPromiscuousReceiveCallback (NetDevice::PromiscuousReceiveCallback cb) +{ + // TODO +} + } // namespace ns3 diff --git a/src/devices/csma/csma-net-device.h b/src/devices/csma/csma-net-device.h index 440206d23..f283c9c47 100644 --- a/src/devices/csma/csma-net-device.h +++ b/src/devices/csma/csma-net-device.h @@ -279,6 +279,7 @@ public: * \param cb The callback. */ virtual void SetReceiveCallback (NetDevice::ReceiveCallback cb); + virtual void SetPromiscuousReceiveCallback (PromiscuousReceiveCallback cb); protected: /** diff --git a/src/devices/point-to-point/point-to-point-net-device.cc b/src/devices/point-to-point/point-to-point-net-device.cc index 6e3ea3f5a..d7100177d 100644 --- a/src/devices/point-to-point/point-to-point-net-device.cc +++ b/src/devices/point-to-point/point-to-point-net-device.cc @@ -458,4 +458,10 @@ PointToPointNetDevice::SetReceiveCallback (NetDevice::ReceiveCallback cb) m_rxCallback = cb; } +void +PointToPointNetDevice::SetPromiscuousReceiveCallback (NetDevice::PromiscuousReceiveCallback cb) +{ + // TODO +} + } // namespace ns3 diff --git a/src/devices/point-to-point/point-to-point-net-device.h b/src/devices/point-to-point/point-to-point-net-device.h index 6b63ecb37..2cdadd122 100644 --- a/src/devices/point-to-point/point-to-point-net-device.h +++ b/src/devices/point-to-point/point-to-point-net-device.h @@ -176,6 +176,7 @@ public: virtual bool NeedsArp (void) const; virtual void SetReceiveCallback (NetDevice::ReceiveCallback cb); + virtual void SetPromiscuousReceiveCallback (PromiscuousReceiveCallback cb); private: diff --git a/src/devices/wifi/wifi-net-device.cc b/src/devices/wifi/wifi-net-device.cc index f3bcad80d..44eb5acac 100644 --- a/src/devices/wifi/wifi-net-device.cc +++ b/src/devices/wifi/wifi-net-device.cc @@ -304,6 +304,12 @@ WifiNetDevice::SetReceiveCallback (NetDevice::ReceiveCallback cb) m_forwardUp = cb; } +void +WifiNetDevice::SetPromiscuousReceiveCallback (NetDevice::PromiscuousReceiveCallback cb) +{ + // TODO +} + void WifiNetDevice::ForwardUp (Ptr packet, const Mac48Address &from) { diff --git a/src/devices/wifi/wifi-net-device.h b/src/devices/wifi/wifi-net-device.h index 6740b9e20..b66cedc11 100644 --- a/src/devices/wifi/wifi-net-device.h +++ b/src/devices/wifi/wifi-net-device.h @@ -100,6 +100,7 @@ public: virtual void SetNode (Ptr node); virtual bool NeedsArp (void) const; virtual void SetReceiveCallback (NetDevice::ReceiveCallback cb); + virtual void SetPromiscuousReceiveCallback (PromiscuousReceiveCallback cb); private: virtual void DoDispose (void); diff --git a/src/node/net-device.h b/src/node/net-device.h index 3e5af9e36..f0fe4de36 100644 --- a/src/node/net-device.h +++ b/src/node/net-device.h @@ -259,6 +259,30 @@ public: */ virtual void SetReceiveCallback (ReceiveCallback cb) = 0; + /** + * \param device a pointer to the net device which is calling this callback + * \param packet the packet received + * \param protocol the 16 bit protocol number associated with this packet. + * This protocol number is expected to be the same protocol number + * given to the Send method by the user on the sender side. + * \param sourceAddress source address + * \param destinationAddress destination address + * \returns true if the callback could handle the packet successfully, false + * otherwise. + */ + typedef Callback,Ptr,uint16_t,const Address &, const Address &> PromiscuousReceiveCallback; + + /** + * \param cb callback to invoke whenever a packet has been received + * in promiscuous mode and must be forwarded to the higher + * layers, i.e. for all packets whose destination address + * does NOT match the NetDevice address. Note that + * ReceiveCallback and PromiscuousReceiveCallback handle + * mutually exclusive sets of packets, and you need to use + * both callbacks in order to receive ALL packets. + */ + virtual void SetPromiscuousReceiveCallback (PromiscuousReceiveCallback cb) = 0; + }; } // namespace ns3 diff --git a/src/node/node.cc b/src/node/node.cc index ef56ec6db..d7e032174 100644 --- a/src/node/node.cc +++ b/src/node/node.cc @@ -96,6 +96,7 @@ Node::AddDevice (Ptr device) device->SetNode (this); device->SetIfIndex(index); device->SetReceiveCallback (MakeCallback (&Node::ReceiveFromDevice, this)); + device->SetPromiscuousReceiveCallback (MakeCallback (&Node::PromiscuousReceiveFromDevice, this)); NotifyDeviceAdded (device); return index; } @@ -181,6 +182,32 @@ Node::UnregisterProtocolHandler (ProtocolHandler handler) } } +void +Node::RegisterPromiscuousProtocolHandler (PromiscuousProtocolHandler handler, + uint16_t protocolType, + Ptr device) +{ + struct Node::PromiscuousProtocolHandlerEntry entry; + entry.handler = handler; + entry.protocol = protocolType; + entry.device = device; + m_promiscuousHandlers.push_back (entry); +} + +void +Node::UnregisterPromiscuousProtocolHandler (PromiscuousProtocolHandler handler) +{ + for (PromiscuousProtocolHandlerList::iterator i = m_promiscuousHandlers.begin (); + i != m_promiscuousHandlers.end (); i++) + { + if (i->handler.IsEqual (handler)) + { + m_promiscuousHandlers.erase (i); + break; + } + } +} + bool Node::ReceiveFromDevice (Ptr device, Ptr packet, uint16_t protocol, const Address &from) @@ -208,4 +235,32 @@ Node::ReceiveFromDevice (Ptr device, Ptr packet, return found; } + +bool +Node::PromiscuousReceiveFromDevice (Ptr device, Ptr packet, + uint16_t protocol, const Address &from, const Address &to) +{ + bool found = false; + // if there are (potentially) multiple handlers, we need to copy the + // packet before passing it to each handler, because handlers may + // modify it. + bool copyNeeded = (m_handlers.size () > 1); + + for (PromiscuousProtocolHandlerList::iterator i = m_promiscuousHandlers.begin (); + i != m_promiscuousHandlers.end (); i++) + { + if (i->device == 0 || + (i->device != 0 && i->device == device)) + { + if (i->protocol == 0 || + i->protocol == protocol) + { + i->handler (device, (copyNeeded ? packet->Copy () : packet), protocol, from, to); + found = true; + } + } + } + return found; +} + }//namespace ns3 diff --git a/src/node/node.h b/src/node/node.h index 8a48d1d62..3588ffc19 100644 --- a/src/node/node.h +++ b/src/node/node.h @@ -154,6 +154,35 @@ public: */ void UnregisterProtocolHandler (ProtocolHandler handler); + /** + * A promiscuous protocol handler + */ + typedef Callback, Ptr,uint16_t, + const Address &, const Address &> PromiscuousProtocolHandler; + /** + * \param handler the handler to register + * \param protocolType the type of protocol this handler is + * interested in. This protocol type is a so-called + * EtherType, as registered here: + * http://standards.ieee.org/regauth/ethertype/eth.txt + * the value zero is interpreted as matching all + * protocols. + * \param device the device attached to this handler. If the + * value is zero, the handler is attached to all + * devices on this node. + */ + void RegisterPromiscuousProtocolHandler (PromiscuousProtocolHandler handler, + uint16_t protocolType, + Ptr device); + /** + * \param handler the handler to unregister + * + * After this call returns, the input handler will never + * be invoked anymore. + */ + void UnregisterPromiscuousProtocolHandler (PromiscuousProtocolHandler handler); + + protected: /** * The dispose method. Subclasses must override this method @@ -172,6 +201,8 @@ private: bool ReceiveFromDevice (Ptr device, Ptr, uint16_t protocol, const Address &from); + bool PromiscuousReceiveFromDevice (Ptr device, Ptr, + uint16_t protocol, const Address &from, const Address &to); void Construct (void); struct ProtocolHandlerEntry { @@ -185,6 +216,15 @@ private: std::vector > m_devices; std::vector > m_applications; ProtocolHandlerList m_handlers; + + // promiscuous protocol handlers + struct PromiscuousProtocolHandlerEntry { + PromiscuousProtocolHandler handler; + uint16_t protocol; + Ptr device; + }; + typedef std::vector PromiscuousProtocolHandlerList; + PromiscuousProtocolHandlerList m_promiscuousHandlers; }; } //namespace ns3 diff --git a/src/node/simple-net-device.cc b/src/node/simple-net-device.cc index 50e4c3611..5b30922d3 100644 --- a/src/node/simple-net-device.cc +++ b/src/node/simple-net-device.cc @@ -171,6 +171,10 @@ SimpleNetDevice::SetReceiveCallback (NetDevice::ReceiveCallback cb) { m_rxCallback = cb; } +void +SimpleNetDevice::SetPromiscuousReceiveCallback (NetDevice::PromiscuousReceiveCallback cb) +{ +} void SimpleNetDevice::DoDispose (void) diff --git a/src/node/simple-net-device.h b/src/node/simple-net-device.h index 19ce5ef3a..fb98e53d7 100644 --- a/src/node/simple-net-device.h +++ b/src/node/simple-net-device.h @@ -67,6 +67,7 @@ public: virtual void SetNode (Ptr node); virtual bool NeedsArp (void) const; virtual void SetReceiveCallback (NetDevice::ReceiveCallback cb); + virtual void SetPromiscuousReceiveCallback (PromiscuousReceiveCallback cb); protected: virtual void DoDispose (void); From d714797804ddb88d43cc5efcd163e155ab257319 Mon Sep 17 00:00:00 2001 From: Craig Dowell Date: Mon, 30 Jun 2008 11:42:38 -0700 Subject: [PATCH 087/495] tweak, tweak the tutorial --- doc/tutorial/building-topologies.texi | 6 +- doc/tutorial/conceptual-overview.texi | 254 ++++++++++++++------------ doc/tutorial/getting-started.texi | 60 +++--- doc/tutorial/introduction.texi | 28 ++- doc/tutorial/tweaking.texi | 76 ++++---- 5 files changed, 220 insertions(+), 204 deletions(-) diff --git a/doc/tutorial/building-topologies.texi b/doc/tutorial/building-topologies.texi index 7880d656e..fcb7008f8 100644 --- a/doc/tutorial/building-topologies.texi +++ b/doc/tutorial/building-topologies.texi @@ -136,7 +136,7 @@ object itself. csmaNodes.Create (nCsma); @end verbatim -The next line of code @code{Get}s the first node (as in having an index of one) +The next line of code @code{Gets} the first node (as in having an index of one) from the point-to-point node container and adds it to the container of nodes that will get CSMA devices. The node in question is going to end up with a point-to-point device @emph{and} a CSMA device. We then create a number of @@ -497,7 +497,7 @@ node number code{nCsma + 1}. This can become annoyingly difficult in larger simulations. An alternate way, which we use here, is to realize that the -@code{NodeContainer}s contain pointers to @command{ns-3} @code{Node} Objects. +@code{NodeContainers} contain pointers to @command{ns-3} @code{Node} Objects. The @code{Node} Object has a method called @code{GetId} which will return that node's ID. Let's go take a look at the Doxygen for the @code{Node} and locate that method, which is further down in the code than we've seen so far. @@ -681,7 +681,7 @@ part of the bus (CSMA) network. csmaNodes.Create (nCsma); @end verbatim -The next line of code @code{Get}s the first node (as in having an index of one) +The next line of code @code{Gets} the first node (as in having an index of one) from the point-to-point node container and adds it to the container of nodes that will get CSMA devices. The node in question is going to end up with a point-to-point device and a CSMA device. We then create a number of ``extra'' diff --git a/doc/tutorial/conceptual-overview.texi b/doc/tutorial/conceptual-overview.texi index 0b3a3592e..1213826e1 100644 --- a/doc/tutorial/conceptual-overview.texi +++ b/doc/tutorial/conceptual-overview.texi @@ -63,7 +63,7 @@ In @command{ns-3} there is no real concept of operating system and especially no concept of privilege levels or system calls. We do, however, have the idea of an application. Just as software applications run on computers to perform tasks in the ``real world,'' @command{ns-3} applications run on -@command{ns-3} @code{Node}s to drive simulations in the simulated world. +@command{ns-3} @code{Nodes} to drive simulations in the simulated world. @cindex class Application In @command{ns-3} the basic abstraction for a user program that generates some @@ -85,16 +85,17 @@ In the real world, one can connect a computer to a network. Often the media over which data flows in these netowrks are called @emph{channels}. When you connect your Ethernet cable to the plug in the wall, you are connecting your computer to an Ethernet communication channel. In the simulated world -of @command{ns-3} one connects a @code{Node} to an object representing a +of @command{ns-3}, one connects a @code{Node} to an object representing a communication channel. Here the basic communication subnetwork abstraction is called the channel and is represented in C++ by the class @code{Channel}. The @code{Channel} class provides methods for managing communication -subnetwork objects and connecting nodes to them. They may also be specialized -by developers in the object oriented programming sense. A @code{Channel} -specialization may model something as simple as a wire. The specialized -@code{Channel} can also model things as complicated as a large Ethernet -switch, or three-dimensional space in the case of wireless networks. +subnetwork objects and connecting nodes to them. @code{Channels} may also be +specialized by developers in the object oriented programming sense. A +@code{Channel} specialization may model something as simple as a wire. The +specialized @code{Channel} can also model things as complicated as a large +Ethernet switch, or three-dimensional space full of obstructions in the case +of wireless networks. We will use specialized versions of the @code{Channel} called @code{CsmaChannel}, @code{PointToPointChannel} and @code{WifiChannel} in this @@ -108,9 +109,10 @@ access} communication medium. This gives us Ethernet-like functionality. It used to be the case that if you wanted to connect a computers to a network, you had to buy a specific kind of network cable and a hardware device called (in PC terminology) a @emph{peripheral card} that needed to be installed in -your computer. These cards were called Network Interface Cards, or -@emph{NIC}s. Today most computers come with the network controller hardware -built in and users don't see these building blocks. +your computer. If the peripheral card implemented some networking function, +theys were called Network Interface Cards, or @emph{NICs}. Today most +computers come with the network interface hardware built in and users don't +see these building blocks. A NIC will not work without a software driver to control the hardware. In Unix (or Linux), a piece of peripheral hardware is classified as a @@ -122,9 +124,9 @@ to these net devices by names such as @emph{eth0}. In @command{ns-3} the @emph{net device} abstraction covers both the software driver and the simulated hardware. A net device is ``installed'' in a @code{Node} in order to enable the @code{Node} to communicate with other -@code{Node}s in the simulation via @code{Channel}s. Just as in a real +@code{Nodes} in the simulation via @code{Channels}. Just as in a real computer, a @code{Node} may be connected to more than one @code{Channel} via -multiple @code{NetDevice}s. +multiple @code{NetDevices}. The net device abstraction is represented in C++ by the class @code{NetDevice}. The @code{NetDevice} class provides methods for managing connections to @@ -145,25 +147,26 @@ a @code{WifiChannel}. In a real network, you will find host computers with added (or built-in) NICs. In @command{ns-3} we would say that you will find @code{Nodes} with attached @code{NetDevices}. In a large simulated network you will need to -arrange many connections between @code{Node}s, @code{NetDevice}s and -@code{Channel}s. +arrange many connections between @code{Nodes}, @code{NetDevices} and +@code{Channels}. -Since connecting @code{NetDevice}s to @code{Node}s, @code{NetDevice}s -to @code{Channel}s, assigning IP addresses, etc., are such common tasks +Since connecting @code{NetDevices} to @code{Nodes}, @code{NetDevices} +to @code{Channels}, assigning IP addresses, etc., are such common tasks in @command{ns-3}, we provide what we call @emph{topology helpers} to make -this as easy as possible. For example, will take several distinct +this as easy as possible. For example, it may take many distinct @command{ns-3} core operations to create a NetDevice, add a MAC address, -connect the net device to a @code{Node}, configure the protocol stack, and -then connect the @code{NetDevice} to a @code{Channel}. More operations would -be required to connect multiple devices onto multipoint channels and then to -connect networks together into internetworks. We use topology helper objects -to combine those many distinct operations into an easy to use model. +install that net device on a @code{Node}, configure the node's protocol stack, +and then connect the @code{NetDevice} to a @code{Channel}. Even more +operations would be required to connect multiple devices onto multipoint +channels and then to connect individual networks together into internetworks. +We provide topology helper objects that combine those many distinct operations +into an easy to use model for your convenience. @c ======================================================================== @c A First ns-3 script @c ======================================================================== @node A First ns-3 Script -@section A First ns-3 script +@section A First ns-3 Script @cindex first script If you downloaded the system as was suggested above, you will have a release of @command{ns-3} in a directory called @code{repos} under your home @@ -180,7 +183,8 @@ directory structure something like the following: Change into the examples directory. You should see a file named @code{first.cc} located there. This is a script that will create a simple point-to-point link between two nodes and echo a single packet between the -nodes. Let's take a look at that script line by line. +nodes. Let's take a look at that script line by line, so go ahead and open +@code{first.cc} in your favorite editor. @subsection Boilerplate The first line in the file is an emacs mode line. This tells emacs about the @@ -195,17 +199,20 @@ out of the way immediately. The @code{ns-3} project, like most large projects, has adopted a coding style to which all contributed code must adhere. If you want to contribute your code to the project, you will eventually have to conform to the @command{ns-3} coding standard as described -in the file @code{doc/codingstd.txt}. We recommend that you, well, just get -used to the look and feel of @code{ns-3} code and adopt this standard whenever -you are working with our code. All of the development team have done so. -The emacs mode line above makes it easier to get the formatting correct if you -use the emacs editor. +in the file @code{doc/codingstd.txt} or shown on the project web page +@uref{http://www.nsnam.org/codingstyle.html,,here}. + +We recommend that you, well, just get used to the look and feel of @code{ns-3} +code and adopt this standard whenever you are working with our code. All of +the development team and contributors have done so with various amounts of +grumbling. The emacs mode line above makes it easier to get the formatting +correct if you use the emacs editor. The @command{ns-3} simulator is licensed using the GNU General Public License. You will see the appropriate GNU legalese at the head of every file in the @command{ns-3} distribution. Often you will see a copyright notice for -one of the institutions involved in the @code{ns-3} project and an author -listed. +one of the institutions involved in the @code{ns-3} project above the GPL +text and an author listed below. @verbatim /* @@ -225,16 +232,7 @@ listed. @end verbatim @subsection Module Includes -The code proper starts with a number of include statements. To help our high -level users deal with the large number of include files present in the system, -we group includes according to relatively large modules. We provide a single -include file that, in turn, includes all of the include files used in each -module. Rather than having to look up exactly what header you need, and -possibly have to get dependencies right, we give you the ability to load a -group of files at a large granularity. This is not the most efficient approach -but it certainly makes writing scripts much easier. Each of the -@command{ns-3} files is placed in a directory called @code{ns3} (under the -build directory) to help avoid include file name collisions. +The code proper starts with a number of include statements. @verbatim #include "ns3/core-module.h" @@ -243,20 +241,35 @@ build directory) to help avoid include file name collisions. #include "ns3/helper-module.h" @end verbatim -The @code{ns3/core-module.h} file corresponds to the ns-3 module you will find -in the directory @code{src/core} in your downloaded release distribution. If -you list this directory you will find a large number of header files. When -you do a build, Waf will place public header files in an @code{ns3} directory -under the appropriate @code{build/debug} or @code{build/optimized} directory -depending on your configuration. Waf will also automatically generate a module -include file to load all of the public header files. Since you are following -this tutorial religiously, you will already have done a +To help our high-level script users deal with the large number of include +files present in the system, we group includes according to relatively large +modules. We provide a single include file that will recursively load all of +the include files used in each module. Rather than having to look up exactly +what header you need, and possibly have to get a number of dependencies right, +we give you the ability to load a group of files at a large granularity. This +is not the most efficient approach but it certainly makes writing scripts much +easier. + +Each of the @command{ns-3} include files is placed in a directory called +@code{ns3} (under the build directory) during the build process to help avoid +include file name collisions. The @code{ns3/core-module.h} file corresponds +to the ns-3 module you will find in the directory @code{src/core} in your +downloaded release distribution. If you list this directory you will find a +large number of header files. When you do a build, Waf will place public +header files in an @code{ns3} directory under the appropriate +@code{build/debug} or @code{build/optimized} directory depending on your +configuration. Waf will also automatically generate a module include file to +load all of the public header files. + +Since you are, of course, following this tutorial religiously, you will +already have done a @verbatim ./waf -d debug configure @end verbatim -to configure the project to perform debug builds. You will also have done a +in order to configure the project to perform debug builds. You will also have +done a @verbatim ./waf @@ -264,8 +277,8 @@ to configure the project to perform debug builds. You will also have done a to build the project. So now if you look in the directory @code{build/debug/ns-3} you will find the four module include files shown -above. You can take a look at the contents to find that these files will -include all of the public includes in the respective modules. +above. You can take a look at the contents of these files and find that they +do include all of the public include files in their respective modules. @subsection Ns3 Namespace The next line in the @code{first.cc} script is a namespace declaration. @@ -295,12 +308,9 @@ The next line of the script is the following, We will use this statement as a convenient place to talk about our Doxygen documentation system. If you look at the project web site, -@uref{http://www.nsnam.org,,ns-3 project}, you will find a link to ``Other -Documentation'' in the navigation bar. If you select this link, you will be -taken to our documentation page. You will find links to our development -@code{ns-3-dev} documentation as well as that for our latest release. If you -select the @code{HTML} link you will be taken to the Doxygen documentation for -that version. +@uref{http://www.nsnam.org,,ns-3 project}, you will find a link to ``APIs +(Doxygen)'' in the navigation bar. If you select this link, you will be +taken to our documentation page. Along the left side, you will find a graphical representation of the structure of the documentation. A good place to start is the @code{NS-3 Modules} @@ -308,20 +318,24 @@ of the documentation. A good place to start is the @code{NS-3 Modules} module documentation. The concept of module here ties directly into the module include files discussed above. It turns out that the @command{ns-3} logging subsystem is part of the @code{core} module, so go ahead and expand -that documentation node. Now, open the @code{Debugging} book and then select -the @code{Logging} page. +that documentation node. Now, expand the @code{Debugging} book and then +select the @code{Logging} page. You should now be looking at the Doxygen documentation for the Logging module. -In the list of @code{#define}s you will see @code{NS_LOG_COMPONENT_DEFINE}. -It would probably be good to look for the ``Detailed Description'' of the -logging module now to get a feel for the overall operation and then look at +In the list of @code{#define}s at the top of the page you will see the entry +for @code{NS_LOG_COMPONENT_DEFINE}. Before jumping in, it would probably be +good to look for the ``Detailed Description'' of the logging module to get a +feel for the overall operation. You can either scroll down or select the +``More...'' link under the collaboration diagram to do this. + +Once you have a general idea of what is going on, go ahead and take a look at the specific @code{NS_LOG_COMPONENT_DEFINE} documentation. I won't duplicate the documentation here, but to summarize, this line declares a logging component called @code{FirstScriptExample} that allows you to enable and disable console message logging by reference to the name. @subsection Main Function -The next lines of the script you will find are: +The next lines of the script you will find are, @verbatim int @@ -329,10 +343,10 @@ The next lines of the script you will find are: { @end verbatim -This is just the declaration of the main function of your program. Just as in -any C++ program, you need to define a main function that will be the first -function run. There is nothing at all special here. Your @command{ns-3} -script is just a C++ program. +This is just the declaration of the main function of your program (script). +Just as in any C++ program, you need to define a main function that will be +the first function run. There is nothing at all special here. Your +@command{ns-3} script is just a C++ program. The next two lines of the script are used to enable two logging components that are built into the Echo Client and Echo Server applications: @@ -342,14 +356,14 @@ are built into the Echo Client and Echo Server applications: LogComponentEnable("UdpEchoServerApplication", LOG_LEVEL_INFO); @end verbatim -If you have read over the Logging component documentation you will see that -there are a number of levels of detail that you can enable on each component. -These two lines of code enable debug logging at the INFO level for echo -clients and servers. This will result in the application printing out -messages as packets are sent and received. +If you have read over the Logging component documentation you will have seen +that there are a number of levels of logging verbosity/detail that you can +enable on each component. These two lines of code enable debug logging at the +INFO level for echo clients and servers. This will result in the application +printing out messages as packets are sent and received during the simulation. Now we will get directly to the business of creating a topology and running -a simulation. We will use the topology helper objects to make this job as +a simulation. We use the topology helper objects to make this job as easy as possible. @subsection Topology Helpers @@ -379,7 +393,7 @@ applications and peripheral cards. The @code{NodeContainer} topology helper provides a convenient way to create, manage and access any @code{Node} objects that we create in order to run a simulation. The first line above just declares a NodeContainer which we call @code{nodes}. The second line calls the -@code{Create} method on the @code{nodes} object that asks the container to +@code{Create} method on the @code{nodes} object and asks the container to create two nodes. As described in the Doxygen, the container calls down into the @command{ns-3} system proper to create two @code{Node} objects and stores pointers to those objects internally. @@ -416,8 +430,8 @@ The first line PointToPointHelper pointToPoint; @end verbatim -creates a @code{PointToPointHelper} object on the stack. From a high-level -perspective the next line, +instantiates a @code{PointToPointHelper} object on the stack. From a +high-level perspective the next line, @verbatim pointToPoint.SetDeviceParameter ("DataRate", StringValue ("5Mbps")); @@ -436,7 +450,7 @@ attribute. Most user-visible @command{ns-3} objects have similar lists of attributes. We use this mechanism to easily configure simulations without recompiling as you will see in a following section. -Similar to the ``DataRate'' on the @code{PointToPointNetDevice} we find a +Similar to the ``DataRate'' on the @code{PointToPointNetDevice} you will find a ``Delay'' attribute associated with the @code{PointToPointChannel}. The final line, @@ -446,14 +460,14 @@ final line, tells the @code{PointToPointHelper} to use the value ``2ms'' (two milliseconds) as the value of the transmission delay of every point to point channel it -creates. +subsequently creates. @subsubsection NetDeviceContainer At this point in the script, we have a @code{NodeContainer} that contains two nodes. We have a @code{PointToPointHelper} that is primed and ready to make @code{PointToPointNetDevices} and wire @code{PointToPointChannel} objects between them. Just as we used the @code{NodeContainer} topology helper object -to create the @code{Node}s for our simulation, we will ask the +to create the @code{Nodes} for our simulation, we will ask the @code{PointToPointHelper} to do the work involved in creating, configuring and installing our devices for us. We will need to have a list of all of the NetDevice objects that are created, so we use a NetDeviceContainer to hold @@ -518,7 +532,7 @@ and increase monotonically, so the first address allocated from this base will be 10.1.1.1, followed by 10.1.1.2, etc. The low level @command{ns-3} system actually remembers all of the IP addresses allocated and will generate a fatal error if you accidentally cause the same address to be generated twice -(which is a very hard to find error, by the way). +(which is a very hard to debug error, by the way). The next line of code, @@ -548,7 +562,7 @@ underlying objects. Here, we use @code{UdpEchoServerHelper} and @subsubsection UdpEchoServerHelper The following lines of code in our example script, @code{first.cc}, are used to set up a UDP echo server application on one of the nodes we have previously -created and connected using a point-to-point link. +created. @verbatim UdpEchoServerHelper echoServer; @@ -578,15 +592,16 @@ work here. We now see that @code{echoServer.Install} is going to install a @code{UdpEchoServerApplication} on the node found at index number one of the @code{NodeContainer} we used to manage our nodes. @code{Install} will return -a container that has all of the applications (one in this case since we passed -a @code{NodeContainer} containing one node) made by the helper. +a container that holds pointers to all of the applications (one in this case +since we passed a @code{NodeContainer} containing one node) created by the +helper. -Applications require a time to ``start'' generating traffic and a time to -``stop.'' These times are set using @code{ApplicationContainer} methods -@code{Start} and @code{Stop}. These methods take @code{Time} parameters. -In this case, we use an explicit conversion sequence to take the C++ double -1.0 and convert it to an @command{ns-3} @code{Time} object using a -@code{Seconds ()} cast. The two lines, +Applications require a time to ``start'' generating traffic and may take an +optional time to ``stop.'' We provide both. These times are set using the +@code{ApplicationContainer} methods @code{Start} and @code{Stop}. These +methods take @code{Time} parameters. In this case, we use an explicit C++ +conversion sequence to take the C++ double 1.0 and convert it to an +@command{ns-3} @code{Time} object using a @code{Seconds} cast. The two lines, @verbatim serverApps.Start (Seconds (1.0)); @@ -596,14 +611,14 @@ In this case, we use an explicit conversion sequence to take the C++ double will cause the echo server application to @code{Start} (enable itself) at one second into the simulation and to @code{Stop} (disable itself) at ten seconds into the simulation. By virtue of the fact that we have implicilty declared -a simulation event at ten seconds, the simulation will last at least ten -seconds. +a simulation event (the application stop event) to be executed at ten seconds, +the simulation will last at least ten seconds. @subsubsection UdpEchoClientHelper -The echo client application is set up in a substantially method similar to the -server. There is an underlying @code{UdpEchoClientApplication} that is -managed by an @code{UdpEchoClientHelper}. +The echo client application is set up in a method substantially similar to +that for the server. There is an underlying @code{UdpEchoClientApplication} +that is managed by an @code{UdpEchoClientHelper}. @verbatim UdpEchoClientHelper echoClient; @@ -620,24 +635,25 @@ managed by an @code{UdpEchoClientHelper}. For the echo client, however, we need to set four different attributes. The first attribute is set using the @code{SetRemote} method. Recall that we used an @code{Ipv4InterfaceContainer} to keep track of the IP addresses we -assigned to our devices. As a result of the allocation, the zeroth interface -in the @code{interfaces} container cooresponds to the IP address of the -zeroth node in the @code{nodes} container. The first interface in the -@code{interfaces} container cooresponds to the IP address of the first node in -the @code{nodes} container. So, in the following line of code (reproduced -from above), we are setting the remote address of the client to be the IP -address assigned to the node on which the server resides, and we tell it to -send packets to port nine. +assigned to our devices. The zeroth interface in the @code{interfaces} +container is going to coorespond to the IP address of the zeroth node in the +@code{nodes} container. The first interface in the @code{interfaces} +container cooresponds to the IP address of the first node in the @code{nodes} +container. So, in the following line of code (reproduced from above), we are +setting the remote address of the client to be the IP address assigned to the +node on which the server resides. We also tell it to send packets to port +nine while we are at ti. @verbatim echoClient.SetRemote (interfaces.GetAddress (1), 9); @end verbatim The ``MaxPackets'' attribute tells the client the maximum number of packets -it can send. The ``Interval'' attribute tells the client how long to wait -between packets, and the ``PacketSize'' attribute tells the client how large -its packets should be. With this combination of attributes, we are telling -the client to send one 1024-byte packet. +we allow it to send during the simulation. The ``Interval'' attribute tells +the client how long to wait between packets, and the ``PacketSize'' attribute +tells the client how large its packet payloads should be. With this +particular combination of attributes, we are telling the client to send one +1024-byte packet. Just as in the case of the echo server, we tell the echo client to @code{Start} and @code{Stop}, but here we start the client one second after the server is @@ -667,13 +683,13 @@ looking through the list of scheduled events and executing them. First it will run the event at 1.0 seconds, which will enable the echo server application. Then it will run the event scheduled for t=2.0 seconds which will start the echo client application. The start event implementation in -the echo client will begin the data transfer phase of the simulation by -sending a packet to the server. +the echo client application will begin the data transfer phase of the +simulation by sending a packet to the server. The act of sending the packet to the server will trigger a chain of events -which will be automatically scheduled and which will perform the mechanics of -the packet echo according to the various timing parameters that we have set -in the script. +that will be automatically scheduled behind the scene and which will perform +the mechanics of the packet echo according to the various timing parameters +that we have set in the script. Eventually, since we only send one packet, the chain of events triggered by that single client echo request will taper off and the simulation will go @@ -704,31 +720,31 @@ built if you run Waf. Let's try it. Copy @code{examples/first.cc} into the @code{scratch} directory. @verbatim - ~/repos/ns-3-tutorial > cp examples/first.cc scratch/ + ~/repos/ns-3-dev > cp examples/first.cc scratch/ @end verbatim and then build it using waf, @verbatim - ~/repos/ns-3-tutorial > ./waf - Entering directory `/home/craigdo/repos/ns-3-tutorial/build' + ~/repos/ns-3-dev > ./waf + Entering directory `/home/craigdo/repos/ns-3-dev/build' [432/477] cxx: scratch/first.cc -> build/debug/scratch/first_2.o [475/477] cxx_link: build/debug/scratch/first_2.o ... Compilation finished successfully -~/repos/ns-3-tutorial > +~/repos/ns-3-dev > @end verbatim You can now run the example (note that if you build your program in the scratch directory you must run it out of the scratch direcory): @verbatim - ~/repos/ns-3-tutorial > ./waf --run scratch/first - Entering directory `/home/craigdo/repos/ns-3-tutorial/build' + ~/repos/ns-3-dev > ./waf --run scratch/first + Entering directory `/home/craigdo/repos/ns-3-dev/build' Compilation finished successfully Sent 1024 bytes to 10.1.1.2 Received 1024 bytes from 10.1.1.1 Received 1024 bytes from 10.1.1.2 - ~/repos/ns-3-tutorial > + ~/repos/ns-3-dev > @end verbatim Here you see that the build system checks to make sure that the file has been diff --git a/doc/tutorial/getting-started.texi b/doc/tutorial/getting-started.texi index d5ae09ffb..cf2f58e31 100644 --- a/doc/tutorial/getting-started.texi +++ b/doc/tutorial/getting-started.texi @@ -33,15 +33,14 @@ @cindex Cygwin @cindex GNU @cindex toolchain -From this point forward, we are going to assume that the reader is working in -Linux or a Linux emulation environment (Linux, Cygwin, etc.) and has the GNU -toolchain installed and verified. - @cindex Mercurial @cindex Waf -We are going to assume that you have Mercurial and Waf installed and running -on the target system as described in the Getting Started section of the -@command{ns-3} web site: @uref{http://www.nsnam.org/getting_started.html}. +From this point forward, we are going to assume that the reader is working in +Linux or a Linux emulation environment (Linux, Cygwin, etc.) and has the GNU +toolchain installed and verified. We are also going to assume that you have +Mercurial and Waf installed and running on the target system as described in +the Getting Started section of the @command{ns-3} web site: +@uref{http://www.nsnam.org/getting_started.html}. @cindex tarball The @command{ns-3} code is available in Mercurial repositories on the server @@ -67,15 +66,15 @@ official release. Since the release numbers are going to be changing, I will stick with the more constant ns-3-dev here in the tutorial, but you can replace the -string ns-3-dev with your choice of release (e.g., ns-3.1) in the text below. -You can find the latest version of the code either by inspection of the -repository list or by going to the ``Getting Started'' web page and looking -for the latest release identifier. +string ``ns-3-dev'' with your choice of release (e.g., ns-3.1) in the text +below. You can find the latest version of the code either by inspection of +the repository list or by going to the ``Getting Started'' web page and +looking for the latest release identifier. One practice is to create a directory called @code{repos} in one's home directory under which one can keep local Mercurial repositories. @emph{Hint: we will assume you do this later in the tutorial.} If you adopt -that approach, you can get a copy of any of the development versions of +that approach, you can get a copy of the development version of @command{ns-3} by typing the following into your Linux shell (assuming you have installed Mercurial): @@ -86,7 +85,8 @@ have installed Mercurial): hg clone http://code.nanam.org/ns-3-dev @end verbatim -As the hg command executes, you should see something like the following, +As the hg (Mercurial) command executes, you should see something like the +following, @verbatim destination directory: ns-3-dev @@ -169,7 +169,7 @@ The build system is now configured and you can build the debug versions of the @command{ns-3} programs by simply typing, @verbatim - ./waf check + ./waf @end verbatim You will see many Waf status messages displayed as the system compiles. The @@ -217,10 +217,10 @@ test has passed. This command is typically run by @code{users} to quickly verify that an @command{ns-3} distribution has built correctly. -You can also run @code{regression tests} to ensure that your distribution and -tool chain have produced binaries that generate trace files which are -compatible with reference trace files stored in a central location. To run the -regression tests you run Waf with the regression flag. +You can also run our regression test suite to ensure that your distribution and +tool chain have produced binaries that generate output that is identical to +reference output files stored in a central location. To run the regression +tests, you provide Waf with the regression flag. @verbatim ./waf --regression @@ -231,16 +231,16 @@ built and will then look for trace files in the aforementioned centralized location. If your tool chain includes Mercurial, the regression tests will be downloaded from a repository at @code{code.nsnam.org}. If you do not have Mercurial installed, the reference traces will be downloaded from a tarball -located in the @code{releases} section of @code{www.nsnam.org}. The -particular name of the reference trace location is built from the -@command{ns-3} version located in the VERSION file, so don't change that -string yourself unless you know what you are doing. +located in the releases section of @code{www.nsnam.org}. The particular name +of the reference trace location is built from the @command{ns-3} version +located in the VERSION file, so don't change that string yourself unless you +know what you are doing. Once the reference traces are downloaded to your local machine, Waf will run -a number of tests that generate trace files. The content of these trace -files are compared with the reference traces just downloaded. If they are -identical, the regression tests report a PASS status. If the regression tests -pass, you should see something like, +a number of tests that generate what we call trace files. The content of +these trace files are compared with the reference traces just downloaded. If +they are identical, the regression tests report a PASS status. If the +regression tests pass, you should see something like, @verbatim ~/repos/ns-3-dev > ./waf --regression @@ -264,7 +264,8 @@ pass, you should see something like, If a regression tests fails you will see a FAIL indication along with a pointer to the offending trace file and its associated reference trace file -along with a suggestion on how to run diff in order to see what has gone awry. +along with a suggestion on diff parameters and options in order to see what +has gone awry. @c ======================================================================== @c Running a Script @@ -276,7 +277,7 @@ along with a suggestion on how to run diff in order to see what has gone awry. We typically run scripts under the control of Waf. This allows the build system to ensure that the shared library paths are set correctly and that the libraries are available at run time. To run a program, simply use the -@code{run} option in Waf. Let's run the @command{ns-3} equivalent of the +@code{--run} option in Waf. Let's run the @command{ns-3} equivalent of the ubiquitous hello world program by typing the following: @verbatim @@ -291,7 +292,8 @@ produces the following output. Hello Simulator @end verbatim +@emph{Congratulations. You are now an ns-3 user.} + If you want to run programs under another tool such as gdb or valgrind, see this @uref{http://www.nsnam.org/wiki/index.php/User_FAQ#How_to_run_NS-3_programs_under_another_tool,,wiki entry}. -@emph{Congratulations. You are now an ns-3 user.} diff --git a/doc/tutorial/introduction.texi b/doc/tutorial/introduction.texi index d15653da1..aace2ed84 100644 --- a/doc/tutorial/introduction.texi +++ b/doc/tutorial/introduction.texi @@ -126,7 +126,7 @@ broad sequences of events. * The Web:: * Mercurial:: * Waf:: -* Environment Idioms Design Patterns:: +* Development Environment:: * Socket Programming:: @end menu @@ -134,21 +134,19 @@ broad sequences of events. @section The Web @cindex www.nsnam.org +@cindex documentation +@cindex architecture There are several important resources of which any @command{ns-3} user must be aware. The main web site is located at @uref{http://www.nsnam.org} and provides access to basic information about the ns-3 system. Detailed documentation is available through the main web site at -@uref{http://www.nsnam.org/documents.html}. +@uref{http://www.nsnam.org/documents.html}. You can also find documents +relating to the system architecture from this page. -@cindex documentation -@cindex architecture -You can find documents relating to the system architecture from this page, -and also gain access to the detailed software documentation. There is a Wiki -that complements the main ns-3 web site which you will find at -@uref{http://www.nsnam.org/wiki/}. - -You will find user and developer FAQs there, as well as troubleshooting -guides, third-party contributed code, papers, etc. +There is a Wiki that complements the main ns-3 web site which you will find at +@uref{http://www.nsnam.org/wiki/}. You will find user and developer FAQs +there, as well as troubleshooting guides, third-party contributed code, +papers, etc. @cindex mercurial repository @cindex ns-3-dev repository @@ -208,8 +206,8 @@ order to extend the system in most cases. For those interested in the gory details of Waf, the main web site can be found at @uref{http://freehackers.org/~tnagy/waf.html}. -@node Environment Idioms Design Patterns -@section Environment, Idioms, and Design Patterns +@node Development Environment +@section Development Environment @cindex C++ As mentioned above, scripting in ns-3 is done in C++. A working @@ -278,5 +276,5 @@ not have access to a copy of the book, the echo clients and servers shown in the website above) you will be in good shape to understand the tutorial. There is a similar book on Multicast Sockets, @uref{http://www.elsevier.com/wps/product/cws_home/700736,,Multicast Sockets, Makofske and Almeroth}. -that covers material you may need to understand for the multicast examples in -the distribution. +that covers material you may need to understand if you look at the multicast +examples in the distribution. diff --git a/doc/tutorial/tweaking.texi b/doc/tutorial/tweaking.texi index 510f5ee42..c2fac0608 100644 --- a/doc/tutorial/tweaking.texi +++ b/doc/tutorial/tweaking.texi @@ -93,13 +93,13 @@ in the @code{first.cc} script you have already built. Go ahead and run the script just as you did previously, @verbatim - ~/repos/ns-3-tutorial > ./waf --run scratch/first - Entering directory `/home/craigdo/repos/ns-3-tutorial/build' + ~/repos/ns-3-dev > ./waf --run scratch/first + Entering directory `/home/craigdo/repos/ns-3-dev/build' Compilation finished successfully Sent 1024 bytes to 10.1.1.2 Received 1024 bytes from 10.1.1.1 Received 1024 bytes from 10.1.1.2 - ~/repos/ns-3-tutorial > + ~/repos/ns-3-dev > @end verbatim The ``Sent'' and ``Received'' messages are actually logging messages from the @@ -125,7 +125,7 @@ increase the logging level and get more information without changing the script and recompiling by setting the NS_LOG environment variable like this: @verbatim - ~/repos/ns-3-tutorial > export NS_LOG=UdpEchoClientApplication=level_all + ~/repos/ns-3-dev > export NS_LOG=UdpEchoClientApplication=level_all @end verbatim This sets the environment variable @code{NS_LOG} to the string, @@ -141,8 +141,8 @@ you run the script with NS_LOG set this way you should see the following output: @verbatim - ~/repos/ns-3-tutorial > ./waf --run scratch/first - Entering directory `/home/craigdo/repos/ns-3-tutorial/build' + ~/repos/ns-3-dev > ./waf --run scratch/first + Entering directory `/home/craigdo/repos/ns-3-dev/build' Compilation finished successfully UdpEchoClientApplication:UdpEchoClient() UdpEchoClientApplication:StartApplication() @@ -155,7 +155,7 @@ output: UdpEchoClientApplication:StopApplication() UdpEchoClientApplication:DoDispose() UdpEchoClientApplication:~UdpEchoClient() - ~/repos/ns-3-tutorial > + ~/repos/ns-3-dev > @end verbatim The only additional debug information provided by the application is from @@ -194,8 +194,8 @@ that every message from the given log component is prefixed with the component name. @verbatim - ~/repos/ns-3-tutorial > ./waf --run scratch/first - Entering directory `/home/craigdo/repos/ns-3-tutorial/build' + ~/repos/ns-3-dev > ./waf --run scratch/first + Entering directory `/home/craigdo/repos/ns-3-dev/build' Compilation finished successfully UdpEchoClientApplication:UdpEchoClient() UdpEchoClientApplication:StartApplication() @@ -208,7 +208,7 @@ name. UdpEchoClientApplication:StopApplication() UdpEchoClientApplication:DoDispose() UdpEchoClientApplication:~UdpEchoClient() - ~/repos/ns-3-tutorial > + ~/repos/ns-3-dev > @end verbatim You can now see all of the messages coming from the UDP echo client application @@ -231,8 +231,8 @@ echo client and server applications. You may see that this can be very useful in debugging problems. @verbatim - ~/repos/ns-3-tutorial > ./waf --run scratch/first - Entering directory `/home/craigdo/repos/ns-3-tutorial/build' + ~/repos/ns-3-dev > ./waf --run scratch/first + Entering directory `/home/craigdo/repos/ns-3-dev/build' Compilation finished successfully UdpEchoServerApplication:UdpEchoServer() UdpEchoClientApplication:UdpEchoClient() @@ -251,7 +251,7 @@ in debugging problems. UdpEchoServerApplication:DoDispose() UdpEchoClientApplication:~UdpEchoClient() UdpEchoServerApplication:~UdpEchoServer() - ~/repos/ns-3-tutorial > + ~/repos/ns-3-dev > @end verbatim It is also sometimes useful to be able to see the simulation time at which a @@ -265,8 +265,8 @@ log message is generated. You can do this by ORing in the prefix_time bit. If you run the script now, you should see the following output: @verbatim - ~/repos/ns-3-tutorial > ./waf --run scratch/first - Entering directory `/home/craigdo/repos/ns-3-tutorial/build' + ~/repos/ns-3-dev > ./waf --run scratch/first + Entering directory `/home/craigdo/repos/ns-3-dev/build' Compilation finished successfully 0ns UdpEchoServerApplication:UdpEchoServer() 0ns UdpEchoClientApplication:UdpEchoClient() @@ -287,7 +287,7 @@ If you run the script now, you should see the following output: UdpEchoServerApplication:DoDispose() UdpEchoClientApplication:~UdpEchoClient() UdpEchoServerApplication:~UdpEchoServer() - ~/repos/ns-3-tutorial > + ~/repos/ns-3-dev > @end verbatim You can see that the constructor for the UdpEchoServer was called at a @@ -324,7 +324,7 @@ for the single packet echo) but you can redirect this information into a file and look through it with your favorite editor if you like, @verbatim - ~/repos/ns-3-tutorial > ./waf --run scratch/first >& log.out + ~/repos/ns-3-dev > ./waf --run scratch/first >& log.out @end verbatim I personally use this quite a bit when I am presented with a problem and I @@ -365,7 +365,7 @@ Now build the script using waf and clear the @code{NS_LOG} variable to turn off the torrent of logging we previously enabled: @verbatim - ~/repos/ns-3-tutorial > export NS_LOG= + ~/repos/ns-3-dev > export NS_LOG= @end verbatim Now, if you run the script, you will not see your new message since its @@ -376,21 +376,21 @@ to @code{NS_LOG_INFO}. If you just want to see this particular level of logging, you can enable it by, @verbatim - ~/repos/ns-3-tutorial > export NS_LOG=FirstScriptExample=info + ~/repos/ns-3-dev > export NS_LOG=FirstScriptExample=info @end verbatim If you now run the script you will see your new ``Creating Topology'' log message, @verbatim - ~/repos/ns-3-tutorial > ./waf --run scratch/first - Entering directory `/home/craigdo/repos/ns-3-tutorial/build' + ~/repos/ns-3-dev > ./waf --run scratch/first + Entering directory `/home/craigdo/repos/ns-3-dev/build' Compilation finished successfully Creating Topology Sent 1024 bytes to 10.1.1.2 Received 1024 bytes from 10.1.1.1 Received 1024 bytes from 10.1.1.2 - ~/repos/ns-3-tutorial > + ~/repos/ns-3-dev > @end verbatim @c ======================================================================== @@ -430,7 +430,7 @@ and add that two lines of code to the @code{first.cc} script at the start of for help in the following way, @verbatim - ~/repos/ns-3-tutorial > ./waf --run "scratch/first --PrintHelp" + ~/repos/ns-3-dev > ./waf --run "scratch/first --PrintHelp" @end verbatim This will ask Waf to run the @code{scratch/first} script and pass the command @@ -439,8 +439,8 @@ sort out which program gets which argument. The command line parser will now see the @code{--PrintHelp} argument and respond with, @verbatim - ~/repos/ns-3-tutorial > ./waf --run ``scratch/first --PrintHelp'' - Entering directory `/home/craigdo/repos/ns-3-tutorial/build' + ~/repos/ns-3-dev > ./waf --run ``scratch/first --PrintHelp'' + Entering directory `/home/craigdo/repos/ns-3-dev/build' Compilation finished successfully --PrintHelp: Print this help message. --PrintGroups: Print the list of groups. @@ -448,7 +448,7 @@ now see the @code{--PrintHelp} argument and respond with, --PrintGroup=[group]: Print all TypeIds of group. --PrintAttributes=[typeid]: Print all attributes of typeid. --PrintGlobals: Print the list of globals. - ~/repos/ns-3-tutorial > + ~/repos/ns-3-dev > @end verbatim Let's focus on the @code{--PrintAttributes} option. We have already hinted @@ -515,8 +515,8 @@ time prefix. If you run the script, you should now see the following output, @verbatim - ~/repos/ns-3-tutorial > ./waf --run scratch/first - Entering directory `/home/craigdo/repos/ns-3-tutorial/build' + ~/repos/ns-3-dev > ./waf --run scratch/first + Entering directory `/home/craigdo/repos/ns-3-dev/build' Compilation finished successfully 0ns UdpEchoServerApplication:UdpEchoServer() 1000000000ns UdpEchoServerApplication:StartApplication() @@ -527,7 +527,7 @@ If you run the script, you should now see the following output, 10000000000ns UdpEchoServerApplication:StopApplication() UdpEchoServerApplication:DoDispose() UdpEchoServerApplication:~UdpEchoServer() - ~/repos/ns-3-tutorial > + ~/repos/ns-3-dev > @end verbatim Recall that the last time we looked at the simulation time at which the packet @@ -644,8 +644,8 @@ Now if you run the script and provide the @code{--PrintHelp} argument, you should see your new @code{User Argument} listed in the help. @verbatim - ~/repos/ns-3-tutorial > ./waf --run "scratch/first --PrintHelp" - Entering directory `/home/craigdo/repos/ns-3-tutorial/build' + ~/repos/ns-3-dev > ./waf --run "scratch/first --PrintHelp" + Entering directory `/home/craigdo/repos/ns-3-dev/build' Compilation finished successfully --PrintHelp: Print this help message. --PrintGroups: Print the list of groups. @@ -655,15 +655,15 @@ should see your new @code{User Argument} listed in the help. --PrintGlobals: Print the list of globals. User Arguments: --nPackets: Number of packets to echo - ~/repos/ns-3-tutorial > + ~/repos/ns-3-dev > @end verbatim If you want to specify the number of packets to echo, you can now do so by setting the @code{--nPackets} argument in the command line, @verbatim - ~/repos/ns-3-tutorial > ./waf --run "scratch/first --nPackets=2" - Entering directory `/home/craigdo/repos/ns-3-tutorial/build' + ~/repos/ns-3-dev > ./waf --run "scratch/first --nPackets=2" + Entering directory `/home/craigdo/repos/ns-3-dev/build' Compilation finished successfully Sent 1024 bytes to 10.1.1.2 Received 1024 bytes from 10.1.1.1 @@ -671,7 +671,7 @@ setting the @code{--nPackets} argument in the command line, Sent 1024 bytes to 10.1.1.2 Received 1024 bytes from 10.1.1.1 Received 1024 bytes from 10.1.1.2 - ~/repos/ns-3-tutorial > + ~/repos/ns-3-dev > @end verbatim You have now echoed two packets. @@ -961,15 +961,15 @@ The easiest thing to do at this point will be to use @code{tcpdump} to look at the @code{pcap} files. Output from dumping both files is shown below: @verbatim - ~/repos/ns-3-tutorial > /usr/sbin/tcpdump -r first-0-0.pcap -nn -tt + ~/repos/ns-3-dev > /usr/sbin/tcpdump -r first-0-0.pcap -nn -tt reading from file first-0-0.pcap, link-type PPP (PPP) 2.000000 IP 10.1.1.1.49153 > 10.1.1.2.9: UDP, length 1024 2.514648 IP 10.1.1.2.9 > 10.1.1.1.49153: UDP, length 1024 - ~/repos/ns-3-tutorial > /usr/sbin/tcpdump -r first-1-0.pcap -nn -tt + ~/repos/ns-3-dev > /usr/sbin/tcpdump -r first-1-0.pcap -nn -tt reading from file first-1-0.pcap, link-type PPP (PPP) 2.257324 IP 10.1.1.1.49153 > 10.1.1.2.9: UDP, length 1024 2.257324 IP 10.1.1.2.9 > 10.1.1.1.49153: UDP, length 1024 - ~/repos/ns-3-tutorial > + ~/repos/ns-3-dev > @end verbatim You can see in the dump of ``first-0.0.pcap'' (the client device) that the From 31417e808d27a076f9ae4492af17c9d3fd4c13e4 Mon Sep 17 00:00:00 2001 From: Craig Dowell Date: Mon, 30 Jun 2008 13:06:34 -0700 Subject: [PATCH 088/495] some final tweaks to the tutorial --- doc/tutorial/building-topologies.texi | 129 +++++++++++++----------- doc/tutorial/conceptual-overview.texi | 2 +- doc/tutorial/tweaking.texi | 139 ++++++++++++++------------ 3 files changed, 146 insertions(+), 124 deletions(-) diff --git a/doc/tutorial/building-topologies.texi b/doc/tutorial/building-topologies.texi index fcb7008f8..04b737df3 100644 --- a/doc/tutorial/building-topologies.texi +++ b/doc/tutorial/building-topologies.texi @@ -246,9 +246,9 @@ if we create @code{nCsma} ``extra'' nodes the last one will be at index code. The client application is set up exactly as we did in the @code{first.cc} -example script. We point the client to the server we just set up on the last -of the ``extra'' CSMA nodes and install the client onto the point-to-point node -that is not associated with any CSMA device. +example script. We tell the client to send packets to the server we just +installed on the last of the ``extra'' CSMA nodes. We install the client on +the leftmost point-to-point node seen in the topology illustration. @verbatim UdpEchoClientHelper echoClient; @@ -305,8 +305,8 @@ repository you would type, ./waf --run scratch/second @end verbatim -Since we have set up the UDP echo applications to log just as we did in the -@code{first.cc} script, you will see similar output. +Since we have set up the UDP echo applications to log just as we did in +@code{first.cc}, you will see similar output when you run the script. @verbatim ~/repos/ns-3-dev > ./waf --run scratch/second @@ -473,12 +473,12 @@ pcap trace file for every node in the simulation. One thing you can do to keep from getting all of those pcap traces with nothing but ARP exchanges in them is to be more specific about which nodes and devices you want to trace. -Let's take a look at @code{scratch/second.cc} and be more specific about which -nodes and devices we want to trace. The file we provide uses the -@code{EnablePcapAll} methods of the helpers to enable pcap on all devices. -We want to use the more specific method, @code{EnablePcap}, which takes -a node number and device number as parameters. Go ahead and replace the -@code{EnablePcapAll} calls with the calls below. +Let's take a look at @code{scratch/second.cc} and add that code enabling us +to be more specific. The file we provided used the @code{EnablePcapAll} +methods of the helpers to enable pcap on all devices. We now want to use the +more specific method, @code{EnablePcap}, which takes a node number and device +number as parameters. Go ahead and replace the @code{EnablePcapAll} calls +with the calls below. @verbatim PointToPointHelper::EnablePcap ("second", p2pNodes.Get (0)->GetId (), 0); @@ -490,30 +490,34 @@ we also know that the device of interest in both cases is going to be zero, so those parameters are not really interesting. In order to get the node number, you have two choices: first, nodes are numbered in a monotonically increasing fashion starting from zero in the order in which you created them. -One way to get a node number to pass to the helper is to figure this number -out ``manually.'' If you take a look at the network topology illustration at -the beginning of the file, you can see that the last CSMA node is going to be -node number code{nCsma + 1}. This can become annoyingly difficult in larger +One way to get a node number is to figure this number out ``manually'' by +contemplating the order of node creation. If you take a look at the network +topology illustration at the beginning of the file, we did this for you and +you can see that the last CSMA node is going to be node number +@code{nCsma + 1}. This approach can become annoyingly difficult in larger simulations. An alternate way, which we use here, is to realize that the @code{NodeContainers} contain pointers to @command{ns-3} @code{Node} Objects. The @code{Node} Object has a method called @code{GetId} which will return that -node's ID. Let's go take a look at the Doxygen for the @code{Node} and locate -that method, which is further down in the code than we've seen so far. +node's ID, which is the node number we seek. Let's go take a look at the +Doxygen for the @code{Node} and locate that method, which is further down in +the @command{ns-3} core code than we've seen so far; but sometimes you have to +search diligently for useful things. Go to the Doxygen documentation for your release (recall that you can find it on the project web site). You can get to the @code{Node} documentation by -looking through at the ``Classes'' tab in and scrolling down to -@code{ns3::Node} in the list. Select @code{ns3::Node} and you will be taken +looking through at the ``Classes'' tab and scrolling down the ``Class List'' +until you find @code{ns3::Node}. Select @code{ns3::Node} and you will be taken to the documentation for the @code{Node} class. If you now scroll down to the @code{GetId} method and select it, you will be taken to the detailed documentation for the method. Using the @code{GetId} method can make determining node numbers much easier in complex topologies. Now that we have got some trace filtering in place, it is reasonable to start -increasing the number of CSMA devices in our simulation. If you run the -simulation setting @code{nCsma} to 100, you will see the following: +increasing the number of CSMA devices in our simulation. If you build the +new script and run the simulation setting @code{nCsma} to 100, you will see +the following output: @verbatim ~/repos/ns-3-dev > ./waf --run "scratch/second --nCsma=100" @@ -526,8 +530,8 @@ simulation setting @code{nCsma} to 100, you will see the following: @end verbatim Note that the echo server is now located at 10.1.2.101 which corresponds to -100 ``extra'' CSMA nodes with the echo server on the last one. If you list -the pcap files in the top level directory, +having 100 ``extra'' CSMA nodes with the echo server on the last one. If you +list the pcap files in the top level directory, @verbatim ~/repos/ns-3-dev > ls *.pcap @@ -569,8 +573,8 @@ script and examine some of the output. Just as in the @code{second.cc} example (and in all @command{ns-3} examples) the file begins with an emacs mode line and some GPL boilerplate. -Lets take a look at the ASCII art that shows the default network topology -constructed in the example. In this case, you can see that we are going to +Take a look at the ASCII art (reproduced below) that shows the default network +topology constructed in the example. You can see that we are going to further extend our example by hanging a wireless network off of the left side. Notice that this is a default network topology since you can actually vary the number of nodes created on the wired and wireless networks. Just as in the @@ -762,8 +766,8 @@ by providing a propagation delay model. Again, I don't want to devolve this tutorial into a manual on @code{Wifi}, but this model describes how the electromagnetic signals are going to propagate. We are going to create the simplest model, the @code{ConstantSpeedPropagationDelayModel} that, by default, -has the signals propagating at a constant speed --- that of the speed of light -in a vacuum. +has the signals propagating at a constant speed --- approximately that of the +speed of light in air. Recall that we created the @code{WifiChannel} and assigned it to a smart pointer. One of the features of a smart pointer is that you can use it @@ -771,7 +775,9 @@ just as you would a ``normal'' C++ pointer. The next line of code will create a @code{ConstantSpeedPropagationDelayModel} using the @code{CreateObject} template function and pass the resulting smart pointer to the chanel model as an unnamed parameter of the -@code{WifiChannel SetPropagationDelayModel} method. +@code{WifiChannel SetPropagationDelayModel} method. In English, we create +a model for propagation speed of electromagnetic signals and tell the +wireless channel to use it. @verbatim channel->SetPropagationDelayModel ( @@ -790,12 +796,13 @@ and set a ``propagation loss model'' for the channel. channel->SetPropagationLossModel (log); @end verbatim -This snippet tells the channel how it should calculate signal attenuation -of a signal. The details of these calcuations are beyond the scope of a -tutorial. You are encouraged to explore the Doxygen documentation of classes -@code{LogDistancePropagationLossModel} and -@code{FriisPropagationLossModel} if you are interested in the details. You -will find the documentation in the ``Classes'' tab of the Doxygen page. +This snippet is used to tell the channel how it should calculate signal +attenuation of waves flowing in the channel. The details of these calcuations +are beyond the scope of a tutorial. You are encouraged to explore the Doxygen +documentation of classes @code{LogDistancePropagationLossModel} and +@code{FriisPropagationLossModel} if you are interested in the details. As +usual, you will find the documentation in the ``Classes'' tab of the Doxygen +documentation. Now we will return to more familiar ground. We next create a @code{WifiHelper} object and set two default atributes that it will use when creating the actual @@ -808,9 +815,9 @@ devices. @end verbatim The @code{SetPhy} method tells the helper the type of physical layer class -we want to instantiate when building @code{Wifi} devices. In this case, it -is asking for physical layer models based on the YANS 802.11a model. Again, -details are avialable in Doxygen. +we want it to instantiate when building @code{Wifi} devices. In this case, +the script is asking for physical layer models based on the YANS 802.11a +model. Again, details are avialable in Doxygen. The @code{SetRemoteStationManager} method tells the helper the type of rate control algorithm to use. Here, it is asking the helper to use the AARF @@ -836,8 +843,9 @@ will not be sent by MACs created by this helper. Again, for the next lines of code we are back on familiar ground. This code will @code{Install} Wifi net devices on the nodes we have created as STA nodes -and will tie them to the @code{WifiChannel} we created manually by passing -in the @code{channel} to the @code{Install} method. +and will tie them to the @code{WifiChannel}. Since we created the +@code{channel} manually rather than having the helper do it for us, we have to +pass it into the helper when we call the @code{Install} method. @verbatim NetDeviceContainer staDevices; @@ -846,7 +854,8 @@ in the @code{channel} to the @code{Install} method. We have configured Wifi for all of our STA nodes, and now we need to configure the AP (access point) node. We begin this process by changing -the default @code{Attributes} to reflect the requirements of the AP. +the default @code{Attributes} of the @code{WifiHelper} to reflect the +requirements of the AP. @verbatim wifi.SetMac ("ns3::NqapWifiMac", @@ -869,7 +878,7 @@ familiar way. @end verbatim Now, we are going to add mobility models. We want the STA nodes to be mobile, -wandering around inside a bounding box and we want to make the AP node +wandering around inside a bounding box, and we want to make the AP node stationary. We use the @code{MobilityHelper} to make this easy for us. First, we instantiate a @code{MobilityHelper} obejct and set some attributes controlling the ``position allocator'' functionality. @@ -907,7 +916,7 @@ STA nodes. mobility.Install (wifiStaNodes); @end verbatim -We wanted the access point to remain in a fixed position during the simulation. +We want the access point to remain in a fixed position during the simulation. We accomplish this by setting the mobility model for this node to be the @code{ns3::StaticMobilityModel}: @@ -1145,8 +1154,8 @@ following function: } @end verbatim -This code just unconditionally pulls the position information from the -mobility model and logs the x and y position of the node. We are +This code just pulls the position information from the mobility model and +unconditionally logs the x and y position of the node. We are going to arrange for this function to be called every time the wireless node with the echo client changes its position. We do this using the @code{Config::Connect} function. Add the following lines of code to the @@ -1162,24 +1171,27 @@ script just before the @code{Simulator::Run} call. @end verbatim What we do here is to create a string containing the tracing namespace path -to the event we want to connect. We have to figure out which node it is we -want to connect to. In the case of the default number of CSMA and wireless -nodes, this turns out to be node seven and the tracing namespace path to the -mobility model is, +of the event to which we want to connect. First, we have to figure out which +node it is we want using the @code{GetId} method as described earlier. In the +case of the default number of CSMA and wireless nodes, this turns out to be +node seven and the tracing namespace path to the mobility model would look +like, @verbatim /NodeList/7/$ns3::MobilityModel/CourseChange @end verbatim -Based on the discussion in the tracing section, you may easily infer that -this string references the seventh node in the NodeList and looks for what is -called an aggregated object of type @code{ns3::MobilityModel}. The dollar -sign prefix implies that the MobilityModel is aggregated to node seven. The -last component of the path means that we are hooking into the ``CourseChange'' -event of that model. We have made a connection between the trace source in -node seven with our trace sink by calling @code{Config::Connect}. Once this -is done, every course change event on node seven will be hooked into our trace -sink, which will in turn print out the new position. +Based on the discussion in the tracing section, you can easily infer that +this trace path references the seventh node in the NodeList. It specifies +what is called an aggregated object of type @code{ns3::MobilityModel}. The +dollar sign prefix implies that the MobilityModel is aggregated to node seven. +The last component of the path means that we are hooking into the +``CourseChange'' event of that model. + +We make a connection between the trace source in node seven with our trace +sink by calling @code{Config::Connect} and passing this namespace path. Once +this is done, every course change event on node seven will be hooked into our +trace sink, which will in turn print out the new position. If you now run the simulation, you will see the course changes displayed as they happen. @@ -1225,8 +1237,7 @@ they happen. If you are feeling brave, there is a list of all trace sources in the @command{ns-3} Doxygen which you can find in the ``NS-3 Modules'' section. Under the ``core'' section, you will find a link to ``The list of all trace -sources.'' In that link you will find a list of all of the trace sources that - you can hook to. You may find it interesting to try and hook some of these +sources.'' You may find it interesting to try and hook some of these traces yourself. Additionally in the ``NS-3 Modules'' documentation, there is a link to ``The list of all attributes.'' You can set the default value of any of these atributes via the command line as we have previously discussed. diff --git a/doc/tutorial/conceptual-overview.texi b/doc/tutorial/conceptual-overview.texi index 1213826e1..232df70f3 100644 --- a/doc/tutorial/conceptual-overview.texi +++ b/doc/tutorial/conceptual-overview.texi @@ -687,7 +687,7 @@ the echo client application will begin the data transfer phase of the simulation by sending a packet to the server. The act of sending the packet to the server will trigger a chain of events -that will be automatically scheduled behind the scene and which will perform +that will be automatically scheduled behind the scenes and which will perform the mechanics of the packet echo according to the various timing parameters that we have set in the script. diff --git a/doc/tutorial/tweaking.texi b/doc/tutorial/tweaking.texi index c2fac0608..cc7e2151c 100644 --- a/doc/tutorial/tweaking.texi +++ b/doc/tutorial/tweaking.texi @@ -43,10 +43,10 @@ used to output debug messages which can quickly turn the output into a blur. @command{Ns-3} takes the view that all of these verbosity levels are useful and we provide a selectable, multi-level approach to message logging. Logging -can be disabled completely, enabled on a component-by-component basis, enabled -globally and has selectable verbosity levels. The @command{ns-3} log module -provides a straightforward, relatively easy to use way to get some kinds of -information out of your simulation. +can be disabled completely, enabled on a component-by-component basis, or +enabled globally; and it provides selectable verbosity levels. The +@command{ns-3} log module provides a straightforward, relatively easy to use +way to get useful information out of your simulation. You should understand that we do provide a general purpose mechanism --- tracing --- to get data out of your models which should be preferred for @@ -78,19 +78,18 @@ irrespective of logging levels or component selection. Each level can be requested singly or cumulatively; and logging can be set up using a shell environment variable (NS_LOG) or by logging system function call. As was seen earlier in the tutorial, the logging system has Doxygen -documentation so now would be a good time to peruse the Logging Module -documentation. +documentation and now would be a good time to peruse the Logging Module +documentation if you have not done so. -Now that you have read the documentation in great detail, we can get some -interesting information out of the @code{first.cc} example script you dropped -in the scratch directory after the script walkthrough. +Now that you have read the documentation in great detail, let's use some of +that knowledge to get some interesting information out of the @code{first.cc} +example script you have already built. @node Enabling Logging @subsection Enabling Logging Using the NS_LOG Environment Variable @cindex NS_LOG -First, let's use the NS_LOG environment variable to turn on some more logging -in the @code{first.cc} script you have already built. Go ahead and run the -script just as you did previously, +Let's use the NS_LOG environment variable to turn on some more logging, but +to get our bearings, go ahead and run the script just as you did previously, @verbatim ~/repos/ns-3-dev > ./waf --run scratch/first @@ -102,16 +101,19 @@ script just as you did previously, ~/repos/ns-3-dev > @end verbatim -The ``Sent'' and ``Received'' messages are actually logging messages from the -@code{UdpEchoClientApplication} and @code{UdpEchoServerApplication}. We can -ask the client application, for example, to print more information by setting -its logging level via the NS_LOG environment variable. I am going to assume -from here on that are using an sh-like shell that uses the``VARIABLE=value'' -syntax. If you are using a csh-like shell, then you will have to convert to -the ``setenv VARIABLE value'' syntax required by those shells. +It turns out that the ``Sent'' and ``Received'' messages are actually logging +messages from the @code{UdpEchoClientApplication} and +@code{UdpEchoServerApplication}. We can ask the client application, for +example, to print more information by setting its logging level via the +NS_LOG environment variable. -Let's ask the UDP echo client application to print a little more information. -Right now, it is responding to the following line of code in @code{first.cc}, +I am going to assume from here on that are using an sh-like shell that uses +the``VARIABLE=value'' syntax. If you are using a csh-like shell, then you +will have to convert my examples to the ``setenv VARIABLE value'' syntax +required by those shells. + +Right now, the UDP echo client application is responding to the following line +of code in @code{first.cc}, @verbatim LogComponentEnable("UdpEchoClientApplication", LOG_LEVEL_INFO); @@ -128,7 +130,7 @@ script and recompiling by setting the NS_LOG environment variable like this: ~/repos/ns-3-dev > export NS_LOG=UdpEchoClientApplication=level_all @end verbatim -This sets the environment variable @code{NS_LOG} to the string, +This sets the shell environment variable @code{NS_LOG} to the string, @verbatim UdpEchoClientApplication=level_all @@ -137,8 +139,8 @@ This sets the environment variable @code{NS_LOG} to the string, The left hand side of the assignment is the name of the logging component we want to set, and the right hand side is the flag we want to use. In this case, we are going to turn on all of the debugging levels for the application. If -you run the script with NS_LOG set this way you should see the following -output: +you run the script with NS_LOG set this way, the @command{ns-3} logging +system will pick up the change and you should see the following output: @verbatim ~/repos/ns-3-dev > ./waf --run scratch/first @@ -158,11 +160,13 @@ output: ~/repos/ns-3-dev > @end verbatim -The only additional debug information provided by the application is from -the NS_LOG_FUNCTION level. Note that there are no requirements in the -@command{ns-3} system that logging components must support any particular -logging functionality. The decision regarding how much information is logged -is left to the individual developer. +The additional debug information provided by the application is from +the NS_LOG_FUNCTION level. This shows every time a function in the application +is called during script execution. Note that there are no requirements in the +@command{ns-3} system that models must support any particular logging +functionality. The decision regarding how much information is logged +is left to the individual model developer. In the case of the echo +applications, a good deal of log output is available. You can now see a log of the function calls that were made to the application. If you look closely you will notice a single colon between the string @@ -296,9 +300,10 @@ simulation starts. The same for the UdpEchoClient constructor. Recall that the @code{first.cc} script started the echo server application at one second into the simulation. You can now see that the -@code{StartApplication} of the server is, in fact, called at one second (or -one billion nanoseconds). You can also see that the echo client application -is started at a simulation time of two seconds as we requested in the script. +@code{StartApplication} method of the server is, in fact, called at one second +(or one billion nanoseconds). You can also see that the echo client +application is started at a simulation time of two seconds as we requested in +the script. You can now follow the progress of the simulation from the @code{ScheduleTransmit} call in the client that calls @code{Send} to the @@ -306,7 +311,7 @@ You can now follow the progress of the simulation from the elapsed time as the packet is sent across the point-to-point link is 3.6864 milliseconds. You see the echo server logging a message telling you that it has echoed the packet and then, after a delay, you see the echo client receive -the echoed packet. +the echoed packet in its @code{HandleRead} method. There is a lot that is happening under the covers in this simulation that you are not seeing as well. You can very easily follow the entire process by @@ -641,7 +646,7 @@ instead of the constant @code{1} as is shown below. @end verbatim Now if you run the script and provide the @code{--PrintHelp} argument, you -should see your new @code{User Argument} listed in the help. +should see your new @code{User Argument} listed in the help display. @verbatim ~/repos/ns-3-dev > ./waf --run "scratch/first --PrintHelp" @@ -676,12 +681,12 @@ setting the @code{--nPackets} argument in the command line, You have now echoed two packets. -If you are an @command{ns-3} user, you can use the command line argument -system to control global values and attributes. If you are a model author, -you can add new attributes to your Objects and they will automatically be -available for setting by your users through the command line system. If you -are a script author, you can add new variables to your scripts and hook them -into the command line system quite painlessly. +You can see that if you are an @command{ns-3} user, you can use the command +line argument system to control global values and attributes. If you are a +model author, you can add new attributes to your Objects and they will +automatically be available for setting by your users through the command line +system. If you are a script author, you can add new variables to your scripts +and hook them into the command line system quite painlessly. @c ======================================================================== @c Using the Tracing System @@ -692,7 +697,7 @@ into the command line system quite painlessly. The whole point of simulation is to generate output for further study, and the @command{ns-3} tracing system is a primary mechanism for this. Since @command{ns-3} is a C++ program, standard facilities for generating output -from C++ programs apply: +from C++ programs could be used: @verbatim #include @@ -705,6 +710,11 @@ from C++ programs apply: } @end verbatim +You could even use the logging module to add a little structure to your +solution. There are many well-known problems generated by such approaches +and so we have provided a generic event tracing subsystem to address the +issues we thought were important. + The basic goals of the @command{ns-3} tracing system are: @itemize @bullet @@ -736,7 +746,7 @@ The rationale for this explicit division is to allow users to attach new types of sinks to existing tracing sources, without requiring editing and recompilation of the the core of the simulator. Thus, in the example above, a user could define a new tracing sink in her script and attach it to an -existing tracing source defined in the simulation core editing only the +existing tracing source defined in the simulation core by editing only the user script. In this tutorial, we will walk through some pre-defined sources and sinks and @@ -747,12 +757,12 @@ extending the tracing namespace and creating new tracing sources. @cindex tracing @cindex ASCII tracing @subsection ASCII Tracing -@command{Ns-3} provides functionality wrapping the low-level tracing system -to help you with the details involved in configuring some easily -understood packe traces. If you enable this functionality, you will see -output of a trace of a simulation appear in an ASCII file --- thus the name. -For those familiar with @command{ns-2} output, this type of trace is -analogous to the @command{out.tr} generated by many scripts. +@command{Ns-3} provides helper functionality that wraps the low-level tracing +system to help you with the details involved in configuring some easily +understood packet traces. If you enable this functionality, you will see +output in a ASCII files --- thus the name. For those familiar with +@command{ns-2} output, this type of trace is analogous to the @command{out.tr} +generated by many scripts. @cindex tracing packets Let's just jump right in and add some ASCII tracing output to our @@ -790,8 +800,8 @@ You can now build the script and run it from the command line: @cindex first.tr Just as you have seen previously, you may see some messages from Waf and then -the ``Compilation finished successfully'' message. The following messages are -from the running program. +the ``Compilation finished successfully'' with some number of messages from +the running program. When it ran, the program will have created a file named @code{first.tr}. Because of the way that Waf works, the file is not created in the local @@ -799,7 +809,7 @@ directory, it is created at the top-level directory of the repository by default. If you want to control where the traces are saved you can use the @code{--cwd} option of Waf to specify this. We have not done so, thus we need to change into the top level directory of our repo and take a look at -the file @code{first.tr} in your favorite editor. +the ASCII trace file @code{first.tr} in your favorite editor. @subsubsection Parsing Ascii Traces @cindex parsing ascii traces @@ -808,11 +818,11 @@ to notice is that there are a number of distinct lines in this file. It may be difficult to see this clearly unless you widen your window considerably. Each line in the file corresponds to a @emph{trace event}. In this case -we are tracing events on the @emph{transmit queue} present in every net device -on every node in the simulation. The transmit queue is a queue through which -every packet destined for a channel must pass. Note that each line in the -trace file begins with a lone character (has a space after it). This -character will have the following meaning: +we are tracing events on the @emph{transmit queue} present in every +point-to-point net device in the simulation. The transmit queue is a queue +through which every packet destined for a point-to-point channel must pass. +Note that each line in the trace file begins with a lone character (has a +space after it). This character will have the following meaning: @cindex ascii trace enqueue operation @cindex ascii trace dequeue operation @@ -855,8 +865,8 @@ we see confirmation that this is, indeed, happening. @cindex node number @cindex net device number @cindex smart pointer -The next line of the example trace (reference 02) tell us the trace source -that originated this even expressed in the tracing namespace. You can think +The next line of the example trace (reference 02) tell us which trace source +originated this event (expressed in the tracing namespace). You can think of the tracing namespace somewhat like you would a filesystem namespace. The root of the namespace is the @code{NodeList}. This corresponds to a container managed in the @command{ns-3} core code that contains all of the nodes that are @@ -869,8 +879,8 @@ You can see that this trace event comes from @code{DeviceList/0} which is the zeroth device installed in the node. The next string, @code{$ns3::PointToPointNetDevice} tells you what kind of -device it is that is in the zeroth position of the device list for node zero. -Recall that the operation @code{+} found at reference 00 means an enqueue +device is in the zeroth position of the device list for node zero. +Recall that the operation @code{+} found at reference 00 meant that an enqueue operation happened on the transmit queue of the device. This is reflected in the final segments of the ``trace path'' which are @code{TxQueue/Enqueue}. @@ -916,7 +926,7 @@ traces in the file. @subsection PCAP Tracing @cindex pcap @cindex Wireshark -The @command{ns-3} device helpers can be used to create trace files in the +The @command{ns-3} device helpers can also be used to create trace files in the @code{.pcap} format. The acronym pcap (usually written in lower case) stands for @emph{p}acket @emph{cap}ture, and is actually an API that includes the definition of a @code{.pcap} file format. The most popular program that can @@ -940,11 +950,12 @@ create a trace file for every point-to-point device in the simulation. The file names will be built using the prefix, the node number, the device number and a ``.pcap'' suffix. -In our example script, we will see a files named ``first-0-0.pcap'' and -``first.1-0.pcap'' which are the pcap traces for node 0-device 0 and +In our example script, we will eventually see files named ``first-0-0.pcap'' +and ``first.1-0.pcap'' which are the pcap traces for node 0-device 0 and node 1-device 1, respectively. -You can now run the script in the usual way: +Once you have added the line of code to enable pcap tracing, you can run the +script in the usual way: @verbatim ./waf --run scratch/first From b271ea5c87d9b0a0e0258ac77788f16066905023 Mon Sep 17 00:00:00 2001 From: Craig Dowell Date: Mon, 30 Jun 2008 13:16:31 -0700 Subject: [PATCH 089/495] Tutorial TOC tweaks --- doc/tutorial/introduction.texi | 2 -- doc/tutorial/tweaking.texi | 2 +- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/doc/tutorial/introduction.texi b/doc/tutorial/introduction.texi index aace2ed84..0b4724061 100644 --- a/doc/tutorial/introduction.texi +++ b/doc/tutorial/introduction.texi @@ -223,8 +223,6 @@ If you are new to C++, you may want to find a tutorial- or cookbook-based book or web site and work through at least the basic features of the language before proceeding. -@subsection Environment - @cindex toolchain @cindex GNU The @command{ns-3} system uses the GNU ``toolchain'' for development. A diff --git a/doc/tutorial/tweaking.texi b/doc/tutorial/tweaking.texi index cc7e2151c..1a8623392 100644 --- a/doc/tutorial/tweaking.texi +++ b/doc/tutorial/tweaking.texi @@ -86,7 +86,7 @@ that knowledge to get some interesting information out of the @code{first.cc} example script you have already built. @node Enabling Logging -@subsection Enabling Logging Using the NS_LOG Environment Variable +@subsection Enabling Logging @cindex NS_LOG Let's use the NS_LOG environment variable to turn on some more logging, but to get our bearings, go ahead and run the script just as you did previously, From 89f5373c27f9234ffe99fe84f378418ce0a888d6 Mon Sep 17 00:00:00 2001 From: Craig Dowell Date: Mon, 30 Jun 2008 13:35:33 -0700 Subject: [PATCH 090/495] Prepare for 3.1 --- RELEASE_NOTES | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/RELEASE_NOTES b/RELEASE_NOTES index 0441d0d04..2c3cbcdfe 100644 --- a/RELEASE_NOTES +++ b/RELEASE_NOTES @@ -3,7 +3,7 @@ This file contains ns-3 release notes (most recent releases first). -Release 3.1 (2008/06/30 tentatively) +Release 3.1 (2008/06/30) ======================== First supported ns-3 release. From 4196578e980d6c79a4478673648ceb473453e88b Mon Sep 17 00:00:00 2001 From: Craig Dowell Date: Mon, 30 Jun 2008 13:44:27 -0700 Subject: [PATCH 091/495] new convention for release tags --- doc/release_steps.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/release_steps.txt b/doc/release_steps.txt index 4641654cd..0802632fd 100644 --- a/doc/release_steps.txt +++ b/doc/release_steps.txt @@ -14,10 +14,10 @@ Steps in doing an ns-3 release 4. test dev tarball on release platforms (waf check and maybe some other scripts) 5. once you are happy with the tarball, tag ns-3-dev and ns-3-dev-ref-traces - - hg tag "release ns-3.1x" + - hg tag "ns-3.1x" - hg push - cd into regression/ns-3-dev-ref-traces - - hg tag "release ns-3.1x" + - hg tag "ns-3.1x" - hg push 6. clone the tagged ns-3-dev and place it on the repository - ssh code.nsnam.org; sudo tcsh; su code; From 46dced7f481e9e8a1bfc19c0a08f8d7a3c33b1fe Mon Sep 17 00:00:00 2001 From: Craig Dowell Date: Mon, 30 Jun 2008 13:46:33 -0700 Subject: [PATCH 092/495] Added tag ns-3.1 for changeset 42504fb1f7be --- .hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/.hgtags b/.hgtags index 6e3254eeb..83542246b 100644 --- a/.hgtags +++ b/.hgtags @@ -14,3 +14,4 @@ b17f2928291eec5bf5b1c59a4a5fd583f704ac40 ns-3.0.12 8869a79a391f49d0c787f0558cc9329b4e7ee40e ns-3.1-RC1 951296e9a277e14113a0d3ba86a9688b222569ae ns-3.1-RC2 ea16c44eb90db579c83d3434fc8a960be506a7f5 ns-3.1-RC3 +42504fb1f7be7817b8be513cdcd3d9bc8f3660e8 ns-3.1 From a52bde7d464763dd4b50771f1dd72640ffb62d51 Mon Sep 17 00:00:00 2001 From: Craig Dowell Date: Mon, 30 Jun 2008 13:47:05 -0700 Subject: [PATCH 093/495] Added tag ns-3.1 for changeset 5768685f9fdb --- .hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/.hgtags b/.hgtags index 83542246b..0125a554a 100644 --- a/.hgtags +++ b/.hgtags @@ -15,3 +15,4 @@ b17f2928291eec5bf5b1c59a4a5fd583f704ac40 ns-3.0.12 951296e9a277e14113a0d3ba86a9688b222569ae ns-3.1-RC2 ea16c44eb90db579c83d3434fc8a960be506a7f5 ns-3.1-RC3 42504fb1f7be7817b8be513cdcd3d9bc8f3660e8 ns-3.1 +5768685f9fdba9fbf2e9561a840f085142c73575 ns-3.1 From 5b9d211ab9d7ab4f28d2277ff7e59fdd5665b089 Mon Sep 17 00:00:00 2001 From: Craig Dowell Date: Mon, 30 Jun 2008 14:17:19 -0700 Subject: [PATCH 094/495] update RELEASE_NOTES --- RELEASE_NOTES | 93 ++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 70 insertions(+), 23 deletions(-) diff --git a/RELEASE_NOTES b/RELEASE_NOTES index 2c3cbcdfe..ad1f6c6c9 100644 --- a/RELEASE_NOTES +++ b/RELEASE_NOTES @@ -5,21 +5,68 @@ This file contains ns-3 release notes (most recent releases first). Release 3.1 (2008/06/30) ======================== -First supported ns-3 release. -- TCP bugfixes and support for packet tags -- CSMA NetDevice cleanup and documentation -- internet-node renamed to internet-stack -- Socket::RecvFrom added; "flags" argument added to Send calls -- updated doxygen -- several bugs and open issues closed out -- revised tutorial +The first ns-3 stable release +----------------------------- -Note: Some API in class ns3::Ipv4 and ns3::Ipv4RoutingProtocol is -deprecated and may be removed and replaced in future releases. +This release is immediately available from: +http://www.nsnam.org/releases/ns-3.1.tar.bz2 + +We dedicate this initial ns-3 release to our late contributor and friend, +Federico Maguolo. + +What is ns-3 ? +-------------- + +ns-3 is a new discrete-event network simulator designed for supporting network +research and education. ns-3 features a solid, well documented C++ core and +models for TCP/IP (IPv4), several link types including WiFi, and mobility +models. + +ns-3 is an open source project released under the GNU GPLv2 license which +allows anyone to use ns-3 without having to pay any license fee or royalties. +ns-3 is actively seeking new contributors to extend the range of supported +models and/or to maintain existing models. + +Where to get more information about ns-3 +---------------------------------------- + +All the ns-3 documentation, is accessible from the ns-3 website: +http://www.nsnam.org + +Including, tutorials: +http://www.nsnam.org/tutorials.html + +Supported platforms +------------------- + +ns-3 is regularly tested on the following platforms: + - linux x86 gcc 4.2, 4.1, and, 3.4.6. + - linux x86_64 gcc 4.1.3, 4.2.1, 3.4.6 + - MacOS X ppc and x86 + - cygwin gcc 3.4.4 (debug only) + +Known issues +------------ + +ns-3 is known to fail on the following platforms: + - gcc 3.3 and earlier + - optimized builds on gcc 3.4.4 and 3.4.5 + - optimized builds on linux x86 gcc 4.0.x + +The IPv4 API defined in src/node/ipv4.h is expected to undergo major changes +in preparation of the merge of the IPv6 API and implementation. + +Future releases +--------------- + +Our next release, which is expected to happen in 2 to 4 months from now, will +feature the merging of some of our projects currently in development: python +scripting, IPv6, emulation, a statistics framework and synchronous posix +sockets. Release 3.0.13 (2008/06/02) -======================== +=========================== - point to point links generate ppp pcap traces - point to point links support asymmetrical data rates. - generate doxygen documentation for all attributes and trace sources @@ -39,7 +86,7 @@ called Simulator::Stop (time), and takes a relative time, instead of absolute. Release 3.0.12 (2008/04/07) -======================== +=========================== - Add Attribute support to the TypeId metadata system and add attribute support to all in-tree models - Add a mid-level helper API to build simulation topologies @@ -52,7 +99,7 @@ in the 802.11 model (Federico Maguolo). - TCP delayed acknowledgements and multitasking server Release 3.0.11 (2008/02/15) -======================== +=========================== - Initial port of GTNetS TCP implementation (initial version that does not support multitasking or delayed acknowledgments yet, but supports a reliable stream service) @@ -62,13 +109,13 @@ metadata system - tutorial updates Release 3.0.10 (2008/01/15) -======================== +=========================== - Add tutorial document content; - Valgrind option for "waf" tool; - Doxygen organization changes. Release 3.0.9 (2007/12/15) -======================== +========================== - A 802.11 model ported from Yans. This model supports: * a rather extensive PHY model * log-distance and friis propagation model @@ -82,26 +129,26 @@ Release 3.0.9 (2007/12/15) - many bugs fixed Release 3.0.8 (2007/11/15) -======================== +========================== - A simple error model - Source files for ns-3 tutorial Release 3.0.7 (2007/10/15) -======================== +========================== - OLSR routing protocol - A timer class - Additional mobility models (random waypoint, random 2D walk) - A mobility visualization tool Release 3.0.6 (2007/09/15) -======================== +========================== - Static multicast IPv4 routing - Logging overhaul (NS_LOG macros) - Refactoring of tracing subsystem - Tutorial document started Release 3.0.5 (2007/08/15) -======================== +========================== - Refactoring to support win32-based unix environments (Cygwin, mingw) - "Packet socket" for allowing applications to access NetDevices directly @@ -112,7 +159,7 @@ Release 3.0.5 (2007/08/15) - Global unicast centralized routing Release 3.0.4 (2007/07/15) -======================== +========================== - Enable waf as the default build system. - Per-packet metadata: a system to track which headers and trailers @@ -120,7 +167,7 @@ Release 3.0.4 (2007/07/15) - Simplifications to point-to-point devices and channel Release 3.0.3 (2007/06/15) -======================== +========================== - Enable Waf for release tarballs: users can now build ns-3 with the "waf" tool. See doc/build-waf.txt. @@ -133,7 +180,7 @@ Release 3.0.3 (2007/06/15) - Many small API cleanups Release 3.0.2 (2007/05/18) -======================== +========================== - Implement a new memory management infrastructure based on reference counting and smart pointers (the latter being @@ -145,7 +192,7 @@ Release 3.0.2 (2007/05/18) - Add support for a BSD-style socket API for user applications Release 3.0.1 (2007/03/31) -======================== +========================== - First public release; not yet pre-alpha. From fbc3554c2c34b9525d842a53b8a4c0a0c3d4c9d8 Mon Sep 17 00:00:00 2001 From: Tom Henderson Date: Mon, 30 Jun 2008 22:41:22 -0700 Subject: [PATCH 095/495] chapter on Node and internet stack, for manual --- doc/manual/Makefile | 3 +- doc/manual/figures/internet-node-recv.obj | 380 ++++++++++++++++++++++ doc/manual/figures/internet-node-send.obj | 352 ++++++++++++++++++++ doc/manual/figures/node.obj | 211 ++++++++++++ doc/manual/manual.texi | 2 + doc/manual/node.texi | 358 ++++++++++++++++++++ 6 files changed, 1304 insertions(+), 2 deletions(-) create mode 100644 doc/manual/figures/internet-node-recv.obj create mode 100644 doc/manual/figures/internet-node-send.obj create mode 100644 doc/manual/figures/node.obj create mode 100644 doc/manual/node.texi diff --git a/doc/manual/Makefile b/doc/manual/Makefile index 8e60864ed..ba9be0635 100644 --- a/doc/manual/Makefile +++ b/doc/manual/Makefile @@ -8,8 +8,7 @@ CSS = --css-include=manual.css SPLIT = --split section DIA_SOURCES = buffer.dia sockets-overview.dia -TGIF_SOURCES = packet.obj - +TGIF_SOURCES = packet.obj node.obj internet-node-send.obj internet-node-recv.obj DIA_EPS = ${DIA_SOURCES:.dia=.eps} DIA_PNG = ${DIA_SOURCES:.dia=.png} DIA_PDF = ${DIA_SOURCES:.dia=.pdf} diff --git a/doc/manual/figures/internet-node-recv.obj b/doc/manual/figures/internet-node-recv.obj new file mode 100644 index 000000000..3440e73f4 --- /dev/null +++ b/doc/manual/figures/internet-node-recv.obj @@ -0,0 +1,380 @@ +%TGIF 4.1.43-QPL +state(0,37,100.000,154,78,0,16,0,9,1,1,0,0,3,0,1,0,'Times-Roman',0,80640,0,3,0,10,0,0,1,1,0,16,0,0,1,1,1,1,1088,1408,1,0,2880,0). +% +% @(#)$Header$ +% %W% +% +unit("1 pixel/pixel"). +color_info(11,65535,0,[ + "magenta", 65535, 0, 65535, 65535, 0, 65535, 1, + "red", 65535, 0, 0, 65535, 0, 0, 1, + "green", 0, 65535, 0, 0, 65535, 0, 1, + "blue", 0, 0, 65535, 0, 0, 65535, 1, + "yellow", 65535, 65535, 0, 65535, 65535, 0, 1, + "pink", 65535, 49344, 52171, 65535, 49344, 52171, 1, + "cyan", 0, 65535, 65535, 0, 65535, 65535, 1, + "CadetBlue", 24415, 40606, 41120, 24415, 40606, 41120, 1, + "white", 65535, 65535, 65535, 65535, 65535, 65535, 1, + "black", 0, 0, 0, 0, 0, 0, 1, + "DarkSlateGray", 12079, 20303, 20303, 12079, 20303, 20303, 1 +]). +script_frac("0.6"). +fg_bg_colors('black','white'). +dont_reencode("FFDingbests:ZapfDingbats"). +page(1,"",1,''). +group([ +rcbox('black','',161,586,241,634,2,1,1,0,16,125,0,0,0,0,'1',0,[ +]), +text('black',161,605,1,0,1,72,18,124,13,5,0,0,0,0,2,72,18,0,0,"",0,0,0,0,618,'',[ +minilines(72,18,0,0,0,0,0,[ +mini_line(72,13,5,0,0,0,[ +str_block(0,72,13,5,0,0,0,0,0,[ +str_seg('black','Courier',0,80640,72,13,5,0,0,0,0,0,0,0, + "NetDevice")]) +]) +])]) +], +141,0,0,[ +]). +group([ +rcbox('black','',147,77,255,125,2,1,1,0,16,354,0,0,0,0,'1',0,[ +]), +text('black',163,96,1,0,1,88,18,353,13,5,0,0,0,0,2,88,18,0,0,"",0,0,0,0,109,'',[ +minilines(88,18,0,0,0,0,0,[ +mini_line(88,13,5,0,0,0,[ +str_block(0,88,13,5,0,0,0,0,0,[ +str_seg('black','Courier',0,80640,88,13,5,0,0,0,0,0,0,0, + "Application")]) +]) +])]) +], +352,0,0,[ +]). +text('black',202,172,1,1,1,90,17,473,14,3,2,0,0,0,2,90,17,0,0,"",0,0,0,0,186,'',[ +minilines(90,17,0,0,1,0,0,[ +mini_line(90,14,3,0,0,0,[ +str_block(0,90,14,3,0,0,0,0,0,[ +str_seg('black','Times-Roman',0,80640,90,14,3,0,0,0,0,0,0,0, + "UdpSocketImpl")]) +]) +])]). +rcbox('black','',132,165,269,198,0,1,1,0,16,474,0,0,0,0,'1',0,[ +]). +text('black',202,241,1,1,1,78,17,475,14,3,2,0,0,0,2,78,17,0,0,"",0,0,0,0,255,'',[ +minilines(78,17,0,0,1,0,0,[ +mini_line(78,14,3,0,0,0,[ +str_block(0,78,14,3,0,0,0,0,0,[ +str_seg('black','Times-Roman',0,80640,78,14,3,0,0,0,0,0,0,0, + "Ipv4EndPoint")]) +]) +])]). +rcbox('black','',132,234,269,267,0,1,1,0,16,476,0,0,0,0,'1',0,[ +]). +text('black',202,338,1,1,1,88,17,488,14,3,2,0,0,0,2,88,17,0,0,"",0,0,0,0,352,'',[ +minilines(88,17,0,0,1,0,0,[ +mini_line(88,14,3,0,0,0,[ +str_block(0,88,14,3,0,0,0,0,0,[ +str_seg('black','Times-Roman',0,80640,88,14,3,0,0,0,0,0,0,0, + "UdpL4Protocol")]) +]) +])]). +rcbox('black','',132,331,269,364,0,1,1,0,16,489,0,0,0,0,'1',0,[ +]). +text('black',202,434,1,1,1,90,17,490,14,3,2,0,0,0,2,90,17,0,0,"",0,0,0,0,448,'',[ +minilines(90,17,0,0,1,0,0,[ +mini_line(90,14,3,0,0,0,[ +str_block(0,90,14,3,0,0,0,0,0,[ +str_seg('black','Times-Roman',0,80640,90,14,3,0,0,0,0,0,0,0, + "Ipv4L3Protocol")]) +]) +])]). +rcbox('black','',132,427,269,460,0,1,1,0,16,491,0,0,0,0,'1',0,[ +]). +text('black',585,11,1,0,1,179,17,496,14,3,0,0,0,0,2,179,17,0,0,"",0,0,0,0,25,'',[ +minilines(179,17,0,0,0,0,0,[ +mini_line(179,14,3,0,0,0,[ +str_block(0,179,14,3,0,-2,0,0,0,[ +str_seg('black','Times-Roman',0,80640,179,14,3,0,-2,1,0,0,0,0, + "Step in packet receive process:")]) +]) +])]). +text('black',480,595,1,0,1,408,17,498,14,3,0,0,0,0,2,408,17,0,0,"",0,0,0,0,609,'',[ +minilines(408,17,0,0,0,0,0,[ +mini_line(408,14,3,0,0,0,[ +str_block(0,408,14,3,0,0,0,0,0,[ +str_seg('black','Times-Roman',0,80640,408,14,3,0,0,0,0,0,0,0, + "1. NetDevice calls the function registered at Node::m_receiveCallback")]) +]) +])]). +text('black',480,572,1,0,1,346,17,520,14,3,0,0,0,0,2,346,17,0,0,"",0,0,0,0,586,'',[ +minilines(346,17,0,0,0,0,0,[ +mini_line(346,14,3,0,0,0,[ +str_block(0,346,14,3,0,0,0,0,0,[ +str_seg('black','Times-Roman',0,80640,346,14,3,0,0,0,0,0,0,0, + "2. This is typically the Node::ReceiveFromDevice() function")]) +]) +])]). +text('black',479,509,3,0,1,460,51,524,14,3,0,0,0,0,2,460,51,0,0,"",0,0,0,0,523,'',[ +minilines(460,51,0,0,0,0,0,[ +mini_line(426,14,3,0,0,0,[ +str_block(0,426,14,3,0,-1,0,0,0,[ +str_seg('black','Times-Roman',0,80640,426,14,3,0,-1,0,0,0,0,0, + "3. Node::ReceiveFromDevice stores a set of callbacks (protocol handlers)")]) +]), +mini_line(460,14,3,0,0,0,[ +str_block(0,460,14,3,0,-1,0,0,0,[ +str_seg('black','Times-Roman',0,80640,460,14,3,0,-1,0,0,0,0,0, + " that are looked up based on protocol number and device. In this case, the lookup")]) +]), +mini_line(300,14,3,0,0,0,[ +str_block(0,300,14,3,0,-1,0,0,0,[ +str_seg('black','Times-Roman',0,80640,300,14,3,0,-1,0,0,0,0,0, + "will result in Ipv4L3Protocol::Receive() being called.")]) +]) +])]). +text('black',480,425,4,0,1,499,68,531,14,3,0,0,0,0,2,499,68,0,0,"",0,0,0,0,439,'',[ +minilines(499,68,0,0,0,0,0,[ +mini_line(475,14,3,0,0,0,[ +str_block(0,475,14,3,0,-2,0,0,0,[ +str_seg('black','Times-Roman',0,80640,475,14,3,0,-2,0,0,0,0,0, + "4. Ipv4L3Protocol removes the IP header, checks checksum (if implemented), and ")]) +]), +mini_line(467,14,3,0,0,0,[ +str_block(0,467,14,3,0,-2,0,0,0,[ +str_seg('black','Times-Roman',0,80640,467,14,3,0,-2,0,0,0,0,0, + "either Forwards the packet or calls ForwardUp(). ForwardUp() then looks up the ")]) +]), +mini_line(499,14,3,0,0,0,[ +str_block(0,499,14,3,0,-1,0,0,0,[ +str_seg('black','Times-Roman',0,80640,499,14,3,0,-1,0,0,0,0,0, + "IP protocol number in an IPv4L4Demux to obtain a pointer to an Ipv4L4Protocol object,")]) +]), +mini_line(191,14,3,0,0,0,[ +str_block(0,191,14,3,0,-1,0,0,0,[ +str_seg('black','Times-Roman',0,80640,191,14,3,0,-1,0,0,0,0,0, + "and calls the ::Receive() method.")]) +]) +])]). +text('black',281,548,1,0,1,140,17,541,14,3,2,0,0,0,2,140,17,0,0,"",0,0,0,0,562,'',[ +minilines(140,17,0,0,0,0,0,[ +mini_line(140,14,3,0,0,0,[ +str_block(0,140,14,3,0,-1,0,0,0,[ +str_seg('black','Times-Roman',0,80640,140,14,3,0,-1,0,0,0,0,0, + "Node::ProtocolHandlers")]) +]) +])]). +rcbox('black','',261,541,398,574,0,1,1,2,16,542,0,0,0,0,'1',0,[ +]). +poly('black','',2,[ + 236,596,327,576],1,1,1,548,0,0,2,0,0,0,0,'1',0,0, + "0","",[ + 0,8,3,0,'8','3','0'],[0,8,3,0,'8','3','0'],[ +]). +text('black',272,590,1,0,1,112,17,550,14,3,0,0,0,0,2,112,17,0,0,"",0,0,0,0,604,'',[ +minilines(112,17,0,0,0,0,0,[ +mini_line(112,14,3,0,0,0,[ +str_block(0,112,14,3,0,0,0,0,0,[ +str_seg('black','Times-Roman',0,80640,112,14,3,0,0,0,0,0,0,0, + "m_receiveCallback")]) +]) +])]). +poly('black','',2,[ + 306,541,202,460],1,1,1,555,0,0,0,0,0,0,0,'1',0,0, + "0","",[ + 0,8,3,0,'8','3','0'],[0,8,3,0,'8','3','0'],[ +]). +poly('black','',2,[ + 280,447,367,423],3,1,1,566,0,0,3,0,0,0,0,'1',0,0, + "0","",[ + 0,8,3,0,'8','3','0'],[0,8,3,0,'8','3','0'],[ +]). +text('black',185,499,1,0,1,65,17,575,14,3,0,0,0,0,2,65,17,0,0,"",0,0,0,0,513,'',[ +minilines(65,17,0,0,0,0,0,[ +mini_line(65,14,3,0,0,0,[ +str_block(0,65,14,3,0,-1,0,0,0,[ +str_seg('black','Times-Roman',0,80640,65,14,3,0,-1,0,0,0,0,0, + "::Receive()")]) +]) +])]). +text('black',315,438,1,0,1,135,17,585,14,3,0,0,0,0,2,135,17,0,0,"",0,0,0,0,452,'',[ +minilines(135,17,0,0,0,0,0,[ +mini_line(135,14,3,0,0,0,[ +str_block(0,135,14,3,0,-1,0,0,0,[ +str_seg('black','Times-Roman',0,80640,135,14,3,0,-1,0,0,0,0,0, + "::GetProtocol(protocol)")]) +]) +])]). +poly('black','',2,[ + 201,426,201,366],1,1,1,593,0,0,0,0,0,0,0,'1',0,0, + "0","",[ + 0,8,3,0,'8','3','0'],[0,8,3,0,'8','3','0'],[ +]). +text('black',211,390,1,0,1,65,17,597,14,3,0,0,0,0,2,65,17,0,0,"",0,0,0,0,404,'',[ +minilines(65,17,0,0,0,0,0,[ +mini_line(65,14,3,0,0,0,[ +str_block(0,65,14,3,0,-1,0,0,0,[ +str_seg('black','Times-Roman',0,80640,65,14,3,0,-1,0,0,0,0,0, + "::Receive()")]) +]) +])]). +text('black',480,291,6,0,1,438,102,612,14,3,0,0,0,0,2,438,102,0,0,"",0,0,0,0,305,'',[ +minilines(438,102,0,0,0,0,0,[ +mini_line(293,14,3,0,0,0,[ +str_block(0,293,14,3,0,0,0,0,0,[ +str_seg('black','Times-Roman',0,80640,293,14,3,0,0,0,0,0,0,0, + "5. UdpL4Protocol is where the socket-independent")]) +]), +mini_line(428,14,3,0,0,0,[ +str_block(0,428,14,3,0,0,0,0,0,[ +str_seg('black','Times-Roman',0,80640,428,14,3,0,0,0,0,0,0,0, + "protocol logic for UDP is implemented. The Receive() method removes the")]) +]), +mini_line(420,14,3,0,0,0,[ +str_block(0,420,14,3,0,0,0,0,0,[ +str_seg('black','Times-Roman',0,80640,420,14,3,0,0,0,0,0,0,0, + "UDP header and looks up the per-flow context state, which is one or more")]) +]), +mini_line(438,14,3,0,0,0,[ +str_block(0,438,14,3,0,-1,0,0,0,[ +str_seg('black','Times-Roman',0,80640,438,14,3,0,-1,0,0,0,0,0, + "Ipv4EndPoint objects stored in an Ipv4EndPointDemux (indexed by src addr,")]) +]), +mini_line(405,14,3,0,0,0,[ +str_block(0,405,14,3,0,-1,0,0,0,[ +str_seg('black','Times-Roman',0,80640,405,14,3,0,-1,0,0,0,0,0, + "src port, dest addr, dest port). It then calls Ipv4EndPoint::ForwardUp()")]) +]), +mini_line(66,14,3,0,0,0,[ +str_block(0,66,14,3,0,-1,0,0,0,[ +str_seg('black','Times-Roman',0,80640,66,14,3,0,-1,0,0,0,0,0, + "when done.")]) +]) +])]). +poly('black','',2,[ + 201,331,201,271],1,1,1,619,0,0,0,0,0,0,0,'1',0,0, + "0","",[ + 0,8,3,0,'8','3','0'],[0,8,3,0,'8','3','0'],[ +]). +text('black',211,295,1,0,1,85,17,620,14,3,0,0,0,0,2,85,17,0,0,"",0,0,0,0,309,'',[ +minilines(85,17,0,0,0,0,0,[ +mini_line(85,14,3,0,0,0,[ +str_block(0,85,14,3,0,-1,0,0,0,[ +str_seg('black','Times-Roman',0,80640,85,14,3,0,-1,0,0,0,0,0, + "::ForwardUp()")]) +]) +])]). +poly('black','',2,[ + 282,335,369,311],3,1,1,630,0,0,3,0,0,0,0,'1',0,0, + "0","",[ + 0,8,3,0,'8','3','0'],[0,8,3,0,'8','3','0'],[ +]). +text('black',317,326,1,0,1,62,17,631,14,3,0,0,0,0,2,62,17,0,0,"",0,0,0,0,340,'',[ +minilines(62,17,0,0,0,0,0,[ +mini_line(62,14,3,0,0,0,[ +str_block(0,62,14,3,0,-1,0,0,0,[ +str_seg('black','Times-Roman',0,80640,62,14,3,0,-1,0,0,0,0,0, + "::Lookup()")]) +]) +])]). +text('black',211,208,1,0,1,181,17,650,14,3,0,0,0,0,2,181,17,0,0,"",0,0,0,0,222,'',[ +minilines(181,17,0,0,0,0,0,[ +mini_line(181,14,3,0,0,0,[ +str_block(0,181,14,3,0,-1,0,0,0,[ +str_seg('black','Times-Roman',0,80640,181,14,3,0,-1,0,0,0,0,0, + "(m_rxCallback)->ForwardUp()")]) +]) +])]). +poly('black','',2,[ + 201,233,201,196],1,1,1,652,0,0,0,0,0,0,0,'1',0,0, + "0","",[ + 0,8,3,0,'8','3','0'],[0,8,3,0,'8','3','0'],[ +]). +text('black',211,138,1,0,1,144,17,656,14,3,0,0,0,0,2,144,17,0,0,"",0,0,0,0,152,'',[ +minilines(144,17,0,0,0,0,0,[ +mini_line(144,14,3,0,0,0,[ +str_block(0,144,14,3,0,-1,0,0,0,[ +str_seg('black','Times-Roman',0,80640,144,14,3,0,-1,0,0,0,0,0, + "(m_rxCallback)->Recv()")]) +]) +])]). +text('black',149,17,1,0,1,321,21,683,17,4,0,0,0,0,2,321,21,0,0,"",0,0,0,0,34,'',[ +minilines(321,21,0,0,0,0,0,[ +mini_line(321,17,4,0,0,0,[ +str_block(0,321,17,4,0,0,0,0,0,[ +str_seg('black','Times-Roman',0,103680,321,17,4,0,0,0,0,0,0,0, + "Function/object trace for receiving a packet")]) +]) +])]). +poly('black','',2,[ + 199,163,199,126],1,1,1,691,0,0,0,0,0,0,0,'1',0,0, + "0","",[ + 0,8,3,0,'8','3','0'],[0,8,3,0,'8','3','0'],[ +]). +group([ +text('black',311,280,1,0,1,120,17,484,14,3,0,0,0,0,2,120,17,0,0,"",0,0,0,0,294,'',[ +minilines(120,17,0,0,0,0,0,[ +mini_line(120,14,3,0,0,0,[ +str_block(0,120,14,3,0,0,0,0,0,[ +str_seg('black','Times-Roman',0,80640,120,14,3,0,0,0,0,0,0,0, + "Ipv4EndPointDemux")]) +]) +])]), +polygon('black','',6,[ + 309,276,324,305,419,305,439,277,309,277,309,276],0,1,1,0,485,0,0,0,0,0,'1',0, + "00",[ +]) +], +704,0,0,[ +]). +text('black',480,190,3,0,1,363,51,708,14,3,0,0,0,0,2,363,51,0,0,"",0,0,0,0,204,'',[ +minilines(363,51,0,0,0,0,0,[ +mini_line(363,14,3,0,0,0,[ +str_block(0,363,14,3,0,-1,0,0,0,[ +str_seg('black','Times-Roman',0,80640,363,14,3,0,-1,0,0,0,0,0, + "6. Ipv4EndPoint has a callback where a Socket object is able to")]) +]), +mini_line(304,14,3,0,0,0,[ +str_block(0,304,14,3,0,-1,0,0,0,[ +str_seg('black','Times-Roman',0,80640,304,14,3,0,-1,0,0,0,0,0, + "register a receive method. Here, this callback calls to")]) +]), +mini_line(175,14,3,0,0,0,[ +str_block(0,175,14,3,0,-1,0,0,0,[ +str_seg('black','Times-Roman',0,80640,175,14,3,0,-1,0,0,0,0,0, + "UdpSocketImpl::ForwardUp()")]) +]) +])]). +text('black',480,106,3,0,1,446,51,712,14,3,0,0,0,0,2,446,51,0,0,"",0,0,0,0,120,'',[ +minilines(446,51,0,0,0,0,0,[ +mini_line(407,14,3,0,0,0,[ +str_block(0,407,14,3,0,0,0,0,0,[ +str_seg('black','Times-Roman',0,80640,407,14,3,0,0,0,0,0,0,0, + "7. UdpSocketImpl itself calls the Recv() callback set by the Application")]) +]), +mini_line(402,14,3,0,0,0,[ +str_block(0,402,14,3,0,0,0,0,0,[ +str_seg('black','Times-Roman',0,80640,402,14,3,0,0,0,0,0,0,0, + "when data is ready to be read. The application can then call the socket")]) +]), +mini_line(446,14,3,0,0,0,[ +str_block(0,446,14,3,0,-1,0,0,0,[ +str_seg('black','Times-Roman',0,80640,446,14,3,0,-1,0,0,0,0,0, + "Recv() or RecvFrom() methods to read data (or dummy data) from the socket.")]) +]) +])]). +group([ +text('black',308,393,1,0,1,96,17,772,14,3,0,0,0,0,2,96,17,0,0,"",0,0,0,0,407,'',[ +minilines(96,17,0,0,0,0,0,[ +mini_line(96,14,3,0,0,0,[ +str_block(0,96,14,3,0,0,0,0,0,[ +str_seg('black','Times-Roman',0,80640,96,14,3,0,0,0,0,0,0,0, + " Ipv4L4Demux")]) +]) +])]), +polygon('black','',6,[ + 306,389,321,418,416,418,436,390,306,390,306,389],0,1,1,0,771,0,0,0,0,0,'1',0, + "00",[ +]) +], +770,0,0,[ +]). diff --git a/doc/manual/figures/internet-node-send.obj b/doc/manual/figures/internet-node-send.obj new file mode 100644 index 000000000..6f96da758 --- /dev/null +++ b/doc/manual/figures/internet-node-send.obj @@ -0,0 +1,352 @@ +%TGIF 4.1.43-QPL +state(0,37,100.000,83,0,0,16,0,9,1,1,0,0,3,2,1,0,'Times-Roman',0,80640,0,3,0,10,0,0,1,1,0,16,0,0,1,1,1,1,1088,1408,1,0,2880,0). +% +% @(#)$Header$ +% %W% +% +unit("1 pixel/pixel"). +color_info(11,65535,0,[ + "magenta", 65535, 0, 65535, 65535, 0, 65535, 1, + "red", 65535, 0, 0, 65535, 0, 0, 1, + "green", 0, 65535, 0, 0, 65535, 0, 1, + "blue", 0, 0, 65535, 0, 0, 65535, 1, + "yellow", 65535, 65535, 0, 65535, 65535, 0, 1, + "pink", 65535, 49344, 52171, 65535, 49344, 52171, 1, + "cyan", 0, 65535, 65535, 0, 65535, 65535, 1, + "CadetBlue", 24415, 40606, 41120, 24415, 40606, 41120, 1, + "white", 65535, 65535, 65535, 65535, 65535, 65535, 1, + "black", 0, 0, 0, 0, 0, 0, 1, + "DarkSlateGray", 12079, 20303, 20303, 12079, 20303, 20303, 1 +]). +script_frac("0.6"). +fg_bg_colors('black','white'). +dont_reencode("FFDingbests:ZapfDingbats"). +page(1,"",1,''). +group([ +rcbox('black','',158,451,238,499,2,1,1,0,16,125,0,0,0,0,'1',0,[ +]), +text('black',158,470,1,0,1,72,18,124,13,5,0,0,0,0,2,72,18,0,0,"",0,0,0,0,483,'',[ +minilines(72,18,0,0,0,0,0,[ +mini_line(72,13,5,0,0,0,[ +str_block(0,72,13,5,0,0,0,0,0,[ +str_seg('black','Courier',0,80640,72,13,5,0,0,0,0,0,0,0, + "NetDevice")]) +]) +])]) +], +141,0,0,[ +]). +group([ +rcbox('black','',147,77,255,125,2,1,1,0,16,354,0,0,0,0,'1',0,[ +]), +text('black',163,96,1,0,1,88,18,353,13,5,0,0,0,0,2,88,18,0,0,"",0,0,0,0,109,'',[ +minilines(88,18,0,0,0,0,0,[ +mini_line(88,13,5,0,0,0,[ +str_block(0,88,13,5,0,0,0,0,0,[ +str_seg('black','Courier',0,80640,88,13,5,0,0,0,0,0,0,0, + "Application")]) +]) +])]) +], +352,0,0,[ +]). +text('black',202,172,1,1,1,90,17,473,14,3,2,0,0,0,2,90,17,0,0,"",0,0,0,0,186,'',[ +minilines(90,17,0,0,1,0,0,[ +mini_line(90,14,3,0,0,0,[ +str_block(0,90,14,3,0,0,0,0,0,[ +str_seg('black','Times-Roman',0,80640,90,14,3,0,0,0,0,0,0,0, + "UdpSocketImpl")]) +]) +])]). +rcbox('black','',132,165,269,198,0,1,1,0,16,474,0,0,0,0,'1',0,[ +]). +text('black',202,241,1,1,1,88,17,475,14,3,2,0,0,0,2,88,17,0,0,"",0,0,0,0,255,'',[ +minilines(88,17,0,0,1,0,0,[ +mini_line(88,14,3,0,0,0,[ +str_block(0,88,14,3,0,0,0,0,0,[ +str_seg('black','Times-Roman',0,80640,88,14,3,0,0,0,0,0,0,0, + "UdpL4Protocol")]) +]) +])]). +rcbox('black','',132,234,269,267,0,1,1,0,16,476,0,0,0,0,'1',0,[ +]). +text('black',201,317,1,1,1,90,17,490,14,3,2,0,0,0,2,90,17,0,0,"",0,0,0,0,331,'',[ +minilines(90,17,0,0,1,0,0,[ +mini_line(90,14,3,0,0,0,[ +str_block(0,90,14,3,0,0,0,0,0,[ +str_seg('black','Times-Roman',0,80640,90,14,3,0,0,0,0,0,0,0, + "Ipv4L3Protocol")]) +]) +])]). +rcbox('black','',131,310,268,343,0,1,1,0,16,491,0,0,0,0,'1',0,[ +]). +text('black',540,56,1,0,1,180,17,496,14,3,0,0,0,0,2,180,17,0,0,"",0,0,0,0,70,'',[ +minilines(180,17,0,0,0,0,0,[ +mini_line(180,14,3,0,0,0,[ +str_block(0,180,14,3,0,-2,0,0,0,[ +str_seg('black','Times-Roman',0,80640,180,14,3,0,-2,1,0,0,0,0, + "Step in packet sending process:")]) +]) +])]). +text('black',480,420,4,0,1,460,68,524,14,3,0,0,0,0,2,460,68,0,0,"",0,0,0,0,434,'',[ +minilines(460,68,0,0,0,0,0,[ +mini_line(457,14,3,0,0,0,[ +str_block(0,457,14,3,0,0,0,0,0,[ +str_seg('black','Times-Roman',0,80640,457,14,3,0,0,0,0,0,0,0, + "5. Ipv4Interface is an abstract base class; here, we depict the ArpIpv4Interface")]) +]), +mini_line(460,14,3,0,0,0,[ +str_block(0,460,14,3,0,-1,0,0,0,[ +str_seg('black','Times-Roman',0,80640,460,14,3,0,-1,0,0,0,0,0, + "concrete class. This object looks up the MAC address if Arp is supported on this")]) +]), +mini_line(454,14,3,0,0,0,[ +str_block(0,454,14,3,0,0,0,0,0,[ +str_seg('black','Times-Roman',0,80640,454,14,3,0,0,0,0,0,0,0, + "NetDevice technology, and if there is a cache hit, it sends it to the NetDevice, or")]) +]), +mini_line(197,14,3,0,0,0,[ +str_block(0,197,14,3,0,-1,0,0,0,[ +str_seg('black','Times-Roman',0,80640,197,14,3,0,-1,0,0,0,0,0, + "else it first initiates an Arp request.")]) +]) +])]). +text('black',479,354,3,0,1,476,51,531,14,3,0,0,0,0,2,476,51,0,0,"",0,0,0,0,368,'',[ +minilines(476,51,0,0,0,0,0,[ +mini_line(469,14,3,0,0,0,[ +str_block(0,469,14,3,0,0,0,0,0,[ +str_seg('black','Times-Roman',0,80640,469,14,3,0,0,0,0,0,0,0, + "4. Ipv4L3Protocol adds the IP header, looks up a route, and sends the packet to an")]) +]), +mini_line(476,14,3,0,0,0,[ +str_block(0,476,14,3,0,-1,0,0,0,[ +str_seg('black','Times-Roman',0,80640,476,14,3,0,-1,0,0,0,0,0, + "appropriate Ipv4Interface instance. In this example, the device is one that supports")]) +]), +mini_line(322,14,3,0,0,0,[ +str_block(0,322,14,3,0,-1,0,0,0,[ +str_seg('black','Times-Roman',0,80640,322,14,3,0,-1,0,0,0,0,0, + "Arp, so the packet is sent to an ArpIpv4Interface object.")]) +]) +])]). +text('black',478,261,4,0,1,437,68,612,14,3,0,0,0,0,2,437,68,0,0,"",0,0,0,0,275,'',[ +minilines(437,68,0,0,0,0,0,[ +mini_line(293,14,3,0,0,0,[ +str_block(0,293,14,3,0,0,0,0,0,[ +str_seg('black','Times-Roman',0,80640,293,14,3,0,0,0,0,0,0,0, + "3. UdpL4Protocol is where the socket-independent")]) +]), +mini_line(387,14,3,0,0,0,[ +str_block(0,387,14,3,0,0,0,0,0,[ +str_seg('black','Times-Roman',0,80640,387,14,3,0,0,0,0,0,0,0, + "protocol logic for UDP is implemented. The Send() method adds the")]) +]), +mini_line(437,14,3,0,0,0,[ +str_block(0,437,14,3,0,-1,0,0,0,[ +str_seg('black','Times-Roman',0,80640,437,14,3,0,-1,0,0,0,0,0, + "UDP header, initializes the checksum, and sends the packet to the Ipv4 layer.")]) +]), +mini_line(431,14,3,0,0,0,[ +str_block(0,431,14,3,0,-1,0,0,0,[ +str_seg('black','Times-Roman',0,80640,431,14,3,0,-1,0,0,0,0,0, + "Here, the Ipv4L3Protocol object is queried, and the Send() method is called.")]) +]) +])]). +poly('black','',2,[ + 201,308,201,271],2,1,1,619,0,0,0,0,0,0,0,'1',0,0, + "0","",[ + 0,8,3,0,'8','3','0'],[0,8,3,0,'8','3','0'],[ +]). +text('black',208,278,1,0,1,47,17,620,14,3,0,0,0,0,2,47,17,0,0,"",0,0,0,0,292,'',[ +minilines(47,17,0,0,0,0,0,[ +mini_line(47,14,3,0,0,0,[ +str_block(0,47,14,3,0,-1,0,0,0,[ +str_seg('black','Times-Roman',0,80640,47,14,3,0,-1,0,0,0,0,0, + "::Send()")]) +]) +])]). +text('black',211,208,1,0,1,47,17,650,14,3,0,0,0,0,2,47,17,0,0,"",0,0,0,0,222,'',[ +minilines(47,17,0,0,0,0,0,[ +mini_line(47,14,3,0,0,0,[ +str_block(0,47,14,3,0,-1,0,0,0,[ +str_seg('black','Times-Roman',0,80640,47,14,3,0,-1,0,0,0,0,0, + "::Send()")]) +]) +])]). +poly('black','',2,[ + 201,233,201,196],2,1,1,652,0,0,0,0,0,0,0,'1',0,0, + "0","",[ + 0,8,3,0,'8','3','0'],[0,8,3,0,'8','3','0'],[ +]). +text('black',211,138,1,0,1,87,17,656,14,3,0,0,0,0,2,87,17,0,0,"",0,0,0,0,152,'',[ +minilines(87,17,0,0,0,0,0,[ +mini_line(87,14,3,0,0,0,[ +str_block(0,87,14,3,0,-1,0,0,0,[ +str_seg('black','Times-Roman',0,80640,87,14,3,0,-1,0,0,0,0,0, + "Socket::Send()")]) +]) +])]). +text('black',149,17,1,0,1,310,21,683,17,4,0,0,0,0,2,310,21,0,0,"",0,0,0,0,34,'',[ +minilines(310,21,0,0,0,0,0,[ +mini_line(310,17,4,0,0,0,[ +str_block(0,310,17,4,0,0,0,0,0,[ +str_seg('black','Times-Roman',0,103680,310,17,4,0,0,0,0,0,0,0, + "Function/object trace for sending a packet")]) +]) +])]). +poly('black','',2,[ + 199,163,199,126],2,1,1,691,0,0,0,0,0,0,0,'1',0,0, + "0","",[ + 0,8,3,0,'8','3','0'],[0,8,3,0,'8','3','0'],[ +]). +text('black',480,153,6,0,1,524,102,708,14,3,0,0,0,0,2,524,102,0,0,"",0,0,0,0,167,'',[ +minilines(524,102,0,0,0,0,0,[ +mini_line(399,14,3,0,0,0,[ +str_block(0,399,14,3,0,-2,0,0,0,[ +str_seg('black','Times-Roman',0,80640,399,14,3,0,-2,0,0,0,0,0, + "2. Socket::Send() forwards to UdpSocketImpl::DoSend() and later to ")]) +]), +mini_line(173,14,3,0,0,0,[ +str_block(0,173,14,3,0,-1,0,0,0,[ +str_seg('black','Times-Roman',0,80640,173,14,3,0,-1,0,0,0,0,0, + "UdpSocketImpl::DoSendTo().")]) +]), +mini_line(479,14,3,0,0,0,[ +str_block(0,479,14,3,0,-1,0,0,0,[ +str_seg('black','Times-Roman',0,80640,479,14,3,0,-1,0,0,0,0,0, + "These functions set the proper source and destination addresses, handle socket calls")]) +]), +mini_line(524,14,3,0,0,0,[ +str_block(0,524,14,3,0,-2,0,0,0,[ +str_seg('black','Times-Roman',0,80640,524,14,3,0,-2,0,0,0,0,0, + "such as bind() and connect() and then the UdpL4Protocol::Send() function is called. As in a ")]) +]), +mini_line(505,14,3,0,0,0,[ +str_block(0,505,14,3,0,-1,0,0,0,[ +str_seg('black','Times-Roman',0,80640,505,14,3,0,-1,0,0,0,0,0, + "real implementation, the socket must query the Ipv4 layer to find the right source address")]) +]), +mini_line(187,14,3,0,0,0,[ +str_block(0,187,14,3,0,-1,0,0,0,[ +str_seg('black','Times-Roman',0,80640,187,14,3,0,-1,0,0,0,0,0, + "to match the destination address.")]) +]) +])]). +text('black',480,106,2,0,1,434,34,712,14,3,0,0,0,0,2,434,34,0,0,"",0,0,0,0,120,'',[ +minilines(434,34,0,0,0,0,0,[ +mini_line(413,14,3,0,0,0,[ +str_block(0,413,14,3,0,-1,0,0,0,[ +str_seg('black','Times-Roman',0,80640,413,14,3,0,-1,0,0,0,0,0, + "1. The Application has previously created a socket (here, a UdpSocket).")]) +]), +mini_line(434,14,3,0,0,0,[ +str_block(0,434,14,3,0,-1,0,0,0,[ +str_seg('black','Times-Roman',0,80640,434,14,3,0,-1,0,0,0,0,0, + "It calls Socket::Send(). Either real data or dummy data is passed at the API.")]) +]) +])]). +text('black',377,315,1,1,1,60,17,774,14,3,2,0,0,0,2,60,17,0,0,"",0,0,0,0,329,'',[ +minilines(60,17,0,0,1,0,0,[ +mini_line(60,14,3,0,0,0,[ +str_block(0,60,14,3,0,0,0,0,0,[ +str_seg('black','Times-Roman',0,80640,60,14,3,0,0,0,0,0,0,0, + "Ipv4Route")]) +]) +])]). +rcbox('black','',307,308,444,341,0,1,1,0,16,775,0,0,0,0,'1',0,[ +]). +poly('black','',2,[ + 267,325,304,325],3,1,1,787,0,0,3,0,0,0,0,'1',0,0, + "0","",[ + 0,8,3,0,'8','3','0'],[0,8,3,0,'8','3','0'],[ +]). +text('black',278,299,1,0,1,62,17,796,14,3,2,0,0,0,2,62,17,0,0,"",0,0,0,0,313,'',[ +minilines(62,17,0,0,0,0,0,[ +mini_line(62,14,3,0,0,0,[ +str_block(0,62,14,3,0,-1,0,0,0,[ +str_seg('black','Times-Roman',0,80640,62,14,3,0,-1,0,0,0,0,0, + "::Lookup()")]) +]) +])]). +text('black',200,385,1,1,1,102,17,803,14,3,2,0,0,0,2,102,17,0,0,"",0,0,0,0,399,'',[ +minilines(102,17,0,0,1,0,0,[ +mini_line(102,14,3,0,0,0,[ +str_block(0,102,14,3,0,0,0,0,0,[ +str_seg('black','Times-Roman',0,80640,102,14,3,0,0,0,0,0,0,0, + "ArpIpv4Interface")]) +]) +])]). +rcbox('black','',130,378,267,411,0,1,1,0,16,804,0,0,0,0,'1',0,[ +]). +poly('black','',2,[ + 199,380,199,343],2,1,1,810,0,0,0,0,0,0,0,'1',0,0, + "0","",[ + 0,8,3,0,'8','3','0'],[0,8,3,0,'8','3','0'],[ +]). +text('black',206,350,1,0,1,47,17,811,14,3,0,0,0,0,2,47,17,0,0,"",0,0,0,0,364,'',[ +minilines(47,17,0,0,0,0,0,[ +mini_line(47,14,3,0,0,0,[ +str_block(0,47,14,3,0,-1,0,0,0,[ +str_seg('black','Times-Roman',0,80640,47,14,3,0,-1,0,0,0,0,0, + "::Send()")]) +]) +])]). +text('black',378,388,1,1,1,71,17,817,14,3,2,0,0,0,2,71,17,0,0,"",0,0,0,0,402,'',[ +minilines(71,17,0,0,1,0,0,[ +mini_line(71,14,3,0,0,0,[ +str_block(0,71,14,3,0,0,0,0,0,[ +str_seg('black','Times-Roman',0,80640,71,14,3,0,0,0,0,0,0,0, + "ArpProtocol")]) +]) +])]). +rcbox('black','',308,381,445,414,0,1,1,0,16,818,0,0,0,0,'1',0,[ +]). +poly('black','',2,[ + 268,398,305,398],3,1,1,819,0,0,3,0,0,0,0,'1',0,0, + "0","",[ + 0,8,3,0,'8','3','0'],[0,8,3,0,'8','3','0'],[ +]). +text('black',279,372,1,0,1,62,17,820,14,3,2,0,0,0,2,62,17,0,0,"",0,0,0,0,386,'',[ +minilines(62,17,0,0,0,0,0,[ +mini_line(62,14,3,0,0,0,[ +str_block(0,62,14,3,0,-1,0,0,0,[ +str_seg('black','Times-Roman',0,80640,62,14,3,0,-1,0,0,0,0,0, + "::Lookup()")]) +]) +])]). +poly('black','',2,[ + 199,448,199,411],2,1,1,837,0,0,0,0,0,0,0,'1',0,0, + "0","",[ + 0,8,3,0,'8','3','0'],[0,8,3,0,'8','3','0'],[ +]). +text('black',206,418,1,0,1,47,17,838,14,3,0,0,0,0,2,47,17,0,0,"",0,0,0,0,432,'',[ +minilines(47,17,0,0,0,0,0,[ +mini_line(47,14,3,0,0,0,[ +str_block(0,47,14,3,0,-1,0,0,0,[ +str_seg('black','Times-Roman',0,80640,47,14,3,0,-1,0,0,0,0,0, + "::Send()")]) +]) +])]). +text('black',371,173,1,1,1,26,17,842,14,3,2,0,0,0,2,26,17,0,0,"",0,0,0,0,187,'',[ +minilines(26,17,0,0,1,0,0,[ +mini_line(26,14,3,0,0,0,[ +str_block(0,26,14,3,0,-1,0,0,0,[ +str_seg('black','Times-Roman',0,80640,26,14,3,0,-1,0,0,0,0,0, + "Ipv4")]) +]) +])]). +rcbox('black','',301,166,438,199,0,1,1,0,16,843,0,0,0,0,'1',0,[ +]). +text('black',272,157,1,0,1,148,17,844,14,3,2,0,0,0,2,148,17,0,0,"",0,0,0,0,171,'',[ +minilines(148,17,0,0,0,0,0,[ +mini_line(148,14,3,0,0,0,[ +str_block(0,148,14,3,0,-1,0,0,0,[ +str_seg('black','Times-Roman',0,80640,148,14,3,0,-1,0,0,0,0,0, + "::GetAddress(outgoing if)")]) +]) +])]). +poly('black','',2,[ + 269,182,306,182],3,1,1,846,0,0,3,0,0,0,0,'1',0,0, + "0","",[ + 0,8,3,0,'8','3','0'],[0,8,3,0,'8','3','0'],[ +]). diff --git a/doc/manual/figures/node.obj b/doc/manual/figures/node.obj new file mode 100644 index 000000000..215463aec --- /dev/null +++ b/doc/manual/figures/node.obj @@ -0,0 +1,211 @@ +%TGIF 4.1.43-QPL +state(0,37,100.000,0,0,0,16,0,9,1,1,0,0,3,2,1,0,'Times-Italic',2,80640,0,8,0,10,0,0,1,1,0,16,0,0,1,1,1,1,1088,1408,1,0,2880,0). +% +% @(#)$Header$ +% %W% +% +unit("1 pixel/pixel"). +color_info(11,65535,0,[ + "magenta", 65535, 0, 65535, 65535, 0, 65535, 1, + "red", 65535, 0, 0, 65535, 0, 0, 1, + "green", 0, 65535, 0, 0, 65535, 0, 1, + "blue", 0, 0, 65535, 0, 0, 65535, 1, + "yellow", 65535, 65535, 0, 65535, 65535, 0, 1, + "pink", 65535, 49344, 52171, 65535, 49344, 52171, 1, + "cyan", 0, 65535, 65535, 0, 65535, 65535, 1, + "CadetBlue", 24415, 40606, 41120, 24415, 40606, 41120, 1, + "white", 65535, 65535, 65535, 65535, 65535, 65535, 1, + "black", 0, 0, 0, 0, 0, 0, 1, + "DarkSlateGray", 12079, 20303, 20303, 12079, 20303, 20303, 1 +]). +script_frac("0.6"). +fg_bg_colors('black','white'). +dont_reencode("FFDingbests:ZapfDingbats"). +page(1,"",1,''). +rcbox('black','',64,64,400,384,0,1,1,0,16,0,0,0,0,0,'1',0,[ +]). +box('black','',280,432,555,464,0,1,1,17,0,0,0,0,0,'1',0,[ +]). +text('black',384,435,1,0,1,56,18,18,13,5,0,0,0,0,2,56,18,0,0,"",0,0,0,0,448,'',[ +minilines(56,18,0,0,0,0,0,[ +mini_line(56,13,5,0,0,0,[ +str_block(0,56,13,5,0,-1,0,0,0,[ +str_seg('black','Courier-Bold',1,80640,56,13,5,0,-1,0,0,0,0,0, + "Channel")]) +]) +])]). +text('black',76,42,1,0,1,208,18,108,13,5,2,0,0,0,2,208,18,0,0,"",0,0,0,0,55,'',[ +minilines(208,18,0,0,0,0,0,[ +mini_line(208,13,5,0,0,0,[ +str_block(0,208,13,5,0,0,0,0,0,[ +str_seg('black','Courier-Bold',1,80640,208,13,5,0,0,0,0,0,0,0, + "class Node : public Object")]) +]) +])]). +group([ +rcbox('black','',112,304,192,352,2,1,1,0,16,134,0,0,0,0,'1',0,[ +]), +text('black',112,323,1,0,1,72,18,135,13,5,0,0,0,0,2,72,18,0,0,"",0,0,0,0,336,'',[ +minilines(72,18,0,0,0,0,0,[ +mini_line(72,13,5,0,0,0,[ +str_block(0,72,13,5,0,0,0,0,0,[ +str_seg('black','Courier',0,80640,72,13,5,0,0,0,0,0,0,0, + "NetDevice")]) +]) +])]) +], +138,0,0,[ +]). +group([ +rcbox('black','',266,304,346,352,2,1,1,0,16,125,0,0,0,0,'1',0,[ +]), +text('black',266,323,1,0,1,72,18,124,13,5,0,0,0,0,2,72,18,0,0,"",0,0,0,0,336,'',[ +minilines(72,18,0,0,0,0,0,[ +mini_line(72,13,5,0,0,0,[ +str_block(0,72,13,5,0,0,0,0,0,[ +str_seg('black','Courier',0,80640,72,13,5,0,0,0,0,0,0,0, + "NetDevice")]) +]) +])]) +], +141,0,0,[ +]). +poly('black','',2,[ + 304,351,304,430],3,1,1,167,0,2,0,0,0,0,0,'1',0,0, + "0","",[ + 0,8,3,0,'8','3','0'],[0,8,3,0,'8','3','0'],[ +]). +text('black',219,304,1,0,1,24,37,177,30,7,2,0,0,0,2,24,37,0,0,"",0,0,0,0,334,'',[ +minilines(24,37,0,0,0,0,0,[ +mini_line(24,30,7,0,0,0,[ +str_block(0,24,30,7,0,-2,0,0,0,[ +str_seg('black','Times-Bold',1,195840,24,30,7,0,-2,0,0,0,0,0, + "...")]) +]) +])]). +text('black',220,98,1,0,1,24,37,182,30,7,2,0,0,0,2,24,37,0,0,"",0,0,0,0,128,'',[ +minilines(24,37,0,0,0,0,0,[ +mini_line(24,30,7,0,0,0,[ +str_block(0,24,30,7,0,-2,0,0,0,[ +str_seg('black','Times-Bold',1,195840,24,30,7,0,-2,0,0,0,0,0, + "...")]) +]) +])]). +text('black',420,116,2,0,1,136,36,183,13,5,2,0,0,0,2,136,36,0,0,"",0,0,0,0,129,'',[ +minilines(136,36,0,0,0,0,0,[ +mini_line(136,13,5,0,0,0,[ +str_block(0,136,13,5,0,0,0,0,0,[ +str_seg('black','Courier-Bold',1,80640,136,13,5,0,0,0,0,0,0,0, + "Unix-like C-based")]) +]), +mini_line(80,13,5,0,0,0,[ +str_block(0,80,13,5,0,-1,0,0,0,[ +str_seg('black','Courier-Bold',1,80640,80,13,5,0,-1,0,0,0,0,0, + "socket API")]) +]) +])]). +text('black',414,212,3,0,1,232,54,198,13,5,2,0,0,0,2,232,54,0,0,"",0,0,0,0,225,'',[ +minilines(232,54,0,0,0,0,0,[ +mini_line(112,13,5,0,0,0,[ +str_block(0,112,13,5,0,0,0,0,0,[ +str_seg('black','Courier-Bold',1,80640,112,13,5,0,0,0,0,0,0,0, + "Callback-based")]) +]), +mini_line(176,13,5,0,0,0,[ +str_block(0,176,13,5,0,0,0,0,0,[ +str_seg('black','Courier-Bold',1,80640,176,13,5,0,0,0,0,0,0,0, + "protocol demultiplexer")]) +]), +mini_line(232,13,5,0,0,0,[ +str_block(0,8,13,5,0,-1,0,0,0,[ +str_seg('black','Courier-Bold',1,80640,8,13,5,0,-1,0,0,0,0,0, + "(")]), +str_block(0,216,13,3,0,-2,0,0,0,[ +str_seg('black','Courier-Oblique',2,80640,216,13,3,0,-2,0,0,0,0,0, + "list of ProtocolHandlers")]), +str_block(0,8,13,5,0,-2,0,0,0,[ +str_seg('black','Courier-Bold',1,80640,8,13,5,0,-2,0,0,0,0,0, + ")")]) +]) +])]). +poly('black','',2,[ + 410,231,222,259],1,1,1,200,0,2,2,0,0,0,0,'1',0,0, + "0","",[ + 0,8,3,0,'8','3','0'],[0,8,3,0,'8','3','0'],[ +]). +box('black','',56,401,229,433,0,1,1,250,0,0,0,0,0,'1',0,[ +]). +text('black',119,409,1,0,1,56,18,251,13,5,0,0,0,0,2,56,18,0,0,"",0,0,0,0,422,'',[ +minilines(56,18,0,0,0,0,0,[ +mini_line(56,13,5,0,0,0,[ +str_block(0,56,13,5,0,-1,0,0,0,[ +str_seg('black','Courier-Bold',1,80640,56,13,5,0,-1,0,0,0,0,0, + "Channel")]) +]) +])]). +poly('black','',2,[ + 154,353,154,400],3,1,1,254,0,2,0,0,0,0,0,'1',0,0, + "0","",[ + 0,8,3,0,'8','3','0'],[0,8,3,0,'8','3','0'],[ +]). +group([ +rcbox('black','',98,96,206,144,2,1,1,0,16,1,0,0,0,0,'1',0,[ +]), +text('black',114,115,1,0,1,88,18,2,13,5,0,0,0,0,2,88,18,0,0,"",0,0,0,0,128,'',[ +minilines(88,18,0,0,0,0,0,[ +mini_line(88,13,5,0,0,0,[ +str_block(0,88,13,5,0,0,0,0,0,[ +str_seg('black','Courier',0,80640,88,13,5,0,0,0,0,0,0,0, + "Application")]) +]) +])]) +], +348,0,0,[ +]). +group([ +rcbox('black','',257,96,365,144,2,1,1,0,16,354,0,0,0,0,'1',0,[ +]), +text('black',273,115,1,0,1,88,18,353,13,5,0,0,0,0,2,88,18,0,0,"",0,0,0,0,128,'',[ +minilines(88,18,0,0,0,0,0,[ +mini_line(88,13,5,0,0,0,[ +str_block(0,88,13,5,0,0,0,0,0,[ +str_seg('black','Courier',0,80640,88,13,5,0,0,0,0,0,0,0, + "Application")]) +]) +])]) +], +352,0,0,[ +]). +text('black',155,73,1,0,1,110,18,426,14,4,2,0,0,0,2,110,18,0,0,"",0,0,0,0,87,'',[ +minilines(110,18,0,0,0,0,0,[ +mini_line(110,14,4,0,0,0,[ +str_block(0,110,14,4,0,-1,0,0,0,[ +str_seg('black','Times-Italic',2,80640,110,14,4,0,-1,0,0,0,0,0, + "list of Applications")]) +]) +])]). +text('black',161,357,1,0,1,106,18,443,14,4,2,0,0,0,2,106,18,0,0,"",0,0,0,0,371,'',[ +minilines(106,18,0,0,0,0,0,[ +mini_line(106,14,4,0,0,0,[ +str_block(0,106,14,4,0,-1,0,0,0,[ +str_seg('black','Times-Italic',2,80640,106,14,4,0,-1,0,0,0,0,0, + "list of NetDevices")]) +]) +])]). +text('black',79,194,2,0,1,55,36,482,14,4,2,0,0,0,2,55,36,0,0,"",0,0,0,0,208,'',[ +minilines(55,36,0,0,0,0,0,[ +mini_line(53,14,4,0,0,0,[ +str_block(0,53,14,4,0,0,0,0,0,[ +str_seg('black','Times-Italic',2,80640,53,14,4,0,0,0,0,0,0,0, + "unique id")]) +]), +mini_line(55,14,4,0,0,0,[ +str_block(0,55,14,4,0,0,0,0,0,[ +str_seg('black','Times-Italic',2,80640,55,14,4,0,0,0,0,0,0,0, + "system id")]) +]) +])]). +polygon('black','',7,[ + 158,271,305,271,288,291,173,291,159,273,160,273,158,271],2,1,1,0,493,8,0,0,0,0,'1',0, + "00",[ +]). diff --git a/doc/manual/manual.texi b/doc/manual/manual.texi index cbffee08b..2d5cb2d02 100644 --- a/doc/manual/manual.texi +++ b/doc/manual/manual.texi @@ -83,6 +83,7 @@ see @uref{http://www.nsnam.org/docs/manual.pdf}. * Attributes:: * Packets:: * Sockets APIs:: +* Node and Internet Stack:: * Routing overview:: * Troubleshooting @end menu @@ -92,6 +93,7 @@ see @uref{http://www.nsnam.org/docs/manual.pdf}. @include attributes.texi @include packets.texi @include sockets.texi +@include node.texi @c @include output.texi @include routing.texi @c @include other.texi diff --git a/doc/manual/node.texi b/doc/manual/node.texi new file mode 100644 index 000000000..31d8b8561 --- /dev/null +++ b/doc/manual/node.texi @@ -0,0 +1,358 @@ +@node Node and Internet Stack +@chapter Node and Internet Stack +@anchor{chap:Node} + +This chapter describes how ns-3 nodes are put together, and provides +a walk-through of how packets traverse an internet-based Node. + +@float Figure,fig:node +@caption{High-level node architecture.} +@image{figures/node,5in} +@end float + +In ns-3, nodes are instances of @code{class Node}. This class +may be subclassed, but instead, the conceptual model is that +we @emph{aggregate} or insert objects to it rather than define +subclasses. + +One might think of a bare ns-3 node as a shell of a computer, +to which one may add NetDevices (cards) and other innards including +the protocols and applications. @ref{fig:node} illustrates +that Node objects contain a list of Applications (initially, +the list is empty), a list of NetDevices (initially, the list +is empty), a unique integer ID, and a system ID (for +distributed simulation). + +The design tries to avoid putting too many dependencies on the +base class Node, Application, or NetDevice for the following: +@itemize @bullet +@item IP version, or whether IP is at all even used in the Node. +@item implementation details of the IP stack +@end itemize + +From a software perspective, the lower interface of applications +corresponds to the C-based sockets API. The upper interface +of NetDevice objects corresponds to the device independent +sublayer of the Linux stack. Everything in between can be +aggregated and plumbed together as needed. + +Let's look more closely at the protocol demultiplexer. We want +incoming frames at layer-2 to be delivered to the right layer-3 +protocol such as Ipv4. The +function of this demultiplexer is to register callbacks for +receiving packets. The callbacks are indexed based on the +@uref{http://en.wikipedia.org/wiki/EtherType,,EtherType} +in the layer-2 frame. + +Many different types of higher-layer protocols may be +connected to the NetDevice, such as IPv4, IPv6, ARP, +MPLS, IEEE 802.1x, and packet sockets. Therefore, the +use of a callback-based demultiplexer avoids the need to +use a common base class for all of these protocols, which +is problematic because of the different types of objects +(including packet sockets) expected to be registered there. + +Each NetDevice delivers packets to a callback with the following +signature: +@verbatim + /** + * \param device a pointer to the net device which is calling this callback + * \param packet the packet received + * \param protocol the 16 bit protocol number associated with this packet. + * This protocol number is expected to be the same protocol number + * given to the Send method by the user on the sender side. + * \param address the address of the sender + * \returns true if the callback could handle the packet successfully, + * false otherwise. + */ + typedef Callback, Ptr, uint16_t, + const Address &> ReceiveCallback; +@end verbatim + +There is a function in class Node that matches that signature: +@verbatim +private: + bool ReceiveFromDevice (Ptr device, Ptr, + uint16_t protocol, const Address &from); +@end verbatim + +However, users do not need to access this function directly. Instead, +when users call @code{uint32_t AddDevice (Ptr device)}, +the implementation of this function sets the callback (and the +function returns the ifIndex of the NetDevice on that Node). + +But what does the ReceiveFromDevice function do? Here, it looks +up another callback, in its list of callbacks, corresponding to the +matching EtherType. This callback is called a ProtocolHandler, and +is specified as follows: +@verbatim + typedef Callback, Ptr, uint16_t, + const Address &> ProtocolHandler; +@end verbatim + +Upper-layer protocols or objects are expected to provide such a function. +and register it with the list of ProtocolHandlers by calling +@code{Node::RegisterProtocolHandler ();} +For instance, if Ipv4 is aggregated to a Node, then the Ipv4 receive +function can be registered with the protocol handler by calling: +@verbatim + RegisterProtocolHandler ( + MakeCallback (&Ipv4L3Protocol::Receive, ipv4), + Ipv4L3Protocol::PROT_NUMBER, 0); +@end verbatim +and likewise for Ipv6, Arp, etc. + +@section NodeList + +Every Node created is automatically added to the ns-3 @code{NodeList}. +The NodeList class provides an @code{Add()} method and C++ iterators +to allow one to walk the node list or fetch a Node pointer by +its integer identifier. + +@section Internet stack aggregation + +The above @code{class Node} is not very useful as-is; other objects +must be aggregated to it to provide useful node functionality. + +The ns-3 source code directory @code{src/internet-stack} provides +implmentation of TCP/IPv4-related components. These include IPv4, +ARP, UDP, TCP, and other related protocols. + +Internet Nodes are not subclasses of class Node; they are simply Nodes +that have had a bunch of IPv4-related +objects aggregated to them. They can be put together by hand, or +via a helper function @code{AddInternetStack ()} which does the +following: +@verbatim +void AddInternetStack (Ptr node) +{ + // Create layer-3 protocols + Ptr ipv4 = CreateObject (); + Ptr arp = CreateObject (); + ipv4->SetNode (node); + arp->SetNode (node); + + // Create an L4 demux + Ptr ipv4L4Demux = CreateObject (); + + // Create transport protocols and insert them into the demux + Ptr udp = CreateObject (); + Ptr tcp = CreateObject (); + + ipv4L4Demux->SetNode (node); + udp->SetNode (node); + tcp->SetNode (node); + + ipv4L4Demux->Insert (udp); + ipv4L4Demux->Insert (tcp); + + // Add factories for instantiating transport protocol sockets + Ptr udpFactory = CreateObject (); + Ptr tcpFactory = CreateObject (); + Ptr ipv4Impl = CreateObject (); + + udpFactory->SetUdp (udp); + tcpFactory->SetTcp (tcp); + ipv4Impl->SetIpv4 (ipv4); + + // Aggregate all of these new objects to the node + node->AggregateObject (ipv4); + node->AggregateObject (arp); + node->AggregateObject (ipv4Impl); + node->AggregateObject (udpFactory); + node->AggregateObject (tcpFactory); + node->AggregateObject (ipv4L4Demux); +} +@end verbatim + +@subsection Internet Node structure + +The Internet Node (an ns-3 Node augmented by aggregation to have one or more +IP stacks) has the following internal structure. + +@subsubsection Layer-3 protocols +At the lowest layer, sitting above the NetDevices, are the "layer 3" +protocols, including IPv4, IPv6, and ARP. These protocols provide +the following key methods and data members: + +@verbatim +class Ipv4L3Protocol : public Object +{ +public: + // Add an Ipv4 interface corresponding to the provided NetDevice + uint32_t AddInterface (Ptr device); + + // Receive function that can be bound to a callback, for receiving + // packets up the stack + void Receive( Ptr device, Ptr p, uint16_t protocol, + const Address &from); + + // Higher-level layers call this method to send a packet + // down the stack to the MAC and PHY layers + // + void Send (Ptr packet, Ipv4Address source, + Ipv4Address destination, uint8_t protocol); + +private: + Ipv4InterfaceList m_interfaces; + + // Protocol handlers +} +@end verbatim +There are many more functions (such as @code{Forward ()}) but we will +focus on the above four items from an architectural perspective. + +First, note that the @code{Receive ()} function has a matching signature +to the ReceiveCallback in the @code{class Node}. This function pointer +is inserted into the the Node's protocol handler when +@code{AddInterface ()} is called. The actual registration is done +with a statement such as: +follows: +@verbatim + RegisterProtocolHandler ( MakeCallback (&Ipv4Protocol::Receive, ipv4), + Ipv4L3Protocol::PROT_NUMBER, 0); +@end verbatim + +The Ipv4L3Protocol object is aggregated to the Node; there is only one +such Ipv4L3Protocol object. Higher-layer protocols that have a packet +to send down to the Ipv4L3Protocol object can call +@code{GetObject ()} to obtain a pointer, as follows: +@verbatim + Ptr ipv4 = m_node->GetObject (); + if (ipv4 != 0) + { + ipv4->Send (packet, saddr, daddr, PROT_NUMBER); + } +@end verbatim + +This class nicely demonstrates two techniques we exploit in +ns-3 to bind objects together: callbacks, and object aggregation. + +Once IPv4 has determined that a packet is for the local node, it +forwards it up the stack. This is done with the following function: + +@verbatim +void +Ipv4L3Protocol::ForwardUp (Ptr p, Ipv4Header const&ip, + Ptr incomingInterface) +{ + NS_LOG_FUNCTION (this << p << &ip); + + Ptr demux = m_node->GetObject (); + Ptr protocol = demux->GetProtocol (ip.GetProtocol ()); + protocol->Receive (p, ip.GetSource (), ip.GetDestination (), incomingInterface); +} +@end verbatim + +The first step is to find the aggregated Ipv4L4Demux object. Then, this +object is consulted to look up the right Ipv4L4Protocol, based on IP protocol +number. For instance, TCP is registered in the demux as protocol number 6. +Finally, the @code{Receive()} function on the Ipv4L4Protocol (such as +@code{TcpL4Protocol::Receive} is called. + +We have not yet introduced the class Ipv4Interface. Basically, +each NetDevice is paired with an IPv4 representation of such device. +In Linux, this @code{class Ipv4Interface} roughly corresponds to +the @code{struct in_device}; the main purpose is to provide +address-family specific information (addresses) about an interface. + +@subsubsection Layer-4 protocols and sockets + +We next describe how the transport protocols, sockets, and applications +tie together. In summary, each transport protocol implementation is +a socket factory. An application that needs a new socket + +For instance, to create a UDP socket, an application would use a code +snippet such as the following: +@verbatim + Ptr udpSocketFactory = GetNode ()->GetObject (); + Ptr m_socket = socketFactory->CreateSocket (); + m_socket->Bind (m_local_address); + ... +@end verbatim +The above will query the node to get a pointer to its UDP socket +factory, will create one such socket, and will use the socket with +an API similar to the C-based sockets API, such as @code{Connect ()} +and @code{Send ()}. See the chapter on ns-3 sockets for more information. + +We have described so far a socket factory (e.g. @code{class Udp}) and +a socket, which may be specialized (e.g., @code{class UdpSocket}). +There are a few more key objects that relate to the specialized +task of demultiplexing a packet to one or more receiving sockets. +The key object in this task is @code{class Ipv4EndPointDemux}. +This demultiplexer stores objects of @code{class Ipv4EndPoint}. +This class holds the addressing/port tuple (local port, local address, +destination port, destination address) associated with the socket, +and a receive callback. This receive callback has a receive +function registered by the socket. The @code{Lookup ()} function to +Ipv4EndPointDemux returns a list of Ipv4EndPoint objects (there may +be a list since more than one socket may match the packet). The +layer-4 protocol copies the packet to each Ipv4EndPoint and calls +its @code{ForwardUp ()} method, which then calls the @code{Receive ()} +function registered by the socket. + +An issue that arises when working with the sockets API on real +systems is the need to manage the reading from a socket, using +some type of I/O (e.g., blocking, non-blocking, asynchronous, ...). +ns-3 implements an asynchronous model for socket I/O; the application +sets a callback to be notified of received data ready to be read, and the +callback is invoked by the transport protocol when data is available. +This callback is specified as follows: +@verbatim + void Socket::SetRecvCallback (Callback, + Ptr, const Address&> receivedData); +@end verbatim +The data being received is conveyed in the Packet data buffer. An example +usage is in @code{class PacketSink}: +@verbatim + m_socket->SetRecvCallback (MakeCallback(&PacketSink::HandleRead, this)); +@end verbatim + +To summarize, internally, the UDP implementation is organized as follows: +@itemize @bullet +@item a @code{UdpImpl} class that implements the Udp socket factory +functionality +@item a @code{UdpL4Protocol} class that implements the protocol logic +that is socket-independent +@item a @code{UdpSocketImpl} class that implements socket-specific aspects +of UDP +@item a class called @code{Ipv4EndPoint} that stores the +addressing tuple (local port, local address, destination port, destination +address) associated with the socket, and a receive callback for the socket. +@end itemize + +@subsection Internet Node interfaces + +Many of the implementation details, or internal objects themselves, +of Internet Node objects are not exposed at the simulator public +API. This allows for different implementations; for instance, +replacing the native ns-3 models with ported TCP/IP stack code. + +The C++ public APIs of all of these objects is found in the +@code{src/node} directory, including principally: +@itemize @bullet +@item @code{socket.h} +@item @code{tcp.h} +@item @code{udp.h} +@item @code{ipv4.h} +@end itemize +These are typically base class objects that implement the default +values used in the implementation, implement access methods to get/set +state variables, host attributes, and implement publicly-available methods +exposed to clients such as @code{CreateSocket}. + +@subsection Example path of a packet + +These two figures show an example stack trace of how packets flow +through the Internet Node objects. + +@float Figure,fig:internet-node-send +@caption{Send path of a packet.} +@image{figures/internet-node-send,5in} +@end float + +@float Figure,fig:internet-node-recv +@caption{Receive path of a packet.} +@image{figures/internet-node-recv,5in} +@end float + From 75fab6d1b0b409c8484428b020b1262868c8f7e5 Mon Sep 17 00:00:00 2001 From: Sebastien Vincent Date: Tue, 1 Jul 2008 10:52:11 -0700 Subject: [PATCH 096/495] bug 236: add optional support for tcp and udp checksum. --- src/common/buffer.cc | 23 +++++++ src/common/buffer.h | 16 +++++ src/internet-stack/tcp-header.cc | 95 ++++++++++++++++++++------- src/internet-stack/tcp-header.h | 21 +++++- src/internet-stack/tcp-l4-protocol.cc | 39 ++++++++++- src/internet-stack/tcp-l4-protocol.h | 3 + src/internet-stack/udp-header.cc | 79 ++++++++++++++-------- src/internet-stack/udp-header.h | 12 +++- src/internet-stack/udp-l4-protocol.cc | 26 +++++++- src/internet-stack/udp-l4-protocol.h | 1 + src/node/ipv4-header.cc | 25 ++----- src/node/ipv4-header.h | 2 +- 12 files changed, 261 insertions(+), 81 deletions(-) diff --git a/src/common/buffer.cc b/src/common/buffer.cc index 29f8c7d39..91b35b9f8 100644 --- a/src/common/buffer.cc +++ b/src/common/buffer.cc @@ -1105,6 +1105,29 @@ Buffer::Iterator::ReadU8 (void) #endif /* BUFFER_USE_INLINE */ +uint16_t +Buffer::Iterator::CalculateIpChecksum(uint16_t size) +{ + return CalculateIpChecksum(size, 0); +} + +uint16_t +Buffer::Iterator::CalculateIpChecksum(uint16_t size, uint32_t initialChecksum) +{ + /* see RFC 1071 to understand this code. */ + uint32_t sum = initialChecksum; + + for (int j = 0; j < size/2; j++) + sum += ReadU16 (); + + if (size & 1) + sum += ReadU8 (); + + while (sum >> 16) + sum = (sum & 0xffff) + (sum >> 16); + return ~sum; +} + } // namespace ns3 diff --git a/src/common/buffer.h b/src/common/buffer.h index 65081f474..b86d0a49c 100644 --- a/src/common/buffer.h +++ b/src/common/buffer.h @@ -342,6 +342,22 @@ public: * bytes read. */ void Read (uint8_t *buffer, uint32_t size); + + /** + * \brief Calculate the checksum. + * \param size size of the buffer. + * \return checksum + */ + uint16_t CalculateIpChecksum(uint16_t size); + + /** + * \brief Calculate the checksum. + * \param size size of the buffer. + * \param initialChecksum initial value + * \return checksum + */ + uint16_t CalculateIpChecksum(uint16_t size, uint32_t initialChecksum); + private: friend class Buffer; Iterator (Buffer const*buffer); diff --git a/src/internet-stack/tcp-header.cc b/src/internet-stack/tcp-header.cc index c0f476220..e23c9e281 100644 --- a/src/internet-stack/tcp-header.cc +++ b/src/internet-stack/tcp-header.cc @@ -28,8 +28,6 @@ namespace ns3 { NS_OBJECT_ENSURE_REGISTERED (TcpHeader); -bool TcpHeader::m_calcChecksum = false; - TcpHeader::TcpHeader () : m_sourcePort (0), m_destinationPort (0), @@ -38,8 +36,11 @@ TcpHeader::TcpHeader () m_length (5), m_flags (0), m_windowSize (0xffff), + m_urgentPointer (0), + m_initialChecksum(0), m_checksum (0), - m_urgentPointer (0) + m_calcChecksum(false), + m_goodChecksum(true) {} TcpHeader::~TcpHeader () @@ -51,6 +52,11 @@ TcpHeader::EnableChecksums (void) m_calcChecksum = true; } +void TcpHeader::SetPayloadSize(uint16_t payloadSize) +{ + m_payloadSize = payloadSize; +} + void TcpHeader::SetSourcePort (uint16_t port) { m_sourcePort = port; @@ -130,8 +136,32 @@ TcpHeader::InitializeChecksum (Ipv4Address source, Ipv4Address destination, uint8_t protocol) { - m_checksum = 0; -//XXX requires peeking into IP to get length of the TCP segment + Buffer buf = Buffer(12); + uint8_t tmp[4]; + Buffer::Iterator it; + uint16_t tcpLength = m_payloadSize + GetSerializedSize(); + + buf.AddAtStart(12); + it = buf.Begin(); + + source.Serialize(tmp); + it.Write(tmp, 4); /* source IP address */ + destination.Serialize(tmp); + it.Write(tmp, 4); /* destination IP address */ + it.WriteU8(0); /* protocol */ + it.WriteU8(protocol); /* protocol */ + it.WriteU8(tcpLength >> 8); /* length */ + it.WriteU8(tcpLength & 0xff); /* length */ + + it = buf.Begin(); + /* we don't CompleteChecksum ( ~ ) now */ + m_initialChecksum = ~(it.CalculateIpChecksum(12)); +} + +bool +TcpHeader::IsChecksumOk (void) const +{ + return m_goodChecksum; } TypeId @@ -188,28 +218,49 @@ uint32_t TcpHeader::GetSerializedSize (void) const } void TcpHeader::Serialize (Buffer::Iterator start) const { - start.WriteHtonU16 (m_sourcePort); - start.WriteHtonU16 (m_destinationPort); - start.WriteHtonU32 (m_sequenceNumber); - start.WriteHtonU32 (m_ackNumber); - start.WriteHtonU16 (m_length << 12 | m_flags); //reserved bits are all zero - start.WriteHtonU16 (m_windowSize); - //XXX calculate checksum here - start.WriteHtonU16 (m_checksum); - start.WriteHtonU16 (m_urgentPointer); + Buffer::Iterator i = start; + uint16_t tcpLength = m_payloadSize + GetSerializedSize(); + i.WriteHtonU16 (m_sourcePort); + i.WriteHtonU16 (m_destinationPort); + i.WriteHtonU32 (m_sequenceNumber); + i.WriteHtonU32 (m_ackNumber); + i.WriteHtonU16 (m_length << 12 | m_flags); //reserved bits are all zero + i.WriteHtonU16 (m_windowSize); + i.WriteHtonU16 (0); + i.WriteHtonU16 (m_urgentPointer); + + if(m_calcChecksum) + { + i = start; + uint16_t checksum = i.CalculateIpChecksum(tcpLength, m_initialChecksum); + + i = start; + i.Next(16); + i.WriteU16(checksum); + } } uint32_t TcpHeader::Deserialize (Buffer::Iterator start) { - m_sourcePort = start.ReadNtohU16 (); - m_destinationPort = start.ReadNtohU16 (); - m_sequenceNumber = start.ReadNtohU32 (); - m_ackNumber = start.ReadNtohU32 (); - uint16_t field = start.ReadNtohU16 (); + Buffer::Iterator i = start; + m_sourcePort = i.ReadNtohU16 (); + m_destinationPort = i.ReadNtohU16 (); + m_sequenceNumber = i.ReadNtohU32 (); + m_ackNumber = i.ReadNtohU32 (); + uint16_t field = i.ReadNtohU16 (); m_flags = field & 0x3F; m_length = field>>12; - m_windowSize = start.ReadNtohU16 (); - m_checksum = start.ReadNtohU16 (); - m_urgentPointer = start.ReadNtohU16 (); + m_windowSize = i.ReadNtohU16 (); + m_checksum = i.ReadU16 (); + m_urgentPointer = i.ReadNtohU16 (); + + if(m_calcChecksum) + { + i = start; + uint16_t checksum = i.CalculateIpChecksum(m_payloadSize + GetSerializedSize(), m_initialChecksum); + + m_goodChecksum = (checksum == 0); + } + return GetSerializedSize (); } diff --git a/src/internet-stack/tcp-header.h b/src/internet-stack/tcp-header.h index c1ba93877..99d91747a 100644 --- a/src/internet-stack/tcp-header.h +++ b/src/internet-stack/tcp-header.h @@ -47,7 +47,7 @@ public: /** * \brief Enable checksum calculation for TCP (XXX currently has no effect) */ - static void EnableChecksums (void); + void EnableChecksums (void); //Setters /** * \param port The source port for this TcpHeader @@ -150,6 +150,17 @@ public: virtual void Serialize (Buffer::Iterator start) const; virtual uint32_t Deserialize (Buffer::Iterator start); + /** + * \param size The payload size in bytes + */ + void SetPayloadSize (uint16_t size); + + /** + * \brief Is the TCP checksum correct ? + * \returns true if the checksum is correct, false otherwise. + */ + bool IsChecksumOk (void) const; + private: uint16_t m_sourcePort; uint16_t m_destinationPort; @@ -158,10 +169,14 @@ private: uint8_t m_length; // really a uint4_t uint8_t m_flags; // really a uint6_t uint16_t m_windowSize; - uint16_t m_checksum; uint16_t m_urgentPointer; + uint16_t m_payloadSize; + uint16_t m_initialChecksum; + uint16_t m_checksum; + + bool m_calcChecksum; + bool m_goodChecksum; - static bool m_calcChecksum; }; }; // namespace ns3 diff --git a/src/internet-stack/tcp-l4-protocol.cc b/src/internet-stack/tcp-l4-protocol.cc index 2898b09f4..6ca747e80 100644 --- a/src/internet-stack/tcp-l4-protocol.cc +++ b/src/internet-stack/tcp-l4-protocol.cc @@ -21,6 +21,7 @@ #include "ns3/assert.h" #include "ns3/log.h" #include "ns3/nstime.h" +#include "ns3/boolean.h" #include "ns3/packet.h" #include "ns3/node.h" @@ -328,6 +329,11 @@ TcpL4Protocol::GetTypeId (void) ObjectFactoryValue (GetDefaultRttEstimatorFactory ()), MakeObjectFactoryAccessor (&TcpL4Protocol::m_rttFactory), MakeObjectFactoryChecker ()) + .AddAttribute ("CalcChecksum", "If true, we calculate the checksum of outgoing packets" + " and verify the checksum of incoming packets.", + BooleanValue (false), + MakeBooleanAccessor (&TcpL4Protocol::m_calcChecksum), + MakeBooleanChecker ()) ; return tid; } @@ -439,14 +445,31 @@ TcpL4Protocol::Receive (Ptr packet, NS_LOG_FUNCTION (this << packet << source << destination << incomingInterface); TcpHeader tcpHeader; + if(m_calcChecksum) + { + tcpHeader.EnableChecksums(); + } + /* XXX very dirty but needs this to AddHeader again because of checksum */ + tcpHeader.SetLength(5); /* XXX TCP without options */ + tcpHeader.SetPayloadSize(packet->GetSize() - tcpHeader.GetSerializedSize()); + tcpHeader.InitializeChecksum(source, destination, PROT_NUMBER); + //these two do a peek, so that the packet can be forwarded up packet->RemoveHeader (tcpHeader); + NS_LOG_LOGIC("TcpL4Protocol " << this << " receiving seq " << tcpHeader.GetSequenceNumber() << " ack " << tcpHeader.GetAckNumber() << " flags "<< std::hex << (int)tcpHeader.GetFlags() << std::dec << " data size " << packet->GetSize()); - packet->AddHeader (tcpHeader); + + if(!tcpHeader.IsChecksumOk ()) + { + NS_LOG_INFO("Bad checksum, dropping packet!"); + return; + } + + packet->AddHeader (tcpHeader); NS_LOG_LOGIC ("TcpL4Protocol "<Lookup (destination, tcpHeader.GetDestinationPort (), @@ -478,6 +501,11 @@ TcpL4Protocol::Send (Ptr packet, TcpHeader tcpHeader; tcpHeader.SetDestinationPort (dport); tcpHeader.SetSourcePort (sport); + tcpHeader.SetPayloadSize(packet->GetSize()); + if(m_calcChecksum) + { + tcpHeader.EnableChecksums(); + } tcpHeader.InitializeChecksum (saddr, daddr, PROT_NUMBER); @@ -507,8 +535,13 @@ TcpL4Protocol::SendPacket (Ptr packet, TcpHeader outgoingHeader, // XXX outgoingHeader cannot be logged outgoingHeader.SetLength (5); //header length in units of 32bit words - outgoingHeader.SetChecksum (0); //XXX - outgoingHeader.SetUrgentPointer (0); //XXX + outgoingHeader.SetPayloadSize(packet->GetSize()); + /* outgoingHeader.SetUrgentPointer (0); //XXX */ + if(m_calcChecksum) + { + outgoingHeader.EnableChecksums(); + } + outgoingHeader.InitializeChecksum(saddr, daddr, PROT_NUMBER); packet->AddHeader (outgoingHeader); diff --git a/src/internet-stack/tcp-l4-protocol.h b/src/internet-stack/tcp-l4-protocol.h index 9092a7e3b..710143001 100644 --- a/src/internet-stack/tcp-l4-protocol.h +++ b/src/internet-stack/tcp-l4-protocol.h @@ -117,6 +117,9 @@ private: void SendPacket (Ptr, TcpHeader, Ipv4Address, Ipv4Address); static ObjectFactory GetDefaultRttEstimatorFactory (void); + + bool m_goodChecksum; + bool m_calcChecksum; }; }; // namespace ns3 diff --git a/src/internet-stack/udp-header.cc b/src/internet-stack/udp-header.cc index 92cd4164b..64a83710f 100644 --- a/src/internet-stack/udp-header.cc +++ b/src/internet-stack/udp-header.cc @@ -19,14 +19,11 @@ */ #include "udp-header.h" -#include "ipv4-checksum.h" namespace ns3 { NS_OBJECT_ENSURE_REGISTERED (UdpHeader); -bool UdpHeader::m_calcChecksum = false; - /* The magic values below are used only for debugging. * They can be used to easily detect memory corruption * problems so you can see the patterns in memory. @@ -35,7 +32,10 @@ UdpHeader::UdpHeader () : m_sourcePort (0xfffd), m_destinationPort (0xfffd), m_payloadSize (0xfffd), - m_initialChecksum (0) + m_initialChecksum (0), + m_checksum(0), + m_calcChecksum(false), + m_goodChecksum(true) {} UdpHeader::~UdpHeader () { @@ -80,18 +80,35 @@ UdpHeader::InitializeChecksum (Ipv4Address source, Ipv4Address destination, uint8_t protocol) { - uint8_t buf[12]; - source.Serialize (buf); - destination.Serialize (buf+4); - buf[8] = 0; - buf[9] = protocol; - uint16_t udpLength = m_payloadSize + GetSerializedSize (); - buf[10] = udpLength >> 8; - buf[11] = udpLength & 0xff; + Buffer buf = Buffer(12); + uint8_t tmp[4]; + Buffer::Iterator it; + uint16_t udpLength = m_payloadSize + GetSerializedSize(); - m_initialChecksum = Ipv4ChecksumCalculate (0, buf, 12); + buf.AddAtStart(12); + it = buf.Begin(); + + source.Serialize(tmp); + it.Write(tmp, 4); /* source IP address */ + destination.Serialize(tmp); + it.Write(tmp, 4); /* destination IP address */ + it.WriteU8(0); /* protocol */ + it.WriteU8(protocol); /* protocol */ + it.WriteU8(udpLength >> 8); /* length */ + it.WriteU8(udpLength & 0xff); /* length */ + + it = buf.Begin(); + /* we don't CompleteChecksum ( ~ ) now */ + m_initialChecksum = ~(it.CalculateIpChecksum(12)); } +bool +UdpHeader::IsChecksumOk (void) const +{ + return m_goodChecksum; +} + + TypeId UdpHeader::GetTypeId (void) { @@ -125,23 +142,21 @@ void UdpHeader::Serialize (Buffer::Iterator start) const { Buffer::Iterator i = start; + uint16_t udpLength = m_payloadSize + GetSerializedSize(); + i.WriteHtonU16 (m_sourcePort); i.WriteHtonU16 (m_destinationPort); - i.WriteHtonU16 (m_payloadSize + GetSerializedSize ()); + i.WriteHtonU16 (udpLength); i.WriteU16 (0); - if (m_calcChecksum) + if (m_calcChecksum) { -#if 0 - //XXXX - uint16_t checksum = Ipv4ChecksumCalculate (m_initialChecksum, - buffer->PeekData (), - GetSerializedSize () + m_payloadSize); - checksum = Ipv4ChecksumComplete (checksum); - i = buffer->Begin (); - i.Next (6); - i.WriteU16 (checksum); -#endif + i = start; + uint16_t checksum = i.CalculateIpChecksum(udpLength, m_initialChecksum); + + i = start; + i.Next(6); + i.WriteU16(checksum); } } uint32_t @@ -151,10 +166,16 @@ UdpHeader::Deserialize (Buffer::Iterator start) m_sourcePort = i.ReadNtohU16 (); m_destinationPort = i.ReadNtohU16 (); m_payloadSize = i.ReadNtohU16 () - GetSerializedSize (); - if (m_calcChecksum) - { - // XXX verify checksum. - } + m_checksum = i.ReadU16(); + + if(m_calcChecksum) + { + i = start; + uint16_t checksum = i.CalculateIpChecksum(m_payloadSize + GetSerializedSize(), m_initialChecksum); + + m_goodChecksum = (checksum == 0); + } + return GetSerializedSize (); } diff --git a/src/internet-stack/udp-header.h b/src/internet-stack/udp-header.h index d2ab5e73a..d3908e64f 100644 --- a/src/internet-stack/udp-header.h +++ b/src/internet-stack/udp-header.h @@ -49,7 +49,7 @@ public: /** * \brief Enable checksum calculation for UDP (XXX currently has no effect) */ - static void EnableChecksums (void); + void EnableChecksums (void); /** * \param port the destination port for this UdpHeader */ @@ -93,13 +93,21 @@ public: virtual void Serialize (Buffer::Iterator start) const; virtual uint32_t Deserialize (Buffer::Iterator start); + /** + * \brief Is the UDP checksum correct ? + * \returns true if the checksum is correct, false otherwise. + */ + bool IsChecksumOk (void) const; + private: uint16_t m_sourcePort; uint16_t m_destinationPort; uint16_t m_payloadSize; uint16_t m_initialChecksum; + uint16_t m_checksum; - static bool m_calcChecksum; + bool m_calcChecksum; + bool m_goodChecksum; }; } // namespace ns3 diff --git a/src/internet-stack/udp-l4-protocol.cc b/src/internet-stack/udp-l4-protocol.cc index 7a8c58152..8def85407 100644 --- a/src/internet-stack/udp-l4-protocol.cc +++ b/src/internet-stack/udp-l4-protocol.cc @@ -22,6 +22,7 @@ #include "ns3/assert.h" #include "ns3/packet.h" #include "ns3/node.h" +#include "ns3/boolean.h" #include "udp-l4-protocol.h" #include "udp-header.h" @@ -45,6 +46,11 @@ UdpL4Protocol::GetTypeId (void) static TypeId tid = TypeId ("ns3::UdpL4Protocol") .SetParent () .AddConstructor () + .AddAttribute ("CalcChecksum", "If true, we calculate the checksum of outgoing packets" + " and verify the checksum of incoming packets.", + BooleanValue (false), + MakeBooleanAccessor (&UdpL4Protocol::m_calcChecksum), + MakeBooleanChecker ()) ; return tid; } @@ -151,9 +157,23 @@ UdpL4Protocol::Receive(Ptr packet, Ptr interface) { NS_LOG_FUNCTION (this << packet << source << destination); - UdpHeader udpHeader; + if(m_calcChecksum) + { + udpHeader.EnableChecksums(); + } + + udpHeader.SetPayloadSize (packet->GetSize () - udpHeader.GetSerializedSize ()); + udpHeader.InitializeChecksum (source, destination, PROT_NUMBER); + packet->RemoveHeader (udpHeader); + + if(!udpHeader.IsChecksumOk ()) + { + NS_LOG_INFO("Bad checksum : dropping packet!"); + return; + } + Ipv4EndPointDemux::EndPoints endPoints = m_endPoints->Lookup (destination, udpHeader.GetDestinationPort (), source, udpHeader.GetSourcePort (), interface); @@ -172,6 +192,10 @@ UdpL4Protocol::Send (Ptr packet, NS_LOG_FUNCTION (this << packet << saddr << daddr << sport << dport); UdpHeader udpHeader; + if(m_calcChecksum) + { + udpHeader.EnableChecksums(); + } udpHeader.SetDestinationPort (dport); udpHeader.SetSourcePort (sport); udpHeader.SetPayloadSize (packet->GetSize ()); diff --git a/src/internet-stack/udp-l4-protocol.h b/src/internet-stack/udp-l4-protocol.h index ce6ec7cae..29d1551cc 100644 --- a/src/internet-stack/udp-l4-protocol.h +++ b/src/internet-stack/udp-l4-protocol.h @@ -93,6 +93,7 @@ protected: private: Ptr m_node; Ipv4EndPointDemux *m_endPoints; + bool m_calcChecksum; }; }; // namespace ns3 diff --git a/src/node/ipv4-header.cc b/src/node/ipv4-header.cc index 758358f98..48c9d1f30 100644 --- a/src/node/ipv4-header.cc +++ b/src/node/ipv4-header.cc @@ -38,6 +38,7 @@ Ipv4Header::Ipv4Header () m_protocol (0), m_flags (0), m_fragmentOffset (0), + m_checksum(0), m_goodChecksum (true) {} @@ -177,23 +178,6 @@ Ipv4Header::IsChecksumOk (void) const return m_goodChecksum; } -uint16_t -Ipv4Header::ChecksumCalculate(Buffer::Iterator &i, uint16_t size) -{ - /* see RFC 1071 to understand this code. */ - uint32_t sum = 0; - - for (int j = 0; j < size/2; j++) - sum += i.ReadU16 (); - - if (size & 1) - sum += i.ReadU8 (); - - while (sum >> 16) - sum = (sum & 0xffff) + (sum >> 16); - return ~sum; -} - TypeId Ipv4Header::GetTypeId (void) { @@ -282,7 +266,7 @@ Ipv4Header::Serialize (Buffer::Iterator start) const if (m_calcChecksum) { i = start; - uint16_t checksum = ChecksumCalculate(i, 20); + uint16_t checksum = i.CalculateIpChecksum(20); NS_LOG_LOGIC ("checksum=" < packet, return; } - packet->AddHeader (tcpHeader); NS_LOG_LOGIC ("TcpL4Protocol "<Lookup (destination, tcpHeader.GetDestinationPort (), From b93a9aeef40c223468cbb363befeaedada0bb5eb Mon Sep 17 00:00:00 2001 From: Mathieu Lacage Date: Wed, 2 Jul 2008 03:16:36 -0700 Subject: [PATCH 098/495] bug 245: build failure with gcc 4.3.x --- src/common/buffer.h | 1 + src/common/data-rate.cc | 9 +++++++-- src/common/tag-list.cc | 1 + src/contrib/config-store.cc | 1 + src/core/callback.h | 1 + src/core/double.h | 1 + src/core/integer.h | 1 + src/core/uinteger.h | 1 + src/devices/wifi/status-code.h | 1 + src/devices/wifi/supported-rates.h | 1 + src/helper/internet-stack-helper.cc | 1 + src/helper/olsr-helper.h | 2 +- src/internet-stack/sgi-hashmap.h | 8 +++++++- src/node/address.cc | 1 + src/node/mac48-address.cc | 1 + src/node/mac64-address.cc | 1 + src/node/socket.cc | 1 + .../global-routing/global-route-manager-impl.cc | 1 + src/simulator/time.cc | 11 +++++++++-- utils/bench-packets.cc | 5 ++++- utils/bench-simulator.cc | 1 + utils/replay-simulation.cc | 1 + 22 files changed, 45 insertions(+), 7 deletions(-) diff --git a/src/common/buffer.h b/src/common/buffer.h index b86d0a49c..245f31ea8 100644 --- a/src/common/buffer.h +++ b/src/common/buffer.h @@ -536,6 +536,7 @@ private: #ifdef BUFFER_USE_INLINE #include "ns3/assert.h" +#include namespace ns3 { diff --git a/src/common/data-rate.cc b/src/common/data-rate.cc index e7727dda0..61d6f6550 100644 --- a/src/common/data-rate.cc +++ b/src/common/data-rate.cc @@ -29,7 +29,10 @@ DoParse (const std::string s, uint64_t *v) std::string::size_type n = s.find_first_not_of("0123456789."); if (n != std::string::npos) { // Found non-numeric - double r = ::atof(s.substr(0, n).c_str()); + std::istringstream iss; + iss.str (s.substr(0, n)); + double r; + iss >> r; std::string trailer = s.substr(n, std::string::npos); if (trailer == "bps") { @@ -117,7 +120,9 @@ DoParse (const std::string s, uint64_t *v) } return true; } - *v = ::atoll(s.c_str()); + std::istringstream iss; + iss.str (s); + iss >> *v; return true; } diff --git a/src/common/tag-list.cc b/src/common/tag-list.cc index 6af8ec7a9..4f8fdaf92 100644 --- a/src/common/tag-list.cc +++ b/src/common/tag-list.cc @@ -20,6 +20,7 @@ #include "tag-list.h" #include "ns3/log.h" #include +#include NS_LOG_COMPONENT_DEFINE ("TagList"); diff --git a/src/contrib/config-store.cc b/src/contrib/config-store.cc index 55f9d7070..d4250bb50 100644 --- a/src/contrib/config-store.cc +++ b/src/contrib/config-store.cc @@ -8,6 +8,7 @@ #include #include #include +#include NS_LOG_COMPONENT_DEFINE ("ConfigStore"); diff --git a/src/core/callback.h b/src/core/callback.h index 40afbd1a6..9d72aeb84 100644 --- a/src/core/callback.h +++ b/src/core/callback.h @@ -25,6 +25,7 @@ #include "fatal-error.h" #include "empty.h" #include "type-traits.h" +#include namespace ns3 { diff --git a/src/core/double.h b/src/core/double.h index 1ed54ecdd..d21b97847 100644 --- a/src/core/double.h +++ b/src/core/double.h @@ -23,6 +23,7 @@ #include "attribute.h" #include "attribute-helper.h" #include +#include namespace ns3 { diff --git a/src/core/integer.h b/src/core/integer.h index 8ac78e47d..2bb8125a9 100644 --- a/src/core/integer.h +++ b/src/core/integer.h @@ -23,6 +23,7 @@ #include "attribute.h" #include "attribute-helper.h" #include +#include namespace ns3 { diff --git a/src/core/uinteger.h b/src/core/uinteger.h index c67709272..881f103bf 100644 --- a/src/core/uinteger.h +++ b/src/core/uinteger.h @@ -23,6 +23,7 @@ #include "attribute.h" #include "attribute-helper.h" #include +#include namespace ns3 { diff --git a/src/devices/wifi/status-code.h b/src/devices/wifi/status-code.h index e7daf9e26..cbeffc570 100644 --- a/src/devices/wifi/status-code.h +++ b/src/devices/wifi/status-code.h @@ -21,6 +21,7 @@ #define STATUS_CODE_H #include +#include #include "ns3/buffer.h" namespace ns3 { diff --git a/src/devices/wifi/supported-rates.h b/src/devices/wifi/supported-rates.h index 417390f1a..0e52cbe50 100644 --- a/src/devices/wifi/supported-rates.h +++ b/src/devices/wifi/supported-rates.h @@ -21,6 +21,7 @@ #define SUPPORTED_RATES_H #include +#include #include "ns3/buffer.h" namespace ns3 { diff --git a/src/helper/internet-stack-helper.cc b/src/helper/internet-stack-helper.cc index 8b6661bfb..792f6e528 100644 --- a/src/helper/internet-stack-helper.cc +++ b/src/helper/internet-stack-helper.cc @@ -26,6 +26,7 @@ #include "ns3/packet-socket-factory.h" #include "ns3/config.h" #include "ns3/simulator.h" +#include namespace ns3 { diff --git a/src/helper/olsr-helper.h b/src/helper/olsr-helper.h index f481fe110..cce8e4aea 100644 --- a/src/helper/olsr-helper.h +++ b/src/helper/olsr-helper.h @@ -39,7 +39,7 @@ public: */ void SetAgent (std::string tid, std::string n0 = "", const AttributeValue &v0 = EmptyAttributeValue (), - std::string n1 = "", const AttributeValue &v2 = EmptyAttributeValue (), + std::string n1 = "", const AttributeValue &v1 = EmptyAttributeValue (), std::string n2 = "", const AttributeValue &v2 = EmptyAttributeValue (), std::string n3 = "", const AttributeValue &v3 = EmptyAttributeValue (), std::string n4 = "", const AttributeValue &v4 = EmptyAttributeValue (), diff --git a/src/internet-stack/sgi-hashmap.h b/src/internet-stack/sgi-hashmap.h index 375d25fee..642fb5f5b 100644 --- a/src/internet-stack/sgi-hashmap.h +++ b/src/internet-stack/sgi-hashmap.h @@ -20,8 +20,14 @@ namespace sgi = std; // GCC 3.0 namespace sgi = ::__gnu_cxx; // GCC 3.1 and later #endif #else // gcc 4.x and later + #if __GNUC_MINOR__ < 3 #include - namespace sgi = ::__gnu_cxx; +namespace sgi = ::__gnu_cxx; + #else +#undef __DEPRECATED + #include +namespace sgi = ::__gnu_cxx; + #endif #endif #endif #else // ... there are other compilers, right? diff --git a/src/node/address.cc b/src/node/address.cc index 365161e63..a9f679c63 100644 --- a/src/node/address.cc +++ b/src/node/address.cc @@ -1,5 +1,6 @@ #include "ns3/assert.h" #include "address.h" +#include #include #include diff --git a/src/node/mac48-address.cc b/src/node/mac48-address.cc index 9683f80d1..6dbb8d312 100644 --- a/src/node/mac48-address.cc +++ b/src/node/mac48-address.cc @@ -22,6 +22,7 @@ #include "ns3/assert.h" #include #include +#include namespace ns3 { diff --git a/src/node/mac64-address.cc b/src/node/mac64-address.cc index 13c4913eb..666397624 100644 --- a/src/node/mac64-address.cc +++ b/src/node/mac64-address.cc @@ -22,6 +22,7 @@ #include "ns3/assert.h" #include #include +#include namespace ns3 { diff --git a/src/node/socket.cc b/src/node/socket.cc index 52f691c57..d133e936f 100644 --- a/src/node/socket.cc +++ b/src/node/socket.cc @@ -25,6 +25,7 @@ #include "node.h" #include "socket.h" #include "socket-factory.h" +#include NS_LOG_COMPONENT_DEFINE ("Socket"); diff --git a/src/routing/global-routing/global-route-manager-impl.cc b/src/routing/global-routing/global-route-manager-impl.cc index bf40994b0..8230c2a7f 100644 --- a/src/routing/global-routing/global-route-manager-impl.cc +++ b/src/routing/global-routing/global-route-manager-impl.cc @@ -1425,6 +1425,7 @@ GlobalRouteManagerImpl::SPFVertexAddParent (SPFVertex* v) #include "ns3/test.h" #include "ns3/simulator.h" +#include // for rand () namespace ns3 { diff --git a/src/simulator/time.cc b/src/simulator/time.cc index a25770277..ba36543e6 100644 --- a/src/simulator/time.cc +++ b/src/simulator/time.cc @@ -72,7 +72,10 @@ TimeUnit<1>::TimeUnit(const std::string& s) std::string::size_type n = s.find_first_not_of("0123456789."); if (n != std::string::npos) { // Found non-numeric - double r = atof(s.substr(0, n).c_str()); + std::istringstream iss; + iss.str (s.substr(0, n)); + double r; + iss >> r; std::string trailer = s.substr(n, std::string::npos); if (trailer == std::string("s")) { @@ -113,7 +116,11 @@ TimeUnit<1>::TimeUnit(const std::string& s) } //else //they didn't provide units, assume seconds - m_data = HighPrecision (atof(s.c_str()) * TimeStepPrecision::g_tsPrecFactor); + std::istringstream iss; + iss. str (s); + double v; + iss >> v; + m_data = HighPrecision (v * TimeStepPrecision::g_tsPrecFactor); } double diff --git a/utils/bench-packets.cc b/utils/bench-packets.cc index 22643a52c..5ea80088e 100644 --- a/utils/bench-packets.cc +++ b/utils/bench-packets.cc @@ -23,6 +23,7 @@ #include #include #include +#include // for exit () using namespace ns3; @@ -261,7 +262,9 @@ int main (int argc, char *argv[]) if (strncmp ("--n=", argv[0],strlen ("--n=")) == 0) { char const *nAscii = argv[0] + strlen ("--n="); - n = atoi (nAscii); + std::istringstream iss; + iss.str (nAscii); + iss >> n; } argc--; argv++; diff --git a/utils/bench-simulator.cc b/utils/bench-simulator.cc index 6b9eb2c2b..6480ab5f5 100644 --- a/utils/bench-simulator.cc +++ b/utils/bench-simulator.cc @@ -23,6 +23,7 @@ #include #include #include +#include using namespace ns3; diff --git a/utils/replay-simulation.cc b/utils/replay-simulation.cc index 1ce94dab9..33a81a398 100644 --- a/utils/replay-simulation.cc +++ b/utils/replay-simulation.cc @@ -24,6 +24,7 @@ #include #include #include +#include using namespace ns3; From 7f91bd111eaf81c6f77e6b99255ac9fb49346531 Mon Sep 17 00:00:00 2001 From: Mathieu Lacage Date: Wed, 2 Jul 2008 08:33:47 -0700 Subject: [PATCH 099/495] avoid pygccxml warning. --- src/core/type-id.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/type-id.h b/src/core/type-id.h index 48455f06f..c75f71490 100644 --- a/src/core/type-id.h +++ b/src/core/type-id.h @@ -44,7 +44,7 @@ class TraceSourceAccessor; class TypeId { public: - enum { + enum AttributeFlag { /** * The attribute can be read */ From 572ee9e3c9e3c6c36cdba91b1ea27db1703e39d4 Mon Sep 17 00:00:00 2001 From: Mathieu Lacage Date: Wed, 2 Jul 2008 08:37:57 -0700 Subject: [PATCH 100/495] export new methods for language bindings --- src/simulator/simulator.h | 28 +++++++++++++++++++++++++--- 1 file changed, 25 insertions(+), 3 deletions(-) diff --git a/src/simulator/simulator.h b/src/simulator/simulator.h index 892f9eb2f..b2eed6685 100644 --- a/src/simulator/simulator.h +++ b/src/simulator/simulator.h @@ -554,6 +554,31 @@ public: * The returned value will always be bigger than or equal to Simulator::Now. */ static Time GetMaximumSimulationTime (void); + /** + * \param time delay until the event expires + * \param event the event to schedule + * \returns a unique identifier for the newly-scheduled event. + * + * This method will be typically used by language bindings + * to delegate events to their own subclass of the EventImpl base class. + */ + static EventId Schedule (Time const &time, const Ptr &event); + /** + * \param event the event to schedule + * \returns a unique identifier for the newly-scheduled event. + * + * This method will be typically used by language bindings + * to delegate events to their own subclass of the EventImpl base class. + */ + static EventId ScheduleDestroy (const Ptr &event); + /** + * \param event the event to schedule + * \returns a unique identifier for the newly-scheduled event. + * + * This method will be typically used by language bindings + * to delegate events to their own subclass of the EventImpl base class. + */ + static EventId ScheduleNow (const Ptr &event); private: Simulator (); ~Simulator (); @@ -594,9 +619,6 @@ private: static Ptr MakeEvent (void (*f) (U1,U2,U3,U4,U5), T1 a1, T2 a2, T3 a3, T4 a4, T5 a5); static Ptr GetPriv (void); - static EventId Schedule (Time const &time, const Ptr &event); - static EventId ScheduleDestroy (const Ptr &event); - static EventId ScheduleNow (const Ptr &event); static Ptr m_priv; }; From 7e12d2843909c159e9ebc54b8dcde20fbbab7f78 Mon Sep 17 00:00:00 2001 From: Raj Bhattacharjea Date: Wed, 2 Jul 2008 15:45:35 -0400 Subject: [PATCH 101/495] Add a tcp server example --- examples/tcp-star-server.cc | 172 ++++++++++++++++++++++++++++++++++++ examples/wscript | 4 + 2 files changed, 176 insertions(+) create mode 100644 examples/tcp-star-server.cc diff --git a/examples/tcp-star-server.cc b/examples/tcp-star-server.cc new file mode 100644 index 000000000..54d5a23e6 --- /dev/null +++ b/examples/tcp-star-server.cc @@ -0,0 +1,172 @@ +/* -*- 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 + * + */ + + +// Default Network topology, 9 nodes in a star +/* + n2 n3 n4 + \ | / + \|/ + n1---n0---n5 + /|\ + / | \ + n8 n7 n6 +*/ +// - CBR Traffic goes from the star "arms" to the "hub" +// - Tracing of queues and packet receptions to file +// "tcp-star-server.tr" +// - pcap traces also generated in the following files +// "tcp-star-server-$n-$i.pcap" where n and i represent node and interface +// numbers respectively +// Usage examples for things you might want to tweak: +// ./waf --run="tcp-star-server" +// ./waf --run="tcp-star-server --nNodes=25" +// ./waf --run="tcp-star-server --ns3::OnOffApplication::DataRate=10000" +// ./waf --run="tcp-star-server --ns3::OnOffApplication::PacketSize=500" +// See the ns-3 tutorial for more info on the command line: +// http://www.nsnam.org/tutorials.html + + + + +#include +#include +#include +#include + +#include "ns3/core-module.h" +#include "ns3/simulator-module.h" +#include "ns3/node-module.h" +#include "ns3/helper-module.h" +#include "ns3/global-route-manager.h" + +using namespace ns3; + +NS_LOG_COMPONENT_DEFINE ("TcpServer"); + +int +main (int argc, char *argv[]) +{ + // Users may find it convenient to turn on explicit debugging + // for selected modules; the below lines suggest how to do this + + //LogComponentEnable ("TcpServer", LOG_LEVEL_INFO); + //LogComponentEnable ("TcpL4Protocol", LOG_LEVEL_ALL); + //LogComponentEnable ("TcpSocketImpl", LOG_LEVEL_ALL); + //LogComponentEnable ("PacketSink", LOG_LEVEL_ALL); + // + // Make the random number generators generate reproducible results. + // + RandomVariable::UseGlobalSeed (1, 1, 2, 3, 5, 8); + + // Set up some default values for the simulation. + Config::SetDefault ("ns3::OnOffApplication::PacketSize", UintegerValue (250)); + Config::SetDefault ("ns3::OnOffApplication::DataRate", StringValue ("5kb/s")); + uint32_t N = 9; //number of nodes in the star + + // Allow the user to override any of the defaults and the above + // Config::SetDefault()s at run-time, via command-line arguments + CommandLine cmd; + cmd.AddValue("nNodes", "Number of nodes to place in the star", N); + cmd.Parse (argc, argv); + + // Here, we will create N nodes in a star. + NS_LOG_INFO ("Create nodes."); + NodeContainer serverNode; + NodeContainer clientNodes; + serverNode.Create(1); + clientNodes.Create(N-1); + NodeContainer allNodes = NodeContainer(serverNode, clientNodes); + + // Install network stacks on the nodes + InternetStackHelper internet; + internet.Install (allNodes); + + //Collect an adjacency list of nodes for the p2p topology + std::vector nodeAdjacencyList(N-1); + for(uint32_t i=0; i deviceAdjacencyList(N-1); + for(uint32_t i=0; i interfaceAdjacencyList(N-1); + for(uint32_t i=0; i Date: Wed, 2 Jul 2008 15:57:33 -0400 Subject: [PATCH 102/495] Fix trace names to match documents in tcp-star-server --- examples/tcp-star-server.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/tcp-star-server.cc b/examples/tcp-star-server.cc index 54d5a23e6..81c7f58f3 100644 --- a/examples/tcp-star-server.cc +++ b/examples/tcp-star-server.cc @@ -159,8 +159,8 @@ main (int argc, char *argv[]) //configure tracing std::ofstream ascii; - ascii.open ("tcp-server.tr"); - PointToPointHelper::EnablePcapAll ("tcp-server"); + ascii.open ("tcp-star-server.tr"); + PointToPointHelper::EnablePcapAll ("tcp-star-server"); PointToPointHelper::EnableAsciiAll (ascii); NS_LOG_INFO ("Run Simulation."); From 2d76aafcfb3a13ef708b4120e0eb9c37e2a99d0a Mon Sep 17 00:00:00 2001 From: Mathieu Lacage Date: Wed, 2 Jul 2008 13:21:43 -0700 Subject: [PATCH 103/495] do not make m_enable protected --- src/common/error-model.cc | 4 ++-- src/common/error-model.h | 4 +--- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/src/common/error-model.cc b/src/common/error-model.cc index 77b5854ef..02bfac62d 100644 --- a/src/common/error-model.cc +++ b/src/common/error-model.cc @@ -178,7 +178,7 @@ bool RateErrorModel::DoCorrupt (Ptr p) { NS_LOG_FUNCTION_NOARGS (); - if (!m_enable) + if (!IsEnabled ()) { return false; } @@ -275,7 +275,7 @@ bool ListErrorModel::DoCorrupt (Ptr p) { NS_LOG_FUNCTION_NOARGS (); - if (!m_enable) + if (!IsEnabled ()) { return false; } diff --git a/src/common/error-model.h b/src/common/error-model.h index 825487750..bf3767637 100644 --- a/src/common/error-model.h +++ b/src/common/error-model.h @@ -104,9 +104,6 @@ public: */ bool IsEnabled (void) const; -protected: - bool m_enable; - private: /* * These methods must be implemented by subclasses @@ -114,6 +111,7 @@ private: virtual bool DoCorrupt (Ptr) = 0; virtual void DoReset (void) = 0; + bool m_enable; }; enum ErrorUnit From 925136697a8b55f98f057a29ceca4d4eac1e54ae Mon Sep 17 00:00:00 2001 From: Mathieu Lacage Date: Wed, 2 Jul 2008 13:21:56 -0700 Subject: [PATCH 104/495] avoid pygccxml warning --- src/core/int-to-type.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/int-to-type.h b/src/core/int-to-type.h index 240fe8a71..612820cf9 100644 --- a/src/core/int-to-type.h +++ b/src/core/int-to-type.h @@ -11,7 +11,7 @@ namespace ns3 { template struct IntToType { - enum {value = v}; + enum v_e {value = v}; }; } // namespace ns3 From 94ee9fd47eaba248626359798738b3ca175d4fad Mon Sep 17 00:00:00 2001 From: Mathieu Lacage Date: Wed, 2 Jul 2008 13:22:14 -0700 Subject: [PATCH 105/495] no need for protected variables --- src/devices/wifi/jakes-propagation-loss-model.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/devices/wifi/jakes-propagation-loss-model.h b/src/devices/wifi/jakes-propagation-loss-model.h index 17ae36e63..bf7c76b50 100644 --- a/src/devices/wifi/jakes-propagation-loss-model.h +++ b/src/devices/wifi/jakes-propagation-loss-model.h @@ -97,7 +97,8 @@ public: * Set the number of oscillators to use to compute the ray coefficient */ void SetNOscillators (uint8_t nOscillators); -protected: + +private: class PathCoefficients; struct ComplexNumber { double real; @@ -109,7 +110,7 @@ protected: ComplexNumber* m_amp; RandomVariable m_variable; double m_fd; -private: + typedef std::vector DestinationList; struct PathsSet { Ptr sender; From f7c64385605be48d66f21e6f20ecd871b1a4ff8b Mon Sep 17 00:00:00 2001 From: Mathieu Lacage Date: Wed, 2 Jul 2008 13:22:32 -0700 Subject: [PATCH 106/495] no need for protected variables --- src/node/channel.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/node/channel.h b/src/node/channel.h index 78c3fc5f0..750a8ef20 100644 --- a/src/node/channel.h +++ b/src/node/channel.h @@ -44,6 +44,7 @@ public: Channel (); Channel (std::string name); + virtual ~Channel (); void SetName(std::string); std::string GetName(void); @@ -62,8 +63,7 @@ public: */ virtual Ptr GetDevice (uint32_t i) const = 0; -protected: - virtual ~Channel (); +private: std::string m_name; }; From ab3a728ba5e623da2c44b0a12e7b057a165cc34a Mon Sep 17 00:00:00 2001 From: Mathieu Lacage Date: Wed, 2 Jul 2008 13:22:46 -0700 Subject: [PATCH 107/495] no need for protected variables --- src/node/socket.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/node/socket.h b/src/node/socket.h index 21f060ca0..1c4e650e0 100644 --- a/src/node/socket.h +++ b/src/node/socket.h @@ -501,7 +501,7 @@ protected: void NotifyDataSent (uint32_t size); void NotifySend (uint32_t spaceAvailable); void NotifyDataRecv (void); - +private: Callback > m_connectionSucceeded; Callback > m_connectionFailed; Callback, const Address &> m_connectionRequest; From 7c7cfcc86545c96f38e8a40f35457b0f31e30e98 Mon Sep 17 00:00:00 2001 From: Mathieu Lacage Date: Wed, 2 Jul 2008 13:23:23 -0700 Subject: [PATCH 108/495] avoid pygccxml warning. --- src/node/address.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/node/address.h b/src/node/address.h index 7e1b5c3ef..b53c6bb6f 100644 --- a/src/node/address.h +++ b/src/node/address.h @@ -66,7 +66,7 @@ namespace ns3 { class Address { public: - enum { + enum MaxSize_e { /** * The maximum size of a byte buffer which * can be stored in an Address instance. From cf37954b0450a1d357727ce5da6fb41ce83fcf35 Mon Sep 17 00:00:00 2001 From: Mathieu Lacage Date: Wed, 2 Jul 2008 13:23:44 -0700 Subject: [PATCH 109/495] no need to export this header --- src/routing/global-routing/wscript | 1 - 1 file changed, 1 deletion(-) diff --git a/src/routing/global-routing/wscript b/src/routing/global-routing/wscript index b2758cc54..17816ade1 100644 --- a/src/routing/global-routing/wscript +++ b/src/routing/global-routing/wscript @@ -13,6 +13,5 @@ def build(bld): headers.source = [ 'global-router-interface.h', 'global-route-manager.h', - 'candidate-queue.h', ] From 74e8ce78453c736c50132e0b0bde1834f9ad02d9 Mon Sep 17 00:00:00 2001 From: Mathieu Lacage Date: Wed, 2 Jul 2008 13:23:54 -0700 Subject: [PATCH 110/495] no need for protected members --- src/routing/global-routing/candidate-queue.h | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/routing/global-routing/candidate-queue.h b/src/routing/global-routing/candidate-queue.h index 35747ec9f..c8b900e44 100644 --- a/src/routing/global-routing/candidate-queue.h +++ b/src/routing/global-routing/candidate-queue.h @@ -162,10 +162,6 @@ public: */ void Reorder (void); -protected: - typedef std::list CandidateList_t; - CandidateList_t m_candidates; - private: /** * Candidate Queue copy construction is disallowed (not implemented) to @@ -180,6 +176,9 @@ private: * properly deal with deep copies. */ CandidateQueue& operator= (CandidateQueue& sr); + + typedef std::list CandidateList_t; + CandidateList_t m_candidates; }; } // namespace ns3 From 0f27dc1b81090546c8b4cf0e4a77da6c4bdcadf0 Mon Sep 17 00:00:00 2001 From: Tom Henderson Date: Wed, 2 Jul 2008 21:07:36 -0700 Subject: [PATCH 111/495] close socket upon PacketSink::StopApplication() --- src/applications/packet-sink/packet-sink.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/src/applications/packet-sink/packet-sink.cc b/src/applications/packet-sink/packet-sink.cc index 3fdcce8c3..1b4e14bad 100644 --- a/src/applications/packet-sink/packet-sink.cc +++ b/src/applications/packet-sink/packet-sink.cc @@ -95,6 +95,7 @@ void PacketSink::StopApplication() // Called at time specified by Stop { if (m_socket) { + m_socket->Close (); m_socket->SetRecvCallback (MakeNullCallback > ()); } } From 12c6c43d57c617c1562bacf8d924a71e57d6bef3 Mon Sep 17 00:00:00 2001 From: Unknown Date: Thu, 3 Jul 2008 09:44:23 -0400 Subject: [PATCH 112/495] Minor doc notes added to ipv4.h --- src/internet-stack/wscript | 3 +++ src/node/ipv4.h | 10 ++++++++++ src/node/node.cc | 12 ++++++++++++ src/node/node.h | 7 +++++++ 4 files changed, 32 insertions(+) diff --git a/src/internet-stack/wscript b/src/internet-stack/wscript index 780a84a98..6f1b7bbd7 100644 --- a/src/internet-stack/wscript +++ b/src/internet-stack/wscript @@ -39,4 +39,7 @@ def build(bld): 'udp-header.h', 'tcp-header.h', 'sequence-number.h', + 'ipv4-interface.h', + 'ipv4-l3-protocol.h', + 'ipv4-static-routing.h', ] diff --git a/src/node/ipv4.h b/src/node/ipv4.h index d2157c959..f6ccec45e 100644 --- a/src/node/ipv4.h +++ b/src/node/ipv4.h @@ -425,6 +425,11 @@ public: /** * \param i index of ipv4 interface * \returns the address associated to the underlying ipv4 interface + * + * Note that the broadcast address for this interface may be fetched + * from the Ipv4Address object returned here using + * Ipv4Address::GetSubnetDirectedBroadcast(mask), where the mask for + * the interface may be retrived using Ipv4::GetNetworkMask(i). */ virtual Ipv4Address GetAddress (uint32_t i) const = 0; @@ -432,6 +437,11 @@ public: * \param destination The IP address of a hypothetical destination. * \returns The IP address assigned to the interface that will be used * if we were to send a packet to destination. + * + * Note that the broadcast address for this interface may be fetched + * from the Ipv4Address object returned here using + * Ipv4Address::GetSubnetDirectedBroadcast(mask), where the mask for + * the interface may be retrived using Ipv4::GetNetworkMask(i). */ virtual Ipv4Address GetSourceAddress (Ipv4Address destination) const = 0; diff --git a/src/node/node.cc b/src/node/node.cc index ef56ec6db..42813b294 100644 --- a/src/node/node.cc +++ b/src/node/node.cc @@ -128,6 +128,18 @@ Node::GetNApplications (void) const { return m_applications.size (); } +Ptr +Node::GetFirstApplication(TypeId tid) +{ + for (std::vector >::iterator i = m_applications.begin (); + i != m_applications.end (); i++) { + Ptr app = *i; + if (app->GetInstanceTypeId() == tid) + return app; + } + + return 0; +} void Node::DoDispose() diff --git a/src/node/node.h b/src/node/node.h index 8a48d1d62..ecd0bb2d7 100644 --- a/src/node/node.h +++ b/src/node/node.h @@ -122,6 +122,13 @@ public: * within this Node. */ Ptr GetApplication (uint32_t index) const; + /** + * \param index + * \returns the application associated to this requested index + * within this Node. + */ + Ptr GetFirstApplication (TypeId tid); + /** * \returns the number of applications associated to this Node. */ From b2b5de9d2270830ad2f044c5e9715a521de54cee Mon Sep 17 00:00:00 2001 From: Craig Dowell Date: Thu, 3 Jul 2008 15:44:54 -0700 Subject: [PATCH 113/495] bug 232, references to Parameter obsolete --- examples/csma-broadcast.cc | 4 ++-- examples/csma-multicast.cc | 4 ++-- examples/csma-one-subnet.cc | 4 ++-- examples/csma-packet-socket.cc | 2 +- examples/mixed-global-routing.cc | 12 ++++++------ examples/mixed-wireless.cc | 4 ++-- examples/simple-alternate-routing.cc | 10 +++++----- examples/simple-error-model.cc | 10 +++++----- examples/simple-global-routing.cc | 8 ++++---- examples/simple-point-to-point-olsr.cc | 8 ++++---- examples/tcp-large-transfer.cc | 6 +++--- examples/tcp-star-server.cc | 4 ++-- examples/udp-echo.cc | 4 ++-- src/helper/csma-helper.cc | 4 ++-- src/helper/csma-helper.h | 12 ++++++------ src/helper/olsr-helper.h | 2 +- src/helper/point-to-point-helper.cc | 4 ++-- src/helper/point-to-point-helper.h | 12 ++++++------ src/helper/wifi-helper.h | 2 +- 19 files changed, 58 insertions(+), 58 deletions(-) diff --git a/examples/csma-broadcast.cc b/examples/csma-broadcast.cc index 963be3ff5..64c20645d 100644 --- a/examples/csma-broadcast.cc +++ b/examples/csma-broadcast.cc @@ -69,8 +69,8 @@ main (int argc, char *argv[]) NS_LOG_INFO ("Build Topology."); CsmaHelper csma; - csma.SetChannelParameter ("DataRate", DataRateValue (DataRate(5000000))); - csma.SetChannelParameter ("Delay", TimeValue (MilliSeconds(2))); + csma.SetChannelAttribute ("DataRate", DataRateValue (DataRate(5000000))); + csma.SetChannelAttribute ("Delay", TimeValue (MilliSeconds(2))); NetDeviceContainer n0 = csma.Install (c0); NetDeviceContainer n1 = csma.Install (c1); diff --git a/examples/csma-multicast.cc b/examples/csma-multicast.cc index a7775c7b8..6b92958b8 100644 --- a/examples/csma-multicast.cc +++ b/examples/csma-multicast.cc @@ -75,8 +75,8 @@ main (int argc, char *argv[]) NS_LOG_INFO ("Build Topology."); CsmaHelper csma; - csma.SetChannelParameter ("DataRate", DataRateValue (DataRate (5000000))); - csma.SetChannelParameter ("Delay", TimeValue (MilliSeconds (2))); + csma.SetChannelAttribute ("DataRate", DataRateValue (DataRate (5000000))); + csma.SetChannelAttribute ("Delay", TimeValue (MilliSeconds (2))); // We will use these NetDevice containers later, for IP addressing NetDeviceContainer nd0 = csma.Install (c0); // First LAN diff --git a/examples/csma-one-subnet.cc b/examples/csma-one-subnet.cc index bd827b904..23514b117 100644 --- a/examples/csma-one-subnet.cc +++ b/examples/csma-one-subnet.cc @@ -66,8 +66,8 @@ main (int argc, char *argv[]) NS_LOG_INFO ("Build Topology"); CsmaHelper csma; - csma.SetChannelParameter ("DataRate", DataRateValue (5000000)); - csma.SetChannelParameter ("Delay", TimeValue (MilliSeconds (2))); + csma.SetChannelAttribute ("DataRate", DataRateValue (5000000)); + csma.SetChannelAttribute ("Delay", TimeValue (MilliSeconds (2))); // // Now fill out the topology by creating the net devices required to connect // the nodes to the channels and hooking them up. AddIpv4CsmaNetDevice will diff --git a/examples/csma-packet-socket.cc b/examples/csma-packet-socket.cc index f35fc77c5..a2798e216 100644 --- a/examples/csma-packet-socket.cc +++ b/examples/csma-packet-socket.cc @@ -74,7 +74,7 @@ main (int argc, char *argv[]) // use a helper function to connect our nodes to the shared channel. NS_LOG_INFO ("Build Topology."); CsmaHelper csma; - csma.SetDeviceParameter ("EncapsulationMode", StringValue ("Llc")); + csma.SetDeviceAttribute ("EncapsulationMode", StringValue ("Llc")); NetDeviceContainer devs = csma.Install (c, channel); NS_LOG_INFO ("Create Applications."); diff --git a/examples/mixed-global-routing.cc b/examples/mixed-global-routing.cc index dfa262414..18141a7d1 100644 --- a/examples/mixed-global-routing.cc +++ b/examples/mixed-global-routing.cc @@ -71,20 +71,20 @@ main (int argc, char *argv[]) // We create the channels first without any IP addressing information NS_LOG_INFO ("Create channels."); PointToPointHelper p2p; - p2p.SetDeviceParameter ("DataRate", StringValue ("5Mbps")); - p2p.SetChannelParameter ("Delay", StringValue ("2ms")); + p2p.SetDeviceAttribute ("DataRate", StringValue ("5Mbps")); + p2p.SetChannelAttribute ("Delay", StringValue ("2ms")); NetDeviceContainer d0d2 = p2p.Install (n0n2); NetDeviceContainer d1d2 = p2p.Install (n1n2); - p2p.SetDeviceParameter ("DataRate", StringValue ("1500kbps")); - p2p.SetChannelParameter ("Delay", StringValue ("10ms")); + p2p.SetDeviceAttribute ("DataRate", StringValue ("1500kbps")); + p2p.SetChannelAttribute ("Delay", StringValue ("10ms")); NetDeviceContainer d5d6 = p2p.Install (n5n6); // We create the channels first without any IP addressing information CsmaHelper csma; - csma.SetChannelParameter ("DataRate", StringValue ("5Mbps")); - csma.SetChannelParameter ("Delay", StringValue ("2ms")); + csma.SetChannelAttribute ("DataRate", StringValue ("5Mbps")); + csma.SetChannelAttribute ("Delay", StringValue ("2ms")); NetDeviceContainer d2345 = csma.Install (n2345); // Later, we add IP addresses. diff --git a/examples/mixed-wireless.cc b/examples/mixed-wireless.cc index 6b062b4d4..21ec3f850 100644 --- a/examples/mixed-wireless.cc +++ b/examples/mixed-wireless.cc @@ -200,9 +200,9 @@ main (int argc, char *argv[]) // collection. // CsmaHelper csma; - csma.SetChannelParameter ("DataRate", + csma.SetChannelAttribute ("DataRate", DataRateValue (DataRate (5000000))); - csma.SetChannelParameter ("Delay", TimeValue (MilliSeconds (2))); + csma.SetChannelAttribute ("Delay", TimeValue (MilliSeconds (2))); NetDeviceContainer lanDevices = csma.Install (lan); // // Add the IPv4 protocol stack to the new LAN nodes diff --git a/examples/simple-alternate-routing.cc b/examples/simple-alternate-routing.cc index 2d130e7f0..ad5446a1a 100644 --- a/examples/simple-alternate-routing.cc +++ b/examples/simple-alternate-routing.cc @@ -97,17 +97,17 @@ main (int argc, char *argv[]) // We create the channels first without any IP addressing information NS_LOG_INFO ("Create channels."); PointToPointHelper p2p; - p2p.SetDeviceParameter ("DataRate", StringValue ("5Mbps")); - p2p.SetChannelParameter ("Delay", StringValue ("2ms")); + p2p.SetDeviceAttribute ("DataRate", StringValue ("5Mbps")); + p2p.SetChannelAttribute ("Delay", StringValue ("2ms")); NetDeviceContainer d0d2 = p2p.Install (n0n2); NetDeviceContainer d1d2 = p2p.Install (n1n2); - p2p.SetDeviceParameter ("DataRate", StringValue ("1500kbps")); - p2p.SetChannelParameter ("Delay", StringValue ("10ms")); + p2p.SetDeviceAttribute ("DataRate", StringValue ("1500kbps")); + p2p.SetChannelAttribute ("Delay", StringValue ("10ms")); NetDeviceContainer d3d2 = p2p.Install (n3n2); - p2p.SetChannelParameter ("Delay", StringValue ("100ms")); + p2p.SetChannelAttribute ("Delay", StringValue ("100ms")); NetDeviceContainer d1d3 = p2p.Install (n1n3); InternetStackHelper internet; diff --git a/examples/simple-error-model.cc b/examples/simple-error-model.cc index 71d022200..3fbc8c355 100644 --- a/examples/simple-error-model.cc +++ b/examples/simple-error-model.cc @@ -64,7 +64,7 @@ main (int argc, char *argv[]) // RandomVariable::UseGlobalSeed (1, 1, 2, 3, 5, 8); - // Set a few parameters + // Set a few attributes Config::SetDefault ("ns3::RateErrorModel::ErrorRate", DoubleValue (0.01)); Config::SetDefault ("ns3::RateErrorModel::ErrorUnit", StringValue ("EU_PKT")); @@ -92,14 +92,14 @@ main (int argc, char *argv[]) // We create the channels first without any IP addressing information NS_LOG_INFO ("Create channels."); PointToPointHelper p2p; - p2p.SetDeviceParameter ("DataRate", DataRateValue (DataRate (5000000))); - p2p.SetChannelParameter ("Delay", TimeValue (MilliSeconds (2))); + p2p.SetDeviceAttribute ("DataRate", DataRateValue (DataRate (5000000))); + p2p.SetChannelAttribute ("Delay", TimeValue (MilliSeconds (2))); NetDeviceContainer d0d2 = p2p.Install (n0n2); NetDeviceContainer d1d2 = p2p.Install (n1n2); - p2p.SetDeviceParameter ("DataRate", DataRateValue (DataRate (1500000))); - p2p.SetChannelParameter ("Delay", TimeValue (MilliSeconds (10))); + p2p.SetDeviceAttribute ("DataRate", DataRateValue (DataRate (1500000))); + p2p.SetChannelAttribute ("Delay", TimeValue (MilliSeconds (10))); NetDeviceContainer d3d2 = p2p.Install (n3n2); // Later, we add IP addresses. diff --git a/examples/simple-global-routing.cc b/examples/simple-global-routing.cc index 35fb96d94..a0ddb0d7a 100644 --- a/examples/simple-global-routing.cc +++ b/examples/simple-global-routing.cc @@ -92,14 +92,14 @@ main (int argc, char *argv[]) // We create the channels first without any IP addressing information NS_LOG_INFO ("Create channels."); PointToPointHelper p2p; - p2p.SetDeviceParameter ("DataRate", StringValue ("5Mbps")); - p2p.SetChannelParameter ("Delay", StringValue ("2ms")); + p2p.SetDeviceAttribute ("DataRate", StringValue ("5Mbps")); + p2p.SetChannelAttribute ("Delay", StringValue ("2ms")); NetDeviceContainer d0d2 = p2p.Install (n0n2); NetDeviceContainer d1d2 = p2p.Install (n1n2); - p2p.SetDeviceParameter ("DataRate", StringValue ("1500kbps")); - p2p.SetChannelParameter ("Delay", StringValue ("10ms")); + p2p.SetDeviceAttribute ("DataRate", StringValue ("1500kbps")); + p2p.SetChannelAttribute ("Delay", StringValue ("10ms")); NetDeviceContainer d3d2 = p2p.Install (n3n2); // Later, we add IP addresses. diff --git a/examples/simple-point-to-point-olsr.cc b/examples/simple-point-to-point-olsr.cc index e11816bff..5079706ed 100644 --- a/examples/simple-point-to-point-olsr.cc +++ b/examples/simple-point-to-point-olsr.cc @@ -93,12 +93,12 @@ main (int argc, char *argv[]) // We create the channels first without any IP addressing information NS_LOG_INFO ("Create channels."); PointToPointHelper p2p; - p2p.SetDeviceParameter ("DataRate", StringValue ("5Mbps")); - p2p.SetChannelParameter ("Delay", StringValue ("2ms")); + p2p.SetDeviceAttribute ("DataRate", StringValue ("5Mbps")); + p2p.SetChannelAttribute ("Delay", StringValue ("2ms")); NetDeviceContainer nd02 = p2p.Install (n02); NetDeviceContainer nd12 = p2p.Install (n12); - p2p.SetDeviceParameter ("DataRate", StringValue ("1500kbps")); - p2p.SetChannelParameter ("Delay", StringValue ("10ms")); + p2p.SetDeviceAttribute ("DataRate", StringValue ("1500kbps")); + p2p.SetChannelAttribute ("Delay", StringValue ("10ms")); NetDeviceContainer nd32 = p2p.Install (n32); NetDeviceContainer nd34 = p2p.Install (n34); diff --git a/examples/tcp-large-transfer.cc b/examples/tcp-large-transfer.cc index f052b478c..d4afeab08 100644 --- a/examples/tcp-large-transfer.cc +++ b/examples/tcp-large-transfer.cc @@ -90,10 +90,10 @@ int main (int argc, char *argv[]) // We create the channels first without any IP addressing information // First make and configure the helper, so that it will put the appropriate - // parameters on the network interfaces and channels we are about to install. + // attributes on the network interfaces and channels we are about to install. PointToPointHelper p2p; - p2p.SetDeviceParameter ("DataRate", DataRateValue (DataRate(10000000))); - p2p.SetChannelParameter ("Delay", TimeValue (MilliSeconds(10))); + p2p.SetDeviceAttribute ("DataRate", DataRateValue (DataRate(10000000))); + p2p.SetChannelAttribute ("Delay", TimeValue (MilliSeconds(10))); // And then install devices and channels connecting our topology. NetDeviceContainer dev0 = p2p.Install (n0n1); diff --git a/examples/tcp-star-server.cc b/examples/tcp-star-server.cc index 81c7f58f3..ca79d681e 100644 --- a/examples/tcp-star-server.cc +++ b/examples/tcp-star-server.cc @@ -106,8 +106,8 @@ main (int argc, char *argv[]) // We create the channels first without any IP addressing information NS_LOG_INFO ("Create channels."); PointToPointHelper p2p; - p2p.SetDeviceParameter ("DataRate", StringValue ("5Mbps")); - p2p.SetChannelParameter ("Delay", StringValue ("2ms")); + p2p.SetDeviceAttribute ("DataRate", StringValue ("5Mbps")); + p2p.SetChannelAttribute ("Delay", StringValue ("2ms")); std::vector deviceAdjacencyList(N-1); for(uint32_t i=0; i channel); diff --git a/src/helper/olsr-helper.h b/src/helper/olsr-helper.h index cce8e4aea..d2eaea80d 100644 --- a/src/helper/olsr-helper.h +++ b/src/helper/olsr-helper.h @@ -35,7 +35,7 @@ public: OlsrHelper (); /** - * \brief Set default OLSR routing agent parameters + * \brief Set default OLSR routing agent attributes */ void SetAgent (std::string tid, std::string n0 = "", const AttributeValue &v0 = EmptyAttributeValue (), diff --git a/src/helper/point-to-point-helper.cc b/src/helper/point-to-point-helper.cc index 7f1fbcd03..eba654a17 100644 --- a/src/helper/point-to-point-helper.cc +++ b/src/helper/point-to-point-helper.cc @@ -52,13 +52,13 @@ PointToPointHelper::SetQueue (std::string type, } void -PointToPointHelper::SetDeviceParameter (std::string n1, const AttributeValue &v1) +PointToPointHelper::SetDeviceAttribute (std::string n1, const AttributeValue &v1) { m_deviceFactory.Set (n1, v1); } void -PointToPointHelper::SetChannelParameter (std::string n1, const AttributeValue &v1) +PointToPointHelper::SetChannelAttribute (std::string n1, const AttributeValue &v1) { m_channelFactory.Set (n1, v1); } diff --git a/src/helper/point-to-point-helper.h b/src/helper/point-to-point-helper.h index f945a144f..7603a50d0 100644 --- a/src/helper/point-to-point-helper.h +++ b/src/helper/point-to-point-helper.h @@ -65,18 +65,18 @@ public: * \param name the name of the attribute to set * \param value the value of the attribute to set * - * Set these parameters on each ns3::PointToPointNetDevice created + * Set these attributes on each ns3::PointToPointNetDevice created * by PointToPointHelper::Install */ - void SetDeviceParameter (std::string name, const AttributeValue &value); + void SetDeviceAttribute (std::string name, const AttributeValue &value); /** * \param name the name of the attribute to set * \param value the value of the attribute to set * - * Set these parameters on each ns3::PointToPointChannel created + * Set these attribute on each ns3::PointToPointChannel created * by PointToPointHelper::Install */ - void SetChannelParameter (std::string name, const AttributeValue &value); + void SetChannelAttribute (std::string name, const AttributeValue &value); /** * \param filename filename prefix to use for pcap files. @@ -159,9 +159,9 @@ public: * \param c a set of nodes * * This method creates a ns3::PointToPointChannel with the - * attributes configured by PointToPointHelper::SetChannelParameter, + * attributes configured by PointToPointHelper::SetChannelAttribute, * then, for each node in the input container, we create a - * ns3::PointToPointNetDevice with the requested parameters, + * ns3::PointToPointNetDevice with the requested attributes, * a queue for this ns3::NetDevice, and associate the resulting * ns3::NetDevice with the ns3::Node and ns3::PointToPointChannel. */ diff --git a/src/helper/wifi-helper.h b/src/helper/wifi-helper.h index 35ec3141b..72cc4a198 100644 --- a/src/helper/wifi-helper.h +++ b/src/helper/wifi-helper.h @@ -35,7 +35,7 @@ class WifiChannel; * * This class can help to create a large set of similar * WifiNetDevice objects and to configure a large set of - * their parameters during creation. + * their attributes during creation. */ class WifiHelper { From 26b91a3c6c9835a0d9186b9826f84acfa0664c0f Mon Sep 17 00:00:00 2001 From: Craig Dowell Date: Thu, 3 Jul 2008 17:37:32 -0700 Subject: [PATCH 114/495] fix bug 234 which changes required methods on helpers to constructor parameters. Update tutorial content to reflect. Change RemoteIpv4 attribute to RemoteAddress. --- doc/tutorial/building-topologies.texi | 45 +++++++++++--------- doc/tutorial/conceptual-overview.texi | 23 +++++----- doc/tutorial/tweaking.texi | 8 ++-- examples/first.cc | 16 +++---- examples/second.cc | 16 +++---- examples/third.cc | 16 +++---- examples/udp-echo.cc | 12 +++--- src/applications/udp-echo/udp-echo-client.cc | 4 +- src/helper/udp-echo-helper.cc | 36 ++++++++-------- src/helper/udp-echo-helper.h | 18 ++++---- 10 files changed, 98 insertions(+), 96 deletions(-) diff --git a/doc/tutorial/building-topologies.texi b/doc/tutorial/building-topologies.texi index 04b737df3..5ee28dde8 100644 --- a/doc/tutorial/building-topologies.texi +++ b/doc/tutorial/building-topologies.texi @@ -149,8 +149,8 @@ helper and a two millisecond delay on channels created by the helper. @verbatim PointToPointHelper pointToPoint; - pointToPoint.SetDeviceParameter ("DataRate", StringValue ("5Mbps")); - pointToPoint.SetChannelParameter ("Delay", StringValue ("2ms")); + pointToPoint.SetDeviceAttribute ("DataRate", StringValue ("5Mbps")); + pointToPoint.SetChannelAttribute ("Delay", StringValue ("2ms")); NetDeviceContainer p2pDevices; p2pDevices = pointToPoint.Install (p2pNodes); @@ -227,9 +227,15 @@ going to be fundamentally similar to the applications section of nodes that has a CSMA node and the client on the node having only a point-to-point device. -First, we set up the echo server. +First, we set up the echo server. We create a @code{UdpEchoServerHelper} and +provide a required attribute value to the constructor which is the server port +number. Recall that this port can be changed later using the +@code{SetAttribute} method if desired, but we require it to be provided to +the constructor. @verbatim + UdpEchoServerHelper echoServer (9); + ApplicationContainer serverApps = echoServer.Install (csmaNodes.Get (nCsma)); serverApps.Start (Seconds (1.0)); serverApps.Stop (Seconds (10.0)); @@ -246,16 +252,17 @@ if we create @code{nCsma} ``extra'' nodes the last one will be at index code. The client application is set up exactly as we did in the @code{first.cc} -example script. We tell the client to send packets to the server we just -installed on the last of the ``extra'' CSMA nodes. We install the client on -the leftmost point-to-point node seen in the topology illustration. +example script. Again, we provide required attributes to the +@code{UdpEchoClientHelper} in the constructor (in this case the remote address +and port). We tell the client to send packets to the server we just installed +on the last of the ``extra'' CSMA nodes. We install the client on the +leftmost point-to-point node seen in the topology illustration. @verbatim - UdpEchoClientHelper echoClient; - echoClient.SetRemote (csmaInterfaces.GetAddress (nCsma), 9); - echoClient.SetAppAttribute ("MaxPackets", UintegerValue (1)); - echoClient.SetAppAttribute ("Interval", TimeValue (Seconds (1.))); - echoClient.SetAppAttribute ("PacketSize", UintegerValue (1024)); + UdpEchoClientHelper echoClient (csmaInterfaces.GetAddress (nCsma), 9); + echoClient.SetAttribute ("MaxPackets", UintegerValue (1)); + echoClient.SetAttribute ("Interval", TimeValue (Seconds (1.))); + echoClient.SetAttribute ("PacketSize", UintegerValue (1024)); ApplicationContainer clientApps = echoClient.Install (p2pNodes.Get (0)); clientApps.Start (Seconds (2.0)); @@ -669,8 +676,8 @@ on the nodes and the channel between them. @verbatim PointToPointHelper pointToPoint; - pointToPoint.SetDeviceParameter ("DataRate", StringValue ("5Mbps")); - pointToPoint.SetChannelParameter ("Delay", StringValue ("2ms")); + pointToPoint.SetDeviceAttribute ("DataRate", StringValue ("5Mbps")); + pointToPoint.SetChannelAttribute ("Delay", StringValue ("2ms")); NetDeviceContainer p2pDevices; p2pDevices = pointToPoint.Install (p2pNodes); @@ -964,8 +971,7 @@ We put the echo server on the ``rightmost'' node in the illustration at the start of the file. We have done this before. @verbatim - UdpEchoServerHelper echoServer; - echoServer.SetPort (9); + UdpEchoServerHelper echoServer (9); ApplicationContainer serverApps = echoServer.Install (csmaNodes.Get (nCsma)); serverApps.Start (Seconds (1.0)); @@ -976,11 +982,10 @@ And we put the echo client on the last STA node we created, pointing it to the server on the CSMA network. We have also seen similar operations before. @verbatim - UdpEchoClientHelper echoClient; - echoClient.SetRemote (csmaInterfaces.GetAddress (nCsma), 9); - echoClient.SetAppAttribute ("MaxPackets", UintegerValue (1)); - echoClient.SetAppAttribute ("Interval", TimeValue (Seconds (1.))); - echoClient.SetAppAttribute ("PacketSize", UintegerValue (1024)); + UdpEchoClientHelper echoClient (csmaInterfaces.GetAddress (nCsma), 9); + echoClient.SetAttribute ("MaxPackets", UintegerValue (1)); + echoClient.SetAttribute ("Interval", TimeValue (Seconds (1.))); + echoClient.SetAttribute ("PacketSize", UintegerValue (1024)); ApplicationContainer clientApps = echoClient.Install (wifiStaNodes.Get (nWifi - 1)); diff --git a/doc/tutorial/conceptual-overview.texi b/doc/tutorial/conceptual-overview.texi index 232df70f3..7cb4ad452 100644 --- a/doc/tutorial/conceptual-overview.texi +++ b/doc/tutorial/conceptual-overview.texi @@ -420,8 +420,8 @@ The next three lines in the script are, @verbatim PointToPointHelper pointToPoint; - pointToPoint.SetDeviceParameter ("DataRate", StringValue ("5Mbps")); - pointToPoint.SetChannelParameter ("Delay", StringValue ("2ms")); + pointToPoint.SetDeviceAttribute ("DataRate", StringValue ("5Mbps")); + pointToPoint.SetChannelAttribute ("Delay", StringValue ("2ms")); @end verbatim The first line @@ -434,7 +434,7 @@ instantiates a @code{PointToPointHelper} object on the stack. From a high-level perspective the next line, @verbatim - pointToPoint.SetDeviceParameter ("DataRate", StringValue ("5Mbps")); + pointToPoint.SetDeviceAttribute ("DataRate", StringValue ("5Mbps")); @end verbatim tells the @code{PointToPointHelper} object to use the value ``5mbps'' @@ -455,7 +455,7 @@ Similar to the ``DataRate'' on the @code{PointToPointNetDevice} you will find a final line, @verbatim - pointToPoint.SetChannelParameter ("Delay", StringValue ("2ms")); + pointToPoint.SetChannelAttribute ("Delay", StringValue ("2ms")); @end verbatim tells the @code{PointToPointHelper} to use the value ``2ms'' (two milliseconds) @@ -565,8 +565,7 @@ to set up a UDP echo server application on one of the nodes we have previously created. @verbatim - UdpEchoServerHelper echoServer; - echoServer.SetPort (9); + UdpEchoServerHelper echoServer (9); ApplicationContainer serverApps = echoServer.Install (nodes.Get (1)); serverApps.Start (Seconds (1.0)); @@ -575,10 +574,14 @@ created. The first line of code in the above snippet declares the @code{UdpEchoServerHelper}. As usual, this isn't the application itself, it -is an object used to help us create the actual applications. The second line -that has the @code{SetPort} call, is used to tell the helper to assign the -value nine to the ``Port'' attribute when creating -@code{UdpEchoServerApplication} objects. +is an object used to help us create the actual applications. One of our +conventions is place required attributes in the helper constructor. In this +case, the helper can't do anything useful unless it is provided with a port +number that the client also knows about. Rather than just picking one and +hoping it all works out, we require the port number as a parameter to the +constructor. The constructor, in turn, simply does a @code{SetAttribute} +with the passed value. You can, if desired, set the ``Port'' attribute to +another value later. Similar to many other helper objects, the @code{UdpEchoServerHelper} object has an @code{Install} method. It is the execution of this method that actually diff --git a/doc/tutorial/tweaking.texi b/doc/tutorial/tweaking.texi index 1a8623392..9b01449fe 100644 --- a/doc/tutorial/tweaking.texi +++ b/doc/tutorial/tweaking.texi @@ -462,8 +462,8 @@ at the @command{ns-3} attribute system while walking through the @verbatim PointToPointHelper pointToPoint; - pointToPoint.SetDeviceParameter ("DataRate", StringValue ("5Mbps")); - pointToPoint.SetChannelParameter ("Delay", StringValue ("2ms")); + pointToPoint.SetDeviceAttribute ("DataRate", StringValue ("5Mbps")); + pointToPoint.SetChannelAttribute ("Delay", StringValue ("2ms")); @end verbatim and mentioned that @code{DataRate} was actually an @code{Attribute} of the @@ -486,10 +486,10 @@ Among the attributes you will see listed is, @end verbatim This is the default value that will be used when a @code{PointToPointNetDevice} -is created in the system. We overrode this default with the ``parameter'' +is created in the system. We overrode this default with the attribute setting in the @code{PointToPointHelper} above. Let's use the default values for the point-to-point devices and channels by deleting the -@code{SetDeviceParameter} call and the @code{SetChannelParameter} call from +@code{SetDeviceAttribute} call and the @code{SetChannelAttribute} call from the @code{first.cc} we have in the scratch directory. Your script should now just declare the @code{PointToPointHelper} and not do diff --git a/examples/first.cc b/examples/first.cc index 74d7f54f3..0461d4cc9 100644 --- a/examples/first.cc +++ b/examples/first.cc @@ -33,8 +33,8 @@ main (int argc, char *argv[]) nodes.Create (2); PointToPointHelper pointToPoint; - pointToPoint.SetDeviceParameter ("DataRate", StringValue ("5Mbps")); - pointToPoint.SetChannelParameter ("Delay", StringValue ("2ms")); + pointToPoint.SetDeviceAttribute ("DataRate", StringValue ("5Mbps")); + pointToPoint.SetChannelAttribute ("Delay", StringValue ("2ms")); NetDeviceContainer devices; devices = pointToPoint.Install (nodes); @@ -47,18 +47,16 @@ main (int argc, char *argv[]) Ipv4InterfaceContainer interfaces = address.Assign (devices); - UdpEchoServerHelper echoServer; - echoServer.SetPort (9); + UdpEchoServerHelper echoServer (9); ApplicationContainer serverApps = echoServer.Install (nodes.Get (1)); serverApps.Start (Seconds (1.0)); serverApps.Stop (Seconds (10.0)); - UdpEchoClientHelper echoClient; - echoClient.SetRemote (interfaces.GetAddress (1), 9); - echoClient.SetAppAttribute ("MaxPackets", UintegerValue (1)); - echoClient.SetAppAttribute ("Interval", TimeValue (Seconds (1.))); - echoClient.SetAppAttribute ("PacketSize", UintegerValue (1024)); + UdpEchoClientHelper echoClient (interfaces.GetAddress (1), 9); + echoClient.SetAttribute ("MaxPackets", UintegerValue (1)); + echoClient.SetAttribute ("Interval", TimeValue (Seconds (1.))); + echoClient.SetAttribute ("PacketSize", UintegerValue (1024)); ApplicationContainer clientApps = echoClient.Install (nodes.Get (0)); clientApps.Start (Seconds (2.0)); diff --git a/examples/second.cc b/examples/second.cc index 817a5e0b9..a54205f58 100644 --- a/examples/second.cc +++ b/examples/second.cc @@ -52,8 +52,8 @@ main (int argc, char *argv[]) csmaNodes.Create (nCsma); PointToPointHelper pointToPoint; - pointToPoint.SetDeviceParameter ("DataRate", StringValue ("5Mbps")); - pointToPoint.SetChannelParameter ("Delay", StringValue ("2ms")); + pointToPoint.SetDeviceAttribute ("DataRate", StringValue ("5Mbps")); + pointToPoint.SetChannelAttribute ("Delay", StringValue ("2ms")); NetDeviceContainer p2pDevices; p2pDevices = pointToPoint.Install (p2pNodes); @@ -76,18 +76,16 @@ main (int argc, char *argv[]) Ipv4InterfaceContainer csmaInterfaces; csmaInterfaces = address.Assign (csmaDevices); - UdpEchoServerHelper echoServer; - echoServer.SetPort (9); + UdpEchoServerHelper echoServer (9); ApplicationContainer serverApps = echoServer.Install (csmaNodes.Get (nCsma)); serverApps.Start (Seconds (1.0)); serverApps.Stop (Seconds (10.0)); - UdpEchoClientHelper echoClient; - echoClient.SetRemote (csmaInterfaces.GetAddress (nCsma), 9); - echoClient.SetAppAttribute ("MaxPackets", UintegerValue (1)); - echoClient.SetAppAttribute ("Interval", TimeValue (Seconds (1.))); - echoClient.SetAppAttribute ("PacketSize", UintegerValue (1024)); + UdpEchoClientHelper echoClient (csmaInterfaces.GetAddress (nCsma), 9); + echoClient.SetAttribute ("MaxPackets", UintegerValue (1)); + echoClient.SetAttribute ("Interval", TimeValue (Seconds (1.))); + echoClient.SetAttribute ("PacketSize", UintegerValue (1024)); ApplicationContainer clientApps = echoClient.Install (p2pNodes.Get (0)); clientApps.Start (Seconds (2.0)); diff --git a/examples/third.cc b/examples/third.cc index 7660d45a1..2c561c2e2 100644 --- a/examples/third.cc +++ b/examples/third.cc @@ -54,8 +54,8 @@ main (int argc, char *argv[]) p2pNodes.Create (2); PointToPointHelper pointToPoint; - pointToPoint.SetDeviceParameter ("DataRate", StringValue ("5Mbps")); - pointToPoint.SetChannelParameter ("Delay", StringValue ("2ms")); + pointToPoint.SetDeviceAttribute ("DataRate", StringValue ("5Mbps")); + pointToPoint.SetChannelAttribute ("Delay", StringValue ("2ms")); NetDeviceContainer p2pDevices; p2pDevices = pointToPoint.Install (p2pNodes); @@ -141,18 +141,16 @@ main (int argc, char *argv[]) address.Assign (staDevices); address.Assign (apDevices); - UdpEchoServerHelper echoServer; - echoServer.SetPort (9); + UdpEchoServerHelper echoServer (9); ApplicationContainer serverApps = echoServer.Install (csmaNodes.Get (nCsma)); serverApps.Start (Seconds (1.0)); serverApps.Stop (Seconds (10.0)); - UdpEchoClientHelper echoClient; - echoClient.SetRemote (csmaInterfaces.GetAddress (nCsma), 9); - echoClient.SetAppAttribute ("MaxPackets", UintegerValue (1)); - echoClient.SetAppAttribute ("Interval", TimeValue (Seconds (1.))); - echoClient.SetAppAttribute ("PacketSize", UintegerValue (1024)); + UdpEchoClientHelper echoClient (csmaInterfaces.GetAddress (nCsma), 9); + echoClient.SetAttribute ("MaxPackets", UintegerValue (1)); + echoClient.SetAttribute ("Interval", TimeValue (Seconds (1.))); + echoClient.SetAttribute ("PacketSize", UintegerValue (1024)); ApplicationContainer clientApps = echoClient.Install (wifiStaNodes.Get (nWifi - 1)); diff --git a/examples/udp-echo.cc b/examples/udp-echo.cc index eb9fd54b5..362c398ab 100644 --- a/examples/udp-echo.cc +++ b/examples/udp-echo.cc @@ -104,8 +104,7 @@ main (int argc, char *argv[]) // Create a UdpEchoServer application on node one. // uint16_t port = 9; // well-known echo port number - UdpEchoServerHelper server; - server.SetPort (port); + UdpEchoServerHelper server (port); ApplicationContainer apps = server.Install (n.Get(1)); apps.Start (Seconds (1.0)); apps.Stop (Seconds (10.0)); @@ -117,11 +116,10 @@ main (int argc, char *argv[]) uint32_t packetSize = 1024; uint32_t maxPacketCount = 1; Time interPacketInterval = Seconds (1.); - UdpEchoClientHelper client; - client.SetRemote (i.GetAddress (1), port); - client.SetAppAttribute ("MaxPackets", UintegerValue (maxPacketCount)); - client.SetAppAttribute ("Interval", TimeValue (interPacketInterval)); - client.SetAppAttribute ("PacketSize", UintegerValue (packetSize)); + UdpEchoClientHelper client (i.GetAddress (1), port); + client.SetAttribute ("MaxPackets", UintegerValue (maxPacketCount)); + client.SetAttribute ("Interval", TimeValue (interPacketInterval)); + client.SetAttribute ("PacketSize", UintegerValue (packetSize)); apps = client.Install (n.Get (0)); apps.Start (Seconds (2.0)); apps.Stop (Seconds (10.0)); diff --git a/src/applications/udp-echo/udp-echo-client.cc b/src/applications/udp-echo/udp-echo-client.cc index 9580b7dbe..d92779aa3 100644 --- a/src/applications/udp-echo/udp-echo-client.cc +++ b/src/applications/udp-echo/udp-echo-client.cc @@ -47,8 +47,8 @@ UdpEchoClient::GetTypeId (void) TimeValue (Seconds (1.0)), MakeTimeAccessor (&UdpEchoClient::m_interval), MakeTimeChecker ()) - .AddAttribute ("RemoteIpv4", - "The Ipv4Address of the outbound packets", + .AddAttribute ("RemoteAddress", + "The destination Ipv4Address of the outbound packets", Ipv4AddressValue (), MakeIpv4AddressAccessor (&UdpEchoClient::m_peerAddress), MakeIpv4AddressChecker ()) diff --git a/src/helper/udp-echo-helper.cc b/src/helper/udp-echo-helper.cc index ef5f59777..c346cb6b2 100644 --- a/src/helper/udp-echo-helper.cc +++ b/src/helper/udp-echo-helper.cc @@ -24,15 +24,21 @@ namespace ns3 { -UdpEchoServerHelper::UdpEchoServerHelper () - : m_port (9) -{} +UdpEchoServerHelper::UdpEchoServerHelper (uint16_t port) +{ + m_factory.SetTypeId (UdpEchoServer::GetTypeId ()); + SetAttribute ("Port", UintegerValue(port)); +} void -UdpEchoServerHelper::SetPort (uint16_t port) +UdpEchoServerHelper::SetAttribute ( + std::string name, + const AttributeValue &value) { - m_port = port; + m_factory.Set (name, value); } + + ApplicationContainer UdpEchoServerHelper::Install (NodeContainer c) { @@ -40,25 +46,24 @@ UdpEchoServerHelper::Install (NodeContainer c) for (NodeContainer::Iterator i = c.Begin (); i != c.End (); ++i) { Ptr node = *i; - Ptr server = CreateObject ("Port", UintegerValue (m_port)); + Ptr server = m_factory.Create (); node->AddApplication (server); apps.Add (server); } return apps; } -UdpEchoClientHelper::UdpEchoClientHelper () +UdpEchoClientHelper::UdpEchoClientHelper (Ipv4Address address, uint16_t port) { m_factory.SetTypeId (UdpEchoClient::GetTypeId ()); + SetAttribute ("RemoteAddress", Ipv4AddressValue (address)); + SetAttribute ("RemotePort", UintegerValue (port)); } + void -UdpEchoClientHelper::SetRemote (Ipv4Address ip, uint16_t port) -{ - m_remoteIp = ip; - m_remotePort = port; -} -void -UdpEchoClientHelper::SetAppAttribute (std::string name, const AttributeValue &value) +UdpEchoClientHelper::SetAttribute ( + std::string name, + const AttributeValue &value) { m_factory.Set (name, value); } @@ -71,13 +76,10 @@ UdpEchoClientHelper::Install (NodeContainer c) { Ptr node = *i; Ptr client = m_factory.Create (); - client->SetRemote (m_remoteIp, m_remotePort); node->AddApplication (client); apps.Add (client); } return apps; } - - } // namespace ns3 diff --git a/src/helper/udp-echo-helper.h b/src/helper/udp-echo-helper.h index ef13c959a..4e06519a1 100644 --- a/src/helper/udp-echo-helper.h +++ b/src/helper/udp-echo-helper.h @@ -31,25 +31,25 @@ namespace ns3 { class UdpEchoServerHelper { public: - UdpEchoServerHelper (); - void SetPort (uint16_t port); + UdpEchoServerHelper (uint16_t port); + + void SetAttribute (std::string name, const AttributeValue &value); ApplicationContainer Install (NodeContainer c); -private: - uint16_t m_port; + + private: + ObjectFactory m_factory; }; class UdpEchoClientHelper { public: - UdpEchoClientHelper (); + UdpEchoClientHelper (Ipv4Address ip, uint16_t port); - void SetRemote (Ipv4Address ip, uint16_t port); - void SetAppAttribute (std::string name, const AttributeValue &value); + void SetAttribute (std::string name, const AttributeValue &value); ApplicationContainer Install (NodeContainer c); + private: ObjectFactory m_factory; - Ipv4Address m_remoteIp; - uint16_t m_remotePort; }; From d8a6c6f3365dde5206620a014edbdefecf5b96db Mon Sep 17 00:00:00 2001 From: Craig Dowell Date: Thu, 3 Jul 2008 20:03:03 -0700 Subject: [PATCH 115/495] some slips of the keyboard in tutorial --- doc/tutorial/conceptual-overview.texi | 40 +++++++++++++-------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/doc/tutorial/conceptual-overview.texi b/doc/tutorial/conceptual-overview.texi index 7cb4ad452..50656b937 100644 --- a/doc/tutorial/conceptual-overview.texi +++ b/doc/tutorial/conceptual-overview.texi @@ -575,7 +575,7 @@ created. The first line of code in the above snippet declares the @code{UdpEchoServerHelper}. As usual, this isn't the application itself, it is an object used to help us create the actual applications. One of our -conventions is place required attributes in the helper constructor. In this +conventions is to place required attributes in the helper constructor. In this case, the helper can't do anything useful unless it is provided with a port number that the client also knows about. Rather than just picking one and hoping it all works out, we require the port number as a parameter to the @@ -624,32 +624,32 @@ that for the server. There is an underlying @code{UdpEchoClientApplication} that is managed by an @code{UdpEchoClientHelper}. @verbatim - UdpEchoClientHelper echoClient; - echoClient.SetRemote (interfaces.GetAddress (1), 9); - echoClient.SetAppAttribute ("MaxPackets", UintegerValue (1)); - echoClient.SetAppAttribute ("Interval", TimeValue (Seconds (1.))); - echoClient.SetAppAttribute ("PacketSize", UintegerValue (1024)); + UdpEchoClientHelper echoClient (interfaces.GetAddress (1), 9); + echoClient.SetAttribute ("MaxPackets", UintegerValue (1)); + echoClient.SetAttribute ("Interval", TimeValue (Seconds (1.))); + echoClient.SetAttribute ("PacketSize", UintegerValue (1024)); ApplicationContainer clientApps = echoClient.Install (nodes.Get (0)); clientApps.Start (Seconds (2.0)); clientApps.Stop (Seconds (10.0)); @end verbatim -For the echo client, however, we need to set four different attributes. The -first attribute is set using the @code{SetRemote} method. Recall that -we used an @code{Ipv4InterfaceContainer} to keep track of the IP addresses we -assigned to our devices. The zeroth interface in the @code{interfaces} -container is going to coorespond to the IP address of the zeroth node in the -@code{nodes} container. The first interface in the @code{interfaces} -container cooresponds to the IP address of the first node in the @code{nodes} -container. So, in the following line of code (reproduced from above), we are -setting the remote address of the client to be the IP address assigned to the -node on which the server resides. We also tell it to send packets to port -nine while we are at ti. +For the echo client, however, we need to set five different attributes. The +first two attributes are set during construction of the +@code{UdpEchoClientHelper}. We pass parameters that are used (internally to +the helper) to set the ``RemoteAddress'' and ``RemotePort'' attributes in +accordance with our convention to make required attributes parameters in the +helper constructors. -@verbatim - echoClient.SetRemote (interfaces.GetAddress (1), 9); -@end verbatim +Recall that we used an @code{Ipv4InterfaceContainer} to keep track of the IP +addresses we assigned to our devices. The zeroth interface in the +@code{interfaces} container is going to coorespond to the IP address of the +zeroth node in the @code{nodes} container. The first interface in the +@code{interfaces} container cooresponds to the IP address of the first node +in the @code{nodes} container. So, in the first line of code (from above), we +are creating the helper and telling it so set the remote address of the client +to be the IP address assigned to the node on which the server resides. We +also tell it to arrange to send packets to port nine. The ``MaxPackets'' attribute tells the client the maximum number of packets we allow it to send during the simulation. The ``Interval'' attribute tells From 45334ff8de704b42047d0e9aac2221d9420163e8 Mon Sep 17 00:00:00 2001 From: "Gustavo J. A. M. Carneiro" Date: Fri, 4 Jul 2008 12:35:13 +0100 Subject: [PATCH 116/495] For csma, set a sensible netdevice name, if none has been set. --- src/devices/csma/csma-net-device.cc | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/src/devices/csma/csma-net-device.cc b/src/devices/csma/csma-net-device.cc index 05dde61b3..532f2b695 100644 --- a/src/devices/csma/csma-net-device.cc +++ b/src/devices/csma/csma-net-device.cc @@ -785,6 +785,25 @@ CsmaNetDevice::GetNode (void) const CsmaNetDevice::SetNode (Ptr node) { m_node = node; + int count = -1; + if (m_name.size () == 0) + { + for (uint32_t i = 0; i < node->GetNDevices (); i++) + { + Ptr dev = node->GetDevice (i); + if (dynamic_cast (PeekPointer (dev))) + { + count++; + if (dev == this) + { + break; + } + } + } + std::ostringstream s; + s << "eth" << count; + m_name = s.str (); + } } bool From 629a5b02dae7f6fca5c6fb8ff5f759a11bbd8f07 Mon Sep 17 00:00:00 2001 From: "Gustavo J. A. M. Carneiro" Date: Fri, 4 Jul 2008 15:37:03 +0100 Subject: [PATCH 117/495] Changes in the promiscuous mode API: now the callback receives everything, both 'for me' and 'not for me', with an additional 'forMe' parameter. --- src/node/net-device.h | 16 +++++++++------- src/node/node.cc | 4 ++-- src/node/node.h | 4 ++-- 3 files changed, 13 insertions(+), 11 deletions(-) diff --git a/src/node/net-device.h b/src/node/net-device.h index f0fe4de36..065b1c2c8 100644 --- a/src/node/net-device.h +++ b/src/node/net-device.h @@ -267,19 +267,21 @@ public: * given to the Send method by the user on the sender side. * \param sourceAddress source address * \param destinationAddress destination address + * \param forMe true if the packet is normally picked up also for + * the non-promiscuous callback, false if it is received exclusively + * by the promiscuous callback. * \returns true if the callback could handle the packet successfully, false * otherwise. */ - typedef Callback,Ptr,uint16_t,const Address &, const Address &> PromiscuousReceiveCallback; + typedef Callback,Ptr,uint16_t, + const Address &, const Address &, bool> PromiscuousReceiveCallback; /** * \param cb callback to invoke whenever a packet has been received - * in promiscuous mode and must be forwarded to the higher - * layers, i.e. for all packets whose destination address - * does NOT match the NetDevice address. Note that - * ReceiveCallback and PromiscuousReceiveCallback handle - * mutually exclusive sets of packets, and you need to use - * both callbacks in order to receive ALL packets. + * in promiscuous mode. Note that PromiscuousReceiveCallback + * handles both packets for the device and packets not for + * it. In that sense, it receives a superset of packets + * received by the normal ReceivedCallback. */ virtual void SetPromiscuousReceiveCallback (PromiscuousReceiveCallback cb) = 0; diff --git a/src/node/node.cc b/src/node/node.cc index d7e032174..3646c8edb 100644 --- a/src/node/node.cc +++ b/src/node/node.cc @@ -238,7 +238,7 @@ Node::ReceiveFromDevice (Ptr device, Ptr packet, bool Node::PromiscuousReceiveFromDevice (Ptr device, Ptr packet, - uint16_t protocol, const Address &from, const Address &to) + uint16_t protocol, const Address &from, const Address &to, bool forMe) { bool found = false; // if there are (potentially) multiple handlers, we need to copy the @@ -255,7 +255,7 @@ Node::PromiscuousReceiveFromDevice (Ptr device, Ptr packet, if (i->protocol == 0 || i->protocol == protocol) { - i->handler (device, (copyNeeded ? packet->Copy () : packet), protocol, from, to); + i->handler (device, (copyNeeded ? packet->Copy () : packet), protocol, from, to, forMe); found = true; } } diff --git a/src/node/node.h b/src/node/node.h index 3588ffc19..c5104a7b1 100644 --- a/src/node/node.h +++ b/src/node/node.h @@ -158,7 +158,7 @@ public: * A promiscuous protocol handler */ typedef Callback, Ptr,uint16_t, - const Address &, const Address &> PromiscuousProtocolHandler; + const Address &, const Address &, bool> PromiscuousProtocolHandler; /** * \param handler the handler to register * \param protocolType the type of protocol this handler is @@ -202,7 +202,7 @@ private: bool ReceiveFromDevice (Ptr device, Ptr, uint16_t protocol, const Address &from); bool PromiscuousReceiveFromDevice (Ptr device, Ptr, - uint16_t protocol, const Address &from, const Address &to); + uint16_t protocol, const Address &from, const Address &to, bool forMe); void Construct (void); struct ProtocolHandlerEntry { From 8a0bcd18ba31cb0f6e760416dd2e44b0ca945b41 Mon Sep 17 00:00:00 2001 From: "Gustavo J. A. M. Carneiro" Date: Fri, 4 Jul 2008 15:37:54 +0100 Subject: [PATCH 118/495] Implement the promiscuous receive callback for CsmaNetDevice. --- src/devices/csma/csma-net-device.cc | 24 ++++++++++++++---------- src/devices/csma/csma-net-device.h | 5 +++++ 2 files changed, 19 insertions(+), 10 deletions(-) diff --git a/src/devices/csma/csma-net-device.cc b/src/devices/csma/csma-net-device.cc index 532f2b695..4c8371e36 100644 --- a/src/devices/csma/csma-net-device.cc +++ b/src/devices/csma/csma-net-device.cc @@ -470,6 +470,7 @@ CsmaNetDevice::Receive (Ptr packet) if (m_encapMode == RAW) { m_rxTrace (packet); + m_promiscRxCallback (this, packet->Copy (), 0, GetAddress (), GetBroadcast (), true); m_rxCallback (this, packet, 0, GetBroadcast ()); return; } @@ -522,15 +523,6 @@ CsmaNetDevice::Receive (Ptr packet) Mac48Address broadcast = Mac48Address::ConvertFrom (GetBroadcast ()); Mac48Address destination = Mac48Address::ConvertFrom (GetAddress ()); - if ((header.GetDestination () != broadcast) && - (mcDest != multicast) && - (header.GetDestination () != destination)) - { - NS_LOG_LOGIC ("Dropping pkt "); - m_dropTrace (packet); - return; - } - if (m_receiveErrorModel && m_receiveErrorModel->IsCorrupt (packet) ) { NS_LOG_LOGIC ("Dropping pkt due to error model "); @@ -561,6 +553,18 @@ CsmaNetDevice::Receive (Ptr packet) NS_ASSERT (false); break; } + + if ((header.GetDestination () != broadcast) && + (mcDest != multicast) && + (header.GetDestination () != destination)) + { + NS_LOG_LOGIC ("Not for me: promisc rx, then dropping pkt "); + m_promiscRxCallback (this, packet->Copy (), protocol, header.GetSource (), header.GetDestination (), false); + m_dropTrace (packet); + return; + } + + m_promiscRxCallback (this, packet->Copy (), protocol, header.GetSource (), header.GetDestination (), true); m_rxTrace (originalPacket); m_rxCallback (this, packet, protocol, header.GetSource ()); } @@ -828,7 +832,7 @@ CsmaNetDevice::SetReceiveCallback (NetDevice::ReceiveCallback cb) void CsmaNetDevice::SetPromiscuousReceiveCallback (NetDevice::PromiscuousReceiveCallback cb) { - // TODO + m_promiscRxCallback = cb; } } // namespace ns3 diff --git a/src/devices/csma/csma-net-device.h b/src/devices/csma/csma-net-device.h index f283c9c47..6649c5991 100644 --- a/src/devices/csma/csma-net-device.h +++ b/src/devices/csma/csma-net-device.h @@ -528,6 +528,11 @@ private: */ NetDevice::ReceiveCallback m_rxCallback; + /** + * The callback used to notify higher layers that a packet has been received in promiscuous mode. + */ + NetDevice::PromiscuousReceiveCallback m_promiscRxCallback; + /** * The interface index (really net evice index) that has been assigned to * this network device. From f8a561c16af1615fcaa0d426619ab8668b1289c2 Mon Sep 17 00:00:00 2001 From: "Gustavo J. A. M. Carneiro" Date: Fri, 4 Jul 2008 15:39:24 +0100 Subject: [PATCH 119/495] Start of a BridgeNetDevice; for now does not yet do the 'learning' part, and does not preserve the source address of mac frames. --- src/devices/bridge/bridge-net-device.cc | 357 ++++++++++++++++++++++++ src/devices/bridge/bridge-net-device.h | 90 ++++++ src/devices/bridge/waf | 1 + src/devices/bridge/wscript | 12 + src/wscript | 1 + 5 files changed, 461 insertions(+) create mode 100644 src/devices/bridge/bridge-net-device.cc create mode 100644 src/devices/bridge/bridge-net-device.h create mode 100755 src/devices/bridge/waf create mode 100644 src/devices/bridge/wscript diff --git a/src/devices/bridge/bridge-net-device.cc b/src/devices/bridge/bridge-net-device.cc new file mode 100644 index 000000000..6a9a997a3 --- /dev/null +++ b/src/devices/bridge/bridge-net-device.cc @@ -0,0 +1,357 @@ +/* -*- 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 + * + * Author: Gustavo Carneiro + */ +#include "bridge-net-device.h" +#include "ns3/node.h" +#include "ns3/channel.h" +#include "ns3/packet.h" +#include "ns3/log.h" + +NS_LOG_COMPONENT_DEFINE ("BridgeNetDevice"); + +namespace ns3 { + + +TypeId +BridgeNetDevice::GetTypeId (void) +{ + static TypeId tid = TypeId ("ns3::BridgeNetDevice") + .SetParent () + .AddConstructor () + ; + return tid; +} + + +BridgeNetDevice::BridgeNetDevice () + : m_node (0), + m_mtu (0xffff), + m_name (""), + m_ifIndex (0) +{} + +void +BridgeNetDevice::PromiscReceive (Ptr incomingPort, Ptr packet, uint16_t protocol, + Address const &src, Address const &dst, bool forMe) +{ + NS_LOG_FUNCTION_NOARGS (); + NS_LOG_LOGIC ("UID is " << packet->GetUid ()); + + Mac48Address src48 = Mac48Address::ConvertFrom (src); + Mac48Address dst48 = Mac48Address::ConvertFrom (dst); + +// +// We never forward up packets that we sent. Real devices don't do this since +// their receivers are disabled during send, so we don't. Drop the packet +// silently (no tracing) since it would really never get here in a real device. +// + if (src48 == m_address) + { + NS_LOG_LOGIC ("Ignoring packet sourced by this device"); + return; + } + +// +// An IP host group address is mapped to an Ethernet multicast address +// by placing the low-order 23-bits of the IP address into the low-order +// 23 bits of the Ethernet multicast address 01-00-5E-00-00-00 (hex). +// +// We are going to receive all packets destined to any multicast address, +// which means clearing the low-order 23 bits the header destination +// + Mac48Address mcDest; + uint8_t mcBuf[6]; + + dst48.CopyTo (mcBuf); + mcBuf[3] &= 0x80; + mcBuf[4] = 0; + mcBuf[5] = 0; + mcDest.CopyFrom (mcBuf); + + Mac48Address multicast = Mac48Address::ConvertFrom (GetMulticast ()); + Mac48Address broadcast = Mac48Address::ConvertFrom (GetBroadcast ()); + + // decide whether this node should receive the packet for itself + + NS_LOG_DEBUG ("incomingPort: " << incomingPort->GetName () + << "; my address: " << m_address + << "; broadcast: " << broadcast + << "; dst48: " << dst48); + + if ((dst48 == broadcast) || + (mcDest == multicast) || + (dst48 == m_address)) + { + m_rxCallback (this, packet, protocol, src); + // m_rxTrace (originalPacket); + } + + // decide whether the packet should be forwarded + if ((dst48 == broadcast) || + (mcDest == multicast) || + (dst48 != m_address)) + { + LearningBridgeForward (incomingPort, packet, protocol, src48, dst48); + } +} + +void +BridgeNetDevice::LearningBridgeForward (Ptr incomingPort, Ptr packet, + uint16_t protocol, Mac48Address src, Mac48Address dst) +{ + NS_LOG_DEBUG ("LearningBridgeForward (incomingPort=" << incomingPort->GetName () + << ", packet=" << packet << ", protocol="< >::iterator iter = m_ports.begin (); + iter != m_ports.end (); iter++) + { + Ptr port = *iter; + if (port != incomingPort) + { + // TODO: port->SendFrom (packet, protocol, dst, src); + port->Send (packet->Copy (), dst, protocol); + } + } +} + + +void +BridgeNetDevice::AddBridgePort (Ptr bridgePort) +{ + if (m_address == Mac48Address ()) + { + m_address = Mac48Address::ConvertFrom (bridgePort->GetAddress ()); + } + + m_node->RegisterPromiscuousProtocolHandler (MakeCallback (&BridgeNetDevice::PromiscReceive, this), + 0, bridgePort); + m_ports.push_back (bridgePort); +} + +void +BridgeNetDevice::SetName(const std::string name) +{ + m_name = name; +} + +std::string +BridgeNetDevice::GetName(void) const +{ + return m_name; +} + +void +BridgeNetDevice::SetIfIndex(const uint32_t index) +{ + m_ifIndex = index; +} + +uint32_t +BridgeNetDevice::GetIfIndex(void) const +{ + return m_ifIndex; +} + +Ptr +BridgeNetDevice::GetChannel (void) const +{ + return 0; +} + +Address +BridgeNetDevice::GetAddress (void) const +{ + return m_address; +} + +bool +BridgeNetDevice::SetMtu (const uint16_t mtu) +{ + m_mtu = mtu; + return true; +} + +uint16_t +BridgeNetDevice::GetMtu (void) const +{ + return m_mtu; +} + + +bool +BridgeNetDevice::IsLinkUp (void) const +{ + return true; +} + + +void +BridgeNetDevice::SetLinkChangeCallback (Callback callback) +{} + + +bool +BridgeNetDevice::IsBroadcast (void) const +{ + return true; +} + + +Address +BridgeNetDevice::GetBroadcast (void) const +{ + return Mac48Address ("ff:ff:ff:ff:ff:ff"); +} + +bool +BridgeNetDevice::IsMulticast (void) const +{ + return true; +} + + +Address +BridgeNetDevice::GetMulticast (void) const +{ + return Mac48Address ("01:00:5e:00:00:00"); +} + + +Address +BridgeNetDevice::MakeMulticastAddress (Ipv4Address multicastGroup) const +{ + NS_LOG_FUNCTION (this << multicastGroup); +// +// First, get the generic multicast address. +// + Address hardwareDestination = GetMulticast (); + + NS_LOG_LOGIC ("Device multicast address: " << hardwareDestination); +// +// It's our address, and we know we're playing with an EUI-48 address here +// primarily since we know that by construction, but also since the parameter +// is an Ipv4Address. +// + Mac48Address etherAddr = Mac48Address::ConvertFrom (hardwareDestination); +// +// We now have the multicast address in an abstract 48-bit container. We +// need to pull it out so we can play with it. When we're done, we have the +// high order bits in etherBuffer[0], etc. +// + uint8_t etherBuffer[6]; + etherAddr.CopyTo (etherBuffer); +// +// Now we need to pull the raw bits out of the Ipv4 destination address. +// + uint8_t ipBuffer[4]; + multicastGroup.Serialize (ipBuffer); +// +// RFC 1112 says that an Ipv4 host group address is mapped to an EUI-48 +// multicast address by placing the low-order 23-bits of the IP address into +// the low-order 23 bits of the Ethernet multicast address +// 01-00-5E-00-00-00 (hex). +// + etherBuffer[3] |= ipBuffer[1] & 0x7f; + etherBuffer[4] = ipBuffer[2]; + etherBuffer[5] = ipBuffer[3]; +// +// Now, etherBuffer has the desired ethernet multicast address. We have to +// suck these bits back into the Mac48Address, +// + etherAddr.CopyFrom (etherBuffer); +// +// Implicit conversion (operator Address ()) is defined for Mac48Address, so +// use it by just returning the EUI-48 address which is automagically converted +// to an Address. +// + NS_LOG_LOGIC ("multicast address is " << etherAddr); + + return etherAddr; +} + + +bool +BridgeNetDevice::IsPointToPoint (void) const +{ + return false; +} + + +bool +BridgeNetDevice::Send(Ptr packet, const Address& dest, uint16_t protocolNumber) +{ + Mac48Address to = Mac48Address::ConvertFrom (dest); + + for (std::vector< Ptr >::iterator iter = m_ports.begin (); + iter != m_ports.end (); iter++) + { + Ptr port = *iter; + // TODO: port->SendFrom (packet, protocolNumber, to, m_address); + port->Send (packet->Copy (), to, protocolNumber); + } + + return true; +} + + +Ptr +BridgeNetDevice::GetNode (void) const +{ + return m_node; +} + + +void +BridgeNetDevice::SetNode (Ptr node) +{ + m_node = node; +} + + +bool +BridgeNetDevice::NeedsArp (void) const +{ + return true; +} + + +void +BridgeNetDevice::SetReceiveCallback (NetDevice::ReceiveCallback cb) +{ + m_rxCallback = cb; +} + + +void +BridgeNetDevice::SetPromiscuousReceiveCallback (NetDevice::PromiscuousReceiveCallback cb) +{ + m_promiscRxCallback = cb; +} + + +void +BridgeNetDevice::DoDispose (void) +{ + m_node = 0; + NetDevice::DoDispose (); +} + + + +} // namespace ns3 diff --git a/src/devices/bridge/bridge-net-device.h b/src/devices/bridge/bridge-net-device.h new file mode 100644 index 000000000..ab2e37e29 --- /dev/null +++ b/src/devices/bridge/bridge-net-device.h @@ -0,0 +1,90 @@ +/* -*- 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 + * + * Author: Gustavo Carneiro + */ +#ifndef BRIDGE_NET_DEVICE_H +#define BRIDGE_NET_DEVICE_H + +#include "ns3/net-device.h" +#include "ns3/mac48-address.h" +#include +#include + +namespace ns3 { + +class Node; + +/** + * \ingroup netdevice + * + * \brief bridge net device for bridge things and testing + */ +class BridgeNetDevice : public NetDevice +{ +public: + static TypeId GetTypeId (void); + BridgeNetDevice (); + + void AddBridgePort (Ptr bridgePort); + + // inherited from NetDevice base class. + virtual void SetName(const std::string name); + virtual std::string GetName(void) const; + virtual void SetIfIndex(const uint32_t index); + virtual uint32_t GetIfIndex(void) const; + virtual Ptr GetChannel (void) const; + virtual Address GetAddress (void) const; + virtual bool SetMtu (const uint16_t mtu); + virtual uint16_t GetMtu (void) const; + virtual bool IsLinkUp (void) const; + virtual void SetLinkChangeCallback (Callback callback); + virtual bool IsBroadcast (void) const; + virtual Address GetBroadcast (void) const; + virtual bool IsMulticast (void) const; + virtual Address GetMulticast (void) const; + virtual Address MakeMulticastAddress (Ipv4Address multicastGroup) const; + virtual bool IsPointToPoint (void) const; + virtual bool Send(Ptr packet, const Address& dest, uint16_t protocolNumber); + virtual Ptr GetNode (void) const; + virtual void SetNode (Ptr node); + virtual bool NeedsArp (void) const; + virtual void SetReceiveCallback (NetDevice::ReceiveCallback cb); + virtual void SetPromiscuousReceiveCallback (PromiscuousReceiveCallback cb); + +protected: + virtual void DoDispose (void); + + void PromiscReceive (Ptr device, Ptr packet, uint16_t protocol, + Address const &source, Address const &destination, bool forMe); + void LearningBridgeForward (Ptr incomingPort, Ptr packet, + uint16_t protocol, Mac48Address src, Mac48Address dst); + + +private: + NetDevice::ReceiveCallback m_rxCallback; + NetDevice::PromiscuousReceiveCallback m_promiscRxCallback; + Ptr m_node; + uint16_t m_mtu; + std::string m_name; + uint32_t m_ifIndex; + Mac48Address m_address; + + std::vector< Ptr > m_ports; +}; + +} // namespace ns3 + +#endif /* BRIDGE_NET_DEVICE_H */ diff --git a/src/devices/bridge/waf b/src/devices/bridge/waf new file mode 100755 index 000000000..4283ec141 --- /dev/null +++ b/src/devices/bridge/waf @@ -0,0 +1 @@ +exec "`dirname "$0"`"/../../../waf "$@" diff --git a/src/devices/bridge/wscript b/src/devices/bridge/wscript new file mode 100644 index 000000000..6b0f5134a --- /dev/null +++ b/src/devices/bridge/wscript @@ -0,0 +1,12 @@ +## -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*- + +def build(bld): + obj = bld.create_ns3_module('bridge', ['node']) + obj.source = [ + 'bridge-net-device.cc', + ] + headers = bld.create_obj('ns3header') + headers.module = 'bridge' + headers.source = [ + 'bridge-net-device.h', + ] diff --git a/src/wscript b/src/wscript index 43dddb49b..1ebbc2bf7 100644 --- a/src/wscript +++ b/src/wscript @@ -27,6 +27,7 @@ all_modules = ( 'mobility', 'devices/wifi', 'helper', + 'devices/bridge', ) def set_options(opt): From d00d6e123c0c9c906176a5a3463deaba53103c5c Mon Sep 17 00:00:00 2001 From: "Gustavo J. A. M. Carneiro" Date: Fri, 4 Jul 2008 15:40:29 +0100 Subject: [PATCH 120/495] Start of a BridgeNetDevice example, using csma (basically an Ethernet Switch). --- examples/csma-bridge.cc | 175 ++++++++++++++++++++++++++++++++++++++++ examples/wscript | 4 + 2 files changed, 179 insertions(+) create mode 100644 examples/csma-bridge.cc diff --git a/examples/csma-bridge.cc b/examples/csma-bridge.cc new file mode 100644 index 000000000..69077ac0a --- /dev/null +++ b/examples/csma-bridge.cc @@ -0,0 +1,175 @@ +/* -*- 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 + */ + +// Network topology +// +// n0 n1 +// | | +// ---------- +// | Switch | +// ---------- +// | | +// n2 n3 +// +// +// - CBR/UDP flows from n0 to n1 and from n3 to n0 +// - DropTail queues +// - Tracing of queues and packet receptions to file "csma-bridge.tr" + +#include +#include + +#include "ns3/simulator-module.h" +#include "ns3/node-module.h" +#include "ns3/core-module.h" +#include "ns3/helper-module.h" +#include "ns3/bridge-module.h" + +using namespace ns3; + +NS_LOG_COMPONENT_DEFINE ("CsmaBridgeExample"); + +int +main (int argc, char *argv[]) +{ + // + // Users may find it convenient to turn on explicit debugging + // for selected modules; the below lines suggest how to do this + // +#if 0 + LogComponentEnable ("CsmaBridgeExample", LOG_LEVEL_INFO); +#endif + + // + // Make the random number generators generate reproducible results. + // + RandomVariable::UseGlobalSeed (1, 1, 2, 3, 5, 8); + + // + // Allow the user to override any of the defaults and the above Bind() at + // run-time, via command-line arguments + // + CommandLine cmd; + cmd.Parse (argc, argv); + + // + // Explicitly create the nodes required by the topology (shown above). + // + NS_LOG_INFO ("Create nodes."); + NodeContainer terminals; + terminals.Create (4); + + NodeContainer csmaSwitch; + csmaSwitch.Create (1); + + NS_LOG_INFO ("Build Topology"); + CsmaHelper csma; + csma.SetChannelParameter ("DataRate", DataRateValue (5000000)); + csma.SetChannelParameter ("Delay", TimeValue (MilliSeconds (2))); + + // Create the csma links, from each terminal to the switch + + NetDeviceContainer terminalDevices; + NetDeviceContainer switchDevices; + + for (int i = 0; i < 4; i++) + { + NetDeviceContainer link = csma.Install (NodeContainer (terminals.Get (i), csmaSwitch)); + terminalDevices.Add (link.Get (0)); + switchDevices.Add (link.Get (1)); + } + + // Create the bridge netdevice, which will do the packet switching + Ptr switchNode = csmaSwitch.Get (0); + Ptr bridgeDevice = CreateObject (); + switchNode->AddDevice (bridgeDevice); + + for (NetDeviceContainer::Iterator portIter = switchDevices.Begin (); + portIter != switchDevices.End (); portIter++) + { + bridgeDevice->AddBridgePort (*portIter); + } + + // Add internet stack to the terminals + InternetStackHelper internet; + internet.Install (terminals); + + // We've got the "hardware" in place. Now we need to add IP addresses. + // + NS_LOG_INFO ("Assign IP Addresses."); + Ipv4AddressHelper ipv4; + ipv4.SetBase ("10.1.1.0", "255.255.255.0"); + ipv4.Assign (terminalDevices); + + // + // Create an OnOff application to send UDP datagrams from node zero to node 1. + // + NS_LOG_INFO ("Create Applications."); + uint16_t port = 9; // Discard port (RFC 863) + + OnOffHelper onoff ("ns3::UdpSocketFactory", + Address (InetSocketAddress (Ipv4Address ("10.1.1.2"), port))); + onoff.SetAttribute ("OnTime", RandomVariableValue (ConstantVariable (1))); + onoff.SetAttribute ("OffTime", RandomVariableValue (ConstantVariable (0))); + + ApplicationContainer app = onoff.Install (terminals.Get (0)); + // Start the application + app.Start (Seconds (1.0)); + app.Stop (Seconds (10.0)); + + // Create an optional packet sink to receive these packets + PacketSinkHelper sink ("ns3::UdpSocketFactory", + Address (InetSocketAddress (Ipv4Address::GetAny (), port))); + sink.Install (terminals.Get (1)); + + // + // Create a similar flow from n3 to n0, starting at time 1.1 seconds + // + onoff.SetAttribute ("Remote", + AddressValue (InetSocketAddress (Ipv4Address ("10.1.1.1"), port))); + ApplicationContainer app2 = onoff.Install (terminals.Get (3)); + + sink.Install (terminals.Get (0)); + + app2.Start (Seconds (1.1)); + app2.Stop (Seconds (10.0)); + + // + // Configure tracing of all enqueue, dequeue, and NetDevice receive events. + // Trace output will be sent to the file "csma-bridge.tr" + // + NS_LOG_INFO ("Configure Tracing."); + std::ofstream ascii; + ascii.open ("csma-bridge.tr"); + CsmaHelper::EnableAsciiAll (ascii); + + // + // Also configure some tcpdump traces; each interface will be traced. + // The output files will be named: + // csma-bridge.pcap-- + // and can be read by the "tcpdump -r" command (use "-tt" option to + // display timestamps correctly) + // + CsmaHelper::EnablePcapAll ("csma-bridge"); + + // + // Now, do the actual simulation. + // + NS_LOG_INFO ("Run Simulation."); + Simulator::Run (); + Simulator::Destroy (); + NS_LOG_INFO ("Done."); +} diff --git a/examples/wscript b/examples/wscript index 7682fecad..391c9e14a 100644 --- a/examples/wscript +++ b/examples/wscript @@ -24,6 +24,10 @@ def build(bld): ['csma', 'internet-stack']) obj.source = 'csma-one-subnet.cc' + obj = bld.create_ns3_program('csma-bridge', + ['bridge', 'csma', 'internet-stack']) + obj.source = 'csma-bridge.cc' + obj = bld.create_ns3_program('udp-echo', ['csma', 'internet-stack']) obj.source = 'udp-echo.cc' From f3d8a5eb6dfef72e6b1b158206ce1c641be83fdf Mon Sep 17 00:00:00 2001 From: "Gustavo J. A. M. Carneiro" Date: Fri, 4 Jul 2008 17:58:31 +0100 Subject: [PATCH 121/495] Don't allow csma devices to receive packets sent by themselves. --- src/devices/csma/csma-channel.cc | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/devices/csma/csma-channel.cc b/src/devices/csma/csma-channel.cc index 9809daa4e..30100b3c8 100644 --- a/src/devices/csma/csma-channel.cc +++ b/src/devices/csma/csma-channel.cc @@ -232,12 +232,14 @@ CsmaChannel::PropagationCompleteEvent() NS_LOG_LOGIC ("Receive"); std::vector::iterator it; + uint32_t devId = 0; for (it = m_deviceList.begin (); it < m_deviceList.end(); it++) { - if (it->IsActive ()) + if (it->IsActive () && m_currentSrc != devId) { it->devicePtr->Receive (m_currentPkt->Copy ()); } + devId++; } m_state = IDLE; } From df677111d48588dfa242723865b7220a4cb0beef Mon Sep 17 00:00:00 2001 From: "Gustavo J. A. M. Carneiro" Date: Fri, 4 Jul 2008 18:03:26 +0100 Subject: [PATCH 122/495] Add a NetDevice::SendFrom API, for sending packets with a custom source MAC address (a.k.a. MAC spoofing). Only implemented for CsmaNetDevice for now. --- src/devices/csma/csma-net-device.cc | 34 +++++++++---------- src/devices/csma/csma-net-device.h | 8 ++++- .../point-to-point-net-device.cc | 9 +++++ .../point-to-point-net-device.h | 4 +-- src/devices/wifi/wifi-net-device.cc | 6 ++++ src/devices/wifi/wifi-net-device.h | 1 + src/node/net-device.h | 14 ++++++++ src/node/simple-net-device.cc | 9 +++++ src/node/simple-net-device.h | 1 + 9 files changed, 65 insertions(+), 21 deletions(-) diff --git a/src/devices/csma/csma-net-device.cc b/src/devices/csma/csma-net-device.cc index 4c8371e36..5cf20ac52 100644 --- a/src/devices/csma/csma-net-device.cc +++ b/src/devices/csma/csma-net-device.cc @@ -173,6 +173,7 @@ CsmaNetDevice::SetBackoffParams ( void CsmaNetDevice::AddHeader ( Ptr p, + Mac48Address source, Mac48Address dest, uint16_t protocolNumber) { @@ -183,7 +184,6 @@ CsmaNetDevice::AddHeader ( return; } - Mac48Address source = Mac48Address::ConvertFrom (GetAddress ()); EthernetHeader header (false); header.SetSource (source); header.SetDestination (dest); @@ -491,17 +491,6 @@ CsmaNetDevice::Receive (Ptr packet) NS_LOG_LOGIC ("Pkt source is " << header.GetSource ()); NS_LOG_LOGIC ("Pkt destination is " << header.GetDestination ()); -// -// We never forward up packets that we sent. Real devices don't do this since -// their receivers are disabled during send, so we don't. Drop the packet -// silently (no tracing) since it would really never get here in a real device. -// - if (header.GetSource () == GetAddress ()) - { - NS_LOG_LOGIC ("Ignoring packet sourced by this device"); - return; - } - // // An IP host group address is mapped to an Ethernet multicast address // by placing the low-order 23-bits of the IP address into the low-order @@ -730,11 +719,19 @@ CsmaNetDevice::IsPointToPoint (void) const return false; } - bool -CsmaNetDevice::Send( - Ptr packet, - const Address& dest, - uint16_t protocolNumber) +bool +CsmaNetDevice::Send (Ptr packet, + const Address& dest, + uint16_t protocolNumber) +{ + return SendFrom (packet, m_address, dest, protocolNumber); +} + +bool +CsmaNetDevice::SendFrom (Ptr packet, + const Address& src, + const Address& dest, + uint16_t protocolNumber) { NS_LOG_FUNCTION_NOARGS (); NS_LOG_LOGIC ("p=" << packet); @@ -751,7 +748,8 @@ CsmaNetDevice::Send( } Mac48Address destination = Mac48Address::ConvertFrom (dest); - AddHeader (packet, destination, protocolNumber); + Mac48Address source = Mac48Address::ConvertFrom (src); + AddHeader (packet, source, destination, protocolNumber); // // Place the packet to be sent on the send queue diff --git a/src/devices/csma/csma-net-device.h b/src/devices/csma/csma-net-device.h index 6649c5991..bc7a205b3 100644 --- a/src/devices/csma/csma-net-device.h +++ b/src/devices/csma/csma-net-device.h @@ -250,6 +250,12 @@ public: virtual bool Send (Ptr packet, const Address& dest, uint16_t protocolNumber); + /** + * Start sending a packet down the channel, with MAC spoofing + */ + virtual bool SendFrom (Ptr packet, const Address& source, const Address& dest, + uint16_t protocolNumber); + /** * Get the node to which this device is attached. * @@ -307,7 +313,7 @@ protected: * \param protocolNumber In some protocols, identifies the type of * payload contained in this packet. */ - void AddHeader (Ptr p, Mac48Address dest, uint16_t protocolNumber); + void AddHeader (Ptr p, Mac48Address source, Mac48Address dest, uint16_t protocolNumber); /** * Removes, from a packet of data, all headers and trailers that diff --git a/src/devices/point-to-point/point-to-point-net-device.cc b/src/devices/point-to-point/point-to-point-net-device.cc index d7100177d..bdf424f3d 100644 --- a/src/devices/point-to-point/point-to-point-net-device.cc +++ b/src/devices/point-to-point/point-to-point-net-device.cc @@ -434,6 +434,15 @@ PointToPointNetDevice::Send( } } +bool +PointToPointNetDevice::SendFrom (Ptr packet, + const Address &source, + const Address &dest, + uint16_t protocolNumber) +{ + return Send (packet, dest, protocolNumber); +} + Ptr PointToPointNetDevice::GetNode (void) const { diff --git a/src/devices/point-to-point/point-to-point-net-device.h b/src/devices/point-to-point/point-to-point-net-device.h index 2cdadd122..604e7a625 100644 --- a/src/devices/point-to-point/point-to-point-net-device.h +++ b/src/devices/point-to-point/point-to-point-net-device.h @@ -167,8 +167,8 @@ public: virtual bool IsPointToPoint (void) const; - virtual bool Send(Ptr packet, const Address &dest, - uint16_t protocolNumber); + virtual bool Send(Ptr packet, const Address &dest, uint16_t protocolNumber); + virtual bool SendFrom(Ptr packet, const Address& source, const Address& dest, uint16_t protocolNumber); virtual Ptr GetNode (void) const; virtual void SetNode (Ptr node); diff --git a/src/devices/wifi/wifi-net-device.cc b/src/devices/wifi/wifi-net-device.cc index 44eb5acac..fd9c0fb09 100644 --- a/src/devices/wifi/wifi-net-device.cc +++ b/src/devices/wifi/wifi-net-device.cc @@ -283,6 +283,12 @@ WifiNetDevice::Send(Ptr packet, const Address& dest, uint16_t protocolNu m_mac->Enqueue (packet, realTo); return true; } +bool +WifiNetDevice::SendFrom (Ptr packet, const Address& source, const Address& dest, uint16_t protocolNumber) +{ + NS_FATAL_ERROR ("WifiNetDevice::SendFrom not implemented."); + return false; +} Ptr WifiNetDevice::GetNode (void) const { diff --git a/src/devices/wifi/wifi-net-device.h b/src/devices/wifi/wifi-net-device.h index b66cedc11..903538df0 100644 --- a/src/devices/wifi/wifi-net-device.h +++ b/src/devices/wifi/wifi-net-device.h @@ -96,6 +96,7 @@ public: virtual Address MakeMulticastAddress (Ipv4Address multicastGroup) const; virtual bool IsPointToPoint (void) const; virtual bool Send(Ptr packet, const Address& dest, uint16_t protocolNumber); + virtual bool SendFrom (Ptr packet, const Address& src, const Address& dest, uint16_t protocolNumber); virtual Ptr GetNode (void) const; virtual void SetNode (Ptr node); virtual bool NeedsArp (void) const; diff --git a/src/node/net-device.h b/src/node/net-device.h index 065b1c2c8..66b91de45 100644 --- a/src/node/net-device.h +++ b/src/node/net-device.h @@ -215,6 +215,20 @@ public: * \return whether the Send operation succeeded */ virtual bool Send(Ptr packet, const Address& dest, uint16_t protocolNumber) = 0; + /** + * \param packet packet sent from above down to Network Device + * \param source source mac address (so called "MAC spoofing") + * \param dest mac address of the destination (already resolved) + * \param protocolNumber identifies the type of payload contained in + * this packet. Used to call the right L3Protocol when the packet + * is received. + * + * Called from higher layer to send packet into Network Device + * with the specified source and destination Addresses. + * + * \return whether the Send operation succeeded + */ + virtual bool SendFrom(Ptr packet, const Address& source, const Address& dest, uint16_t protocolNumber) = 0; /** * \returns the node base class which contains this network * interface. diff --git a/src/node/simple-net-device.cc b/src/node/simple-net-device.cc index 5b30922d3..b3fbf26f5 100644 --- a/src/node/simple-net-device.cc +++ b/src/node/simple-net-device.cc @@ -151,6 +151,15 @@ SimpleNetDevice::Send(Ptr packet, const Address& dest, uint16_t protocol m_channel->Send (packet, protocolNumber, to, m_address, this); return true; } +bool +SimpleNetDevice::SendFrom(Ptr packet, const Address& source, const Address& dest, uint16_t protocolNumber) +{ + Mac48Address to = Mac48Address::ConvertFrom (dest); + Mac48Address from = Mac48Address::ConvertFrom (source); + m_channel->Send (packet, protocolNumber, to, from, this); + return true; +} + Ptr SimpleNetDevice::GetNode (void) const { diff --git a/src/node/simple-net-device.h b/src/node/simple-net-device.h index fb98e53d7..455717871 100644 --- a/src/node/simple-net-device.h +++ b/src/node/simple-net-device.h @@ -63,6 +63,7 @@ public: virtual Address MakeMulticastAddress (Ipv4Address multicastGroup) const; virtual bool IsPointToPoint (void) const; virtual bool Send(Ptr packet, const Address& dest, uint16_t protocolNumber); + virtual bool SendFrom(Ptr packet, const Address& source, const Address& dest, uint16_t protocolNumber); virtual Ptr GetNode (void) const; virtual void SetNode (Ptr node); virtual bool NeedsArp (void) const; From a97acf9ac0a22993fdc6a295d5a87a937b2b4a2f Mon Sep 17 00:00:00 2001 From: "Gustavo J. A. M. Carneiro" Date: Fri, 4 Jul 2008 18:04:13 +0100 Subject: [PATCH 123/495] Use NetDevice::SendFrom where appropriate, in order to preserve source address of bridged mac frames. --- src/devices/bridge/bridge-net-device.cc | 29 ++++++++++++++++++------- src/devices/bridge/bridge-net-device.h | 3 ++- 2 files changed, 23 insertions(+), 9 deletions(-) diff --git a/src/devices/bridge/bridge-net-device.cc b/src/devices/bridge/bridge-net-device.cc index 6a9a997a3..b472c7bb4 100644 --- a/src/devices/bridge/bridge-net-device.cc +++ b/src/devices/bridge/bridge-net-device.cc @@ -49,7 +49,7 @@ BridgeNetDevice::PromiscReceive (Ptr incomingPort, Ptr packet Address const &src, Address const &dst, bool forMe) { NS_LOG_FUNCTION_NOARGS (); - NS_LOG_LOGIC ("UID is " << packet->GetUid ()); + NS_LOG_DEBUG ("UID is " << packet->GetUid ()); Mac48Address src48 = Mac48Address::ConvertFrom (src); Mac48Address dst48 = Mac48Address::ConvertFrom (dst); @@ -124,8 +124,10 @@ BridgeNetDevice::LearningBridgeForward (Ptr incomingPort, Ptr Ptr port = *iter; if (port != incomingPort) { - // TODO: port->SendFrom (packet, protocol, dst, src); - port->Send (packet->Copy (), dst, protocol); + NS_LOG_LOGIC ("LearningBridgeForward (" << src << " => " << dst << "): " << incomingPort->GetName () + << " --> " << port->GetName () + << " (UID " << packet->GetUid () << ")."); + port->SendFrom (packet->Copy (), src, dst, protocol); } } } @@ -134,6 +136,7 @@ BridgeNetDevice::LearningBridgeForward (Ptr incomingPort, Ptr void BridgeNetDevice::AddBridgePort (Ptr bridgePort) { + NS_ASSERT (bridgePort != this); if (m_address == Mac48Address ()) { m_address = Mac48Address::ConvertFrom (bridgePort->GetAddress ()); @@ -294,16 +297,26 @@ BridgeNetDevice::IsPointToPoint (void) const bool -BridgeNetDevice::Send(Ptr packet, const Address& dest, uint16_t protocolNumber) +BridgeNetDevice::Send (Ptr packet, const Address& dest, uint16_t protocolNumber) { - Mac48Address to = Mac48Address::ConvertFrom (dest); - for (std::vector< Ptr >::iterator iter = m_ports.begin (); iter != m_ports.end (); iter++) { Ptr port = *iter; - // TODO: port->SendFrom (packet, protocolNumber, to, m_address); - port->Send (packet->Copy (), to, protocolNumber); + port->SendFrom (packet, m_address, dest, protocolNumber); + } + + return true; +} + +bool +BridgeNetDevice::SendFrom (Ptr packet, const Address& src, const Address& dest, uint16_t protocolNumber) +{ + for (std::vector< Ptr >::iterator iter = m_ports.begin (); + iter != m_ports.end (); iter++) + { + Ptr port = *iter; + port->SendFrom (packet, src, dest, protocolNumber); } return true; diff --git a/src/devices/bridge/bridge-net-device.h b/src/devices/bridge/bridge-net-device.h index ab2e37e29..c60ede80c 100644 --- a/src/devices/bridge/bridge-net-device.h +++ b/src/devices/bridge/bridge-net-device.h @@ -57,7 +57,8 @@ public: virtual Address GetMulticast (void) const; virtual Address MakeMulticastAddress (Ipv4Address multicastGroup) const; virtual bool IsPointToPoint (void) const; - virtual bool Send(Ptr packet, const Address& dest, uint16_t protocolNumber); + virtual bool Send (Ptr packet, const Address& dest, uint16_t protocolNumber); + virtual bool SendFrom (Ptr packet, const Address& source, const Address& dest, uint16_t protocolNumber); virtual Ptr GetNode (void) const; virtual void SetNode (Ptr node); virtual bool NeedsArp (void) const; From 1c8622e4f8586660b9b0a81336ce8833433298a1 Mon Sep 17 00:00:00 2001 From: "Gustavo J. A. M. Carneiro" Date: Fri, 4 Jul 2008 18:48:10 +0100 Subject: [PATCH 124/495] Add the 'learning' part of the Learning Bridge, with option to disable it and revert to dummy mode (hub-like). --- src/devices/bridge/bridge-net-device.cc | 93 +++++++++++++++++++++++-- src/devices/bridge/bridge-net-device.h | 29 +++++--- 2 files changed, 107 insertions(+), 15 deletions(-) diff --git a/src/devices/bridge/bridge-net-device.cc b/src/devices/bridge/bridge-net-device.cc index b472c7bb4..03401e561 100644 --- a/src/devices/bridge/bridge-net-device.cc +++ b/src/devices/bridge/bridge-net-device.cc @@ -20,6 +20,8 @@ #include "ns3/channel.h" #include "ns3/packet.h" #include "ns3/log.h" +#include "ns3/boolean.h" +#include "ns3/simulator.h" NS_LOG_COMPONENT_DEFINE ("BridgeNetDevice"); @@ -32,6 +34,16 @@ BridgeNetDevice::GetTypeId (void) static TypeId tid = TypeId ("ns3::BridgeNetDevice") .SetParent () .AddConstructor () + .AddAttribute ("EnableLearning", + "Enable the learning mode of the Learning Bridge", + BooleanValue (true), + MakeBooleanAccessor (&BridgeNetDevice::m_enableLearning), + MakeBooleanChecker ()) + .AddAttribute ("ExpirationTime", + "Time it takes for learned MAC state entry to expire.", + TimeValue (Seconds (30)), + MakeTimeAccessor (&BridgeNetDevice::m_expirationTime), + MakeTimeChecker ()) ; return tid; } @@ -39,9 +51,9 @@ BridgeNetDevice::GetTypeId (void) BridgeNetDevice::BridgeNetDevice () : m_node (0), - m_mtu (0xffff), m_name (""), - m_ifIndex (0) + m_ifIndex (0), + m_mtu (0xffff) {} void @@ -102,21 +114,57 @@ BridgeNetDevice::PromiscReceive (Ptr incomingPort, Ptr packet // decide whether the packet should be forwarded if ((dst48 == broadcast) || - (mcDest == multicast) || - (dst48 != m_address)) + (mcDest == multicast)) { - LearningBridgeForward (incomingPort, packet, protocol, src48, dst48); + ForwardBroadcast (incomingPort, packet, protocol, src48, dst48); + } + else if (dst48 != m_address) + { + ForwardUnicast (incomingPort, packet, protocol, src48, dst48); } } void -BridgeNetDevice::LearningBridgeForward (Ptr incomingPort, Ptr packet, +BridgeNetDevice::ForwardUnicast (Ptr incomingPort, Ptr packet, + uint16_t protocol, Mac48Address src, Mac48Address dst) +{ + NS_LOG_DEBUG ("LearningBridgeForward (incomingPort=" << incomingPort->GetName () + << ", packet=" << packet << ", protocol="< outPort = GetLearnedState (dst); + if (outPort != NULL && outPort != incomingPort) + { + NS_LOG_LOGIC ("Learning bridge state says to use port `" << outPort->GetName () << "'"); + outPort->SendFrom (packet->Copy (), src, dst, protocol); + } + else + { + NS_LOG_LOGIC ("No learned state: send through all ports"); + for (std::vector< Ptr >::iterator iter = m_ports.begin (); + iter != m_ports.end (); iter++) + { + Ptr port = *iter; + if (port != incomingPort) + { + NS_LOG_LOGIC ("LearningBridgeForward (" << src << " => " << dst << "): " << incomingPort->GetName () + << " --> " << port->GetName () + << " (UID " << packet->GetUid () << ")."); + port->SendFrom (packet->Copy (), src, dst, protocol); + } + } + } +} + +void +BridgeNetDevice::ForwardBroadcast (Ptr incomingPort, Ptr packet, uint16_t protocol, Mac48Address src, Mac48Address dst) { NS_LOG_DEBUG ("LearningBridgeForward (incomingPort=" << incomingPort->GetName () << ", packet=" << packet << ", protocol="< >::iterator iter = m_ports.begin (); iter != m_ports.end (); iter++) @@ -132,6 +180,37 @@ BridgeNetDevice::LearningBridgeForward (Ptr incomingPort, Ptr } } +void BridgeNetDevice::Learn (Mac48Address source, Ptr port) +{ + if (m_enableLearning) + { + LearnedState &state = m_learnState[source]; + state.associatedPort = port; + state.expirationTime = Simulator::Now () + m_expirationTime; + } +} + +Ptr BridgeNetDevice::GetLearnedState (Mac48Address source) +{ + if (m_enableLearning) + { + std::map::iterator iter = + m_learnState.find (source); + if (iter != m_learnState.end ()) + { + LearnedState &state = iter->second; + if (state.expirationTime > Simulator::Now ()) + { + return state.associatedPort; + } + else + { + m_learnState.erase (iter); + } + } + } + return NULL; +} void BridgeNetDevice::AddBridgePort (Ptr bridgePort) diff --git a/src/devices/bridge/bridge-net-device.h b/src/devices/bridge/bridge-net-device.h index c60ede80c..d316555e6 100644 --- a/src/devices/bridge/bridge-net-device.h +++ b/src/devices/bridge/bridge-net-device.h @@ -20,8 +20,10 @@ #include "ns3/net-device.h" #include "ns3/mac48-address.h" +#include "ns3/nstime.h" #include #include +#include namespace ns3 { @@ -70,20 +72,31 @@ protected: void PromiscReceive (Ptr device, Ptr packet, uint16_t protocol, Address const &source, Address const &destination, bool forMe); - void LearningBridgeForward (Ptr incomingPort, Ptr packet, - uint16_t protocol, Mac48Address src, Mac48Address dst); - + void ForwardUnicast (Ptr incomingPort, Ptr packet, + uint16_t protocol, Mac48Address src, Mac48Address dst); + void ForwardBroadcast (Ptr incomingPort, Ptr packet, + uint16_t protocol, Mac48Address src, Mac48Address dst); + void Learn (Mac48Address source, Ptr port); + Ptr GetLearnedState (Mac48Address source); private: NetDevice::ReceiveCallback m_rxCallback; NetDevice::PromiscuousReceiveCallback m_promiscRxCallback; - Ptr m_node; - uint16_t m_mtu; - std::string m_name; - uint32_t m_ifIndex; - Mac48Address m_address; + Mac48Address m_address; + Time m_expirationTime; // time it takes for learned MAC state to expire + struct LearnedState + { + Ptr associatedPort; + Time expirationTime; + }; + std::map m_learnState; + Ptr m_node; + std::string m_name; std::vector< Ptr > m_ports; + uint32_t m_ifIndex; + uint16_t m_mtu; + bool m_enableLearning; }; } // namespace ns3 From ab714db3a9b1a823ab5bf2f1f0c3bef7278484fb Mon Sep 17 00:00:00 2001 From: "Gustavo J. A. M. Carneiro" Date: Fri, 4 Jul 2008 19:15:00 +0100 Subject: [PATCH 125/495] Try to preserve API compatibility, after SendFrom / promiscuous mode changes. --- src/devices/csma/csma-net-device.cc | 6 ++++++ src/devices/csma/csma-net-device.h | 1 + src/node/net-device.cc | 21 +++++++++++++++++++++ src/node/net-device.h | 9 +++++++-- src/node/node.cc | 9 ++++++++- 5 files changed, 43 insertions(+), 3 deletions(-) diff --git a/src/devices/csma/csma-net-device.cc b/src/devices/csma/csma-net-device.cc index 5cf20ac52..809bbb3c6 100644 --- a/src/devices/csma/csma-net-device.cc +++ b/src/devices/csma/csma-net-device.cc @@ -833,4 +833,10 @@ CsmaNetDevice::SetPromiscuousReceiveCallback (NetDevice::PromiscuousReceiveCallb m_promiscRxCallback = cb; } +bool +CsmaNetDevice::SupportsPromiscuousReceiveCallback (void) const +{ + return true; +} + } // namespace ns3 diff --git a/src/devices/csma/csma-net-device.h b/src/devices/csma/csma-net-device.h index bc7a205b3..a8733adad 100644 --- a/src/devices/csma/csma-net-device.h +++ b/src/devices/csma/csma-net-device.h @@ -286,6 +286,7 @@ public: */ virtual void SetReceiveCallback (NetDevice::ReceiveCallback cb); virtual void SetPromiscuousReceiveCallback (PromiscuousReceiveCallback cb); + virtual bool SupportsPromiscuousReceiveCallback (void) const; protected: /** diff --git a/src/node/net-device.cc b/src/node/net-device.cc index 410cc3f49..8d9c43209 100644 --- a/src/node/net-device.cc +++ b/src/node/net-device.cc @@ -21,6 +21,7 @@ #include "ns3/object.h" #include "ns3/log.h" #include "net-device.h" +#include "ns3/packet.h" NS_LOG_COMPONENT_DEFINE ("NetDevice"); @@ -38,4 +39,24 @@ TypeId NetDevice::GetTypeId (void) NetDevice::~NetDevice () {} +bool +NetDevice::SupportsPromiscuousReceiveCallback (void) const +{ + return false; +} + +void +NetDevice::SetPromiscuousReceiveCallback (PromiscuousReceiveCallback cb) +{ + NS_FATAL_ERROR ("promiscuous receive callback not supported for this device"); +} + +bool +NetDevice::SendFrom(Ptr packet, const Address& source, const Address& dest, uint16_t protocolNumber) +{ + NS_FATAL_ERROR ("NetDevice " << GetInstanceTypeId ().GetName () << " does not support SendFrom."); + return false; +} + + } // namespace ns3 diff --git a/src/node/net-device.h b/src/node/net-device.h index 66b91de45..c6eb8dfc8 100644 --- a/src/node/net-device.h +++ b/src/node/net-device.h @@ -228,7 +228,7 @@ public: * * \return whether the Send operation succeeded */ - virtual bool SendFrom(Ptr packet, const Address& source, const Address& dest, uint16_t protocolNumber) = 0; + virtual bool SendFrom(Ptr packet, const Address& source, const Address& dest, uint16_t protocolNumber); /** * \returns the node base class which contains this network * interface. @@ -297,7 +297,12 @@ public: * it. In that sense, it receives a superset of packets * received by the normal ReceivedCallback. */ - virtual void SetPromiscuousReceiveCallback (PromiscuousReceiveCallback cb) = 0; + virtual void SetPromiscuousReceiveCallback (PromiscuousReceiveCallback cb); + + /** + * \returns true if device supports promiscuous receive callback + */ + virtual bool SupportsPromiscuousReceiveCallback (void) const; }; diff --git a/src/node/node.cc b/src/node/node.cc index 3646c8edb..9209f8653 100644 --- a/src/node/node.cc +++ b/src/node/node.cc @@ -96,7 +96,10 @@ Node::AddDevice (Ptr device) device->SetNode (this); device->SetIfIndex(index); device->SetReceiveCallback (MakeCallback (&Node::ReceiveFromDevice, this)); - device->SetPromiscuousReceiveCallback (MakeCallback (&Node::PromiscuousReceiveFromDevice, this)); + if (device->SupportsPromiscuousReceiveCallback ()) + { + device->SetPromiscuousReceiveCallback (MakeCallback (&Node::PromiscuousReceiveFromDevice, this)); + } NotifyDeviceAdded (device); return index; } @@ -191,6 +194,10 @@ Node::RegisterPromiscuousProtocolHandler (PromiscuousProtocolHandler handler, entry.handler = handler; entry.protocol = protocolType; entry.device = device; + if (device) + { + NS_ASSERT (device->SupportsPromiscuousReceiveCallback ()); + } m_promiscuousHandlers.push_back (entry); } From 95be482f24060e569d22ebee4c350d18e1fe6599 Mon Sep 17 00:00:00 2001 From: "Gustavo J. A. M. Carneiro" Date: Mon, 7 Jul 2008 10:26:00 +0100 Subject: [PATCH 126/495] Backed out changeset ae9f7d5e2d56 --- src/devices/csma/csma-net-device.cc | 6 ------ src/devices/csma/csma-net-device.h | 1 - src/node/net-device.cc | 21 --------------------- src/node/net-device.h | 9 ++------- src/node/node.cc | 9 +-------- 5 files changed, 3 insertions(+), 43 deletions(-) diff --git a/src/devices/csma/csma-net-device.cc b/src/devices/csma/csma-net-device.cc index 809bbb3c6..5cf20ac52 100644 --- a/src/devices/csma/csma-net-device.cc +++ b/src/devices/csma/csma-net-device.cc @@ -833,10 +833,4 @@ CsmaNetDevice::SetPromiscuousReceiveCallback (NetDevice::PromiscuousReceiveCallb m_promiscRxCallback = cb; } -bool -CsmaNetDevice::SupportsPromiscuousReceiveCallback (void) const -{ - return true; -} - } // namespace ns3 diff --git a/src/devices/csma/csma-net-device.h b/src/devices/csma/csma-net-device.h index a8733adad..bc7a205b3 100644 --- a/src/devices/csma/csma-net-device.h +++ b/src/devices/csma/csma-net-device.h @@ -286,7 +286,6 @@ public: */ virtual void SetReceiveCallback (NetDevice::ReceiveCallback cb); virtual void SetPromiscuousReceiveCallback (PromiscuousReceiveCallback cb); - virtual bool SupportsPromiscuousReceiveCallback (void) const; protected: /** diff --git a/src/node/net-device.cc b/src/node/net-device.cc index 8d9c43209..410cc3f49 100644 --- a/src/node/net-device.cc +++ b/src/node/net-device.cc @@ -21,7 +21,6 @@ #include "ns3/object.h" #include "ns3/log.h" #include "net-device.h" -#include "ns3/packet.h" NS_LOG_COMPONENT_DEFINE ("NetDevice"); @@ -39,24 +38,4 @@ TypeId NetDevice::GetTypeId (void) NetDevice::~NetDevice () {} -bool -NetDevice::SupportsPromiscuousReceiveCallback (void) const -{ - return false; -} - -void -NetDevice::SetPromiscuousReceiveCallback (PromiscuousReceiveCallback cb) -{ - NS_FATAL_ERROR ("promiscuous receive callback not supported for this device"); -} - -bool -NetDevice::SendFrom(Ptr packet, const Address& source, const Address& dest, uint16_t protocolNumber) -{ - NS_FATAL_ERROR ("NetDevice " << GetInstanceTypeId ().GetName () << " does not support SendFrom."); - return false; -} - - } // namespace ns3 diff --git a/src/node/net-device.h b/src/node/net-device.h index c6eb8dfc8..66b91de45 100644 --- a/src/node/net-device.h +++ b/src/node/net-device.h @@ -228,7 +228,7 @@ public: * * \return whether the Send operation succeeded */ - virtual bool SendFrom(Ptr packet, const Address& source, const Address& dest, uint16_t protocolNumber); + virtual bool SendFrom(Ptr packet, const Address& source, const Address& dest, uint16_t protocolNumber) = 0; /** * \returns the node base class which contains this network * interface. @@ -297,12 +297,7 @@ public: * it. In that sense, it receives a superset of packets * received by the normal ReceivedCallback. */ - virtual void SetPromiscuousReceiveCallback (PromiscuousReceiveCallback cb); - - /** - * \returns true if device supports promiscuous receive callback - */ - virtual bool SupportsPromiscuousReceiveCallback (void) const; + virtual void SetPromiscuousReceiveCallback (PromiscuousReceiveCallback cb) = 0; }; diff --git a/src/node/node.cc b/src/node/node.cc index 9209f8653..3646c8edb 100644 --- a/src/node/node.cc +++ b/src/node/node.cc @@ -96,10 +96,7 @@ Node::AddDevice (Ptr device) device->SetNode (this); device->SetIfIndex(index); device->SetReceiveCallback (MakeCallback (&Node::ReceiveFromDevice, this)); - if (device->SupportsPromiscuousReceiveCallback ()) - { - device->SetPromiscuousReceiveCallback (MakeCallback (&Node::PromiscuousReceiveFromDevice, this)); - } + device->SetPromiscuousReceiveCallback (MakeCallback (&Node::PromiscuousReceiveFromDevice, this)); NotifyDeviceAdded (device); return index; } @@ -194,10 +191,6 @@ Node::RegisterPromiscuousProtocolHandler (PromiscuousProtocolHandler handler, entry.handler = handler; entry.protocol = protocolType; entry.device = device; - if (device) - { - NS_ASSERT (device->SupportsPromiscuousReceiveCallback ()); - } m_promiscuousHandlers.push_back (entry); } From bcae4f9ea16b159b2564cdbf7f9640a6489f03a0 Mon Sep 17 00:00:00 2001 From: "Gustavo J. A. M. Carneiro" Date: Mon, 7 Jul 2008 10:37:09 +0100 Subject: [PATCH 127/495] Move the csma packet-from-self receive filtering away from the CsmaChannel into the CsmaNetDevice, with the help of an extra Ptr parameter in Receive(). As discussed in the mailing list. --- src/devices/csma/csma-channel.cc | 4 ++-- src/devices/csma/csma-net-device.cc | 15 +++++++++++++-- src/devices/csma/csma-net-device.h | 3 ++- 3 files changed, 17 insertions(+), 5 deletions(-) diff --git a/src/devices/csma/csma-channel.cc b/src/devices/csma/csma-channel.cc index 30100b3c8..3ba7564e5 100644 --- a/src/devices/csma/csma-channel.cc +++ b/src/devices/csma/csma-channel.cc @@ -235,9 +235,9 @@ CsmaChannel::PropagationCompleteEvent() uint32_t devId = 0; for (it = m_deviceList.begin (); it < m_deviceList.end(); it++) { - if (it->IsActive () && m_currentSrc != devId) + if (it->IsActive ()) { - it->devicePtr->Receive (m_currentPkt->Copy ()); + it->devicePtr->Receive (m_currentPkt->Copy (), m_deviceList[m_currentSrc].devicePtr); } devId++; } diff --git a/src/devices/csma/csma-net-device.cc b/src/devices/csma/csma-net-device.cc index 5cf20ac52..77cf52312 100644 --- a/src/devices/csma/csma-net-device.cc +++ b/src/devices/csma/csma-net-device.cc @@ -452,12 +452,23 @@ CsmaNetDevice::SetReceiveErrorModel (Ptr em) m_receiveErrorModel = em; } - void -CsmaNetDevice::Receive (Ptr packet) +void +CsmaNetDevice::Receive (Ptr packet, Ptr senderDevice) { NS_LOG_FUNCTION_NOARGS (); NS_LOG_LOGIC ("UID is " << packet->GetUid ()); + + // + // We never forward up packets that we sent. Real devices don't do this since + // their receivers are disabled during send, so we don't. Drop the packet + // silently (no tracing) since it would really never get here in a real device. + // + if (senderDevice == this) + { + return; + } + // // Only receive if the send side of net device is enabled // diff --git a/src/devices/csma/csma-net-device.h b/src/devices/csma/csma-net-device.h index bc7a205b3..bcfc70616 100644 --- a/src/devices/csma/csma-net-device.h +++ b/src/devices/csma/csma-net-device.h @@ -158,8 +158,9 @@ public: * * @see CsmaChannel * \param p a reference to the received packet + * \param sender the CsmaNetDevice that transmitted the packet in the first place */ - void Receive (Ptr p); + void Receive (Ptr p, Ptr sender); /** * Is the send side of the network device enabled? From cb491541ac78003fcb58b590c5f77ad1f567b60a Mon Sep 17 00:00:00 2001 From: "Gustavo J. A. M. Carneiro" Date: Mon, 7 Jul 2008 12:18:05 +0100 Subject: [PATCH 128/495] Simplify promiscuous mode API: NetDevices always operate in promiscuous mode, normal receive callbacks receive extra destination address and packet type. --- src/devices/bridge/bridge-net-device.cc | 81 +++++-------------- src/devices/bridge/bridge-net-device.h | 6 +- src/devices/csma/csma-net-device.cc | 41 +++++----- src/devices/csma/csma-net-device.h | 6 -- .../point-to-point-net-device.cc | 8 +- .../point-to-point-net-device.h | 1 - src/devices/wifi/wifi-net-device.cc | 10 +-- src/devices/wifi/wifi-net-device.h | 3 +- src/internet-stack/arp-l3-protocol.cc | 9 ++- src/internet-stack/arp-l3-protocol.h | 3 +- src/internet-stack/ipv4-l3-protocol.cc | 8 +- src/internet-stack/ipv4-l3-protocol.h | 4 +- src/internet-stack/ipv4-loopback-interface.cc | 5 +- src/node/net-device.h | 41 +++------- src/node/node.cc | 61 +------------- src/node/node.h | 19 ++--- src/node/packet-socket.cc | 8 +- src/node/packet-socket.h | 4 +- src/node/simple-net-device.cc | 18 +++-- src/node/simple-net-device.h | 1 - 20 files changed, 115 insertions(+), 222 deletions(-) diff --git a/src/devices/bridge/bridge-net-device.cc b/src/devices/bridge/bridge-net-device.cc index 03401e561..88709fd68 100644 --- a/src/devices/bridge/bridge-net-device.cc +++ b/src/devices/bridge/bridge-net-device.cc @@ -57,8 +57,8 @@ BridgeNetDevice::BridgeNetDevice () {} void -BridgeNetDevice::PromiscReceive (Ptr incomingPort, Ptr packet, uint16_t protocol, - Address const &src, Address const &dst, bool forMe) +BridgeNetDevice::ReceiveFromDevice (Ptr incomingPort, Ptr packet, uint16_t protocol, + Address const &src, Address const &dst, PacketType packetType) { NS_LOG_FUNCTION_NOARGS (); NS_LOG_DEBUG ("UID is " << packet->GetUid ()); @@ -66,61 +66,25 @@ BridgeNetDevice::PromiscReceive (Ptr incomingPort, Ptr packet Mac48Address src48 = Mac48Address::ConvertFrom (src); Mac48Address dst48 = Mac48Address::ConvertFrom (dst); -// -// We never forward up packets that we sent. Real devices don't do this since -// their receivers are disabled during send, so we don't. Drop the packet -// silently (no tracing) since it would really never get here in a real device. -// - if (src48 == m_address) + + switch (packetType) { - NS_LOG_LOGIC ("Ignoring packet sourced by this device"); - return; - } + case PACKET_HOST: + if (dst48 == m_address) + { + m_rxCallback (this, packet, protocol, src, dst, packetType); + } + break; -// -// An IP host group address is mapped to an Ethernet multicast address -// by placing the low-order 23-bits of the IP address into the low-order -// 23 bits of the Ethernet multicast address 01-00-5E-00-00-00 (hex). -// -// We are going to receive all packets destined to any multicast address, -// which means clearing the low-order 23 bits the header destination -// - Mac48Address mcDest; - uint8_t mcBuf[6]; - - dst48.CopyTo (mcBuf); - mcBuf[3] &= 0x80; - mcBuf[4] = 0; - mcBuf[5] = 0; - mcDest.CopyFrom (mcBuf); - - Mac48Address multicast = Mac48Address::ConvertFrom (GetMulticast ()); - Mac48Address broadcast = Mac48Address::ConvertFrom (GetBroadcast ()); - - // decide whether this node should receive the packet for itself - - NS_LOG_DEBUG ("incomingPort: " << incomingPort->GetName () - << "; my address: " << m_address - << "; broadcast: " << broadcast - << "; dst48: " << dst48); - - if ((dst48 == broadcast) || - (mcDest == multicast) || - (dst48 == m_address)) - { - m_rxCallback (this, packet, protocol, src); - // m_rxTrace (originalPacket); - } - - // decide whether the packet should be forwarded - if ((dst48 == broadcast) || - (mcDest == multicast)) - { + case PACKET_BROADCAST: + case PACKET_MULTICAST: + m_rxCallback (this, packet, protocol, src, dst, packetType); ForwardBroadcast (incomingPort, packet, protocol, src48, dst48); - } - else if (dst48 != m_address) - { + break; + + case PACKET_OTHERHOST: ForwardUnicast (incomingPort, packet, protocol, src48, dst48); + break; } } @@ -221,8 +185,8 @@ BridgeNetDevice::AddBridgePort (Ptr bridgePort) m_address = Mac48Address::ConvertFrom (bridgePort->GetAddress ()); } - m_node->RegisterPromiscuousProtocolHandler (MakeCallback (&BridgeNetDevice::PromiscReceive, this), - 0, bridgePort); + m_node->RegisterProtocolHandler (MakeCallback (&BridgeNetDevice::ReceiveFromDevice, this), + 0, bridgePort); m_ports.push_back (bridgePort); } @@ -430,13 +394,6 @@ BridgeNetDevice::SetReceiveCallback (NetDevice::ReceiveCallback cb) } -void -BridgeNetDevice::SetPromiscuousReceiveCallback (NetDevice::PromiscuousReceiveCallback cb) -{ - m_promiscRxCallback = cb; -} - - void BridgeNetDevice::DoDispose (void) { diff --git a/src/devices/bridge/bridge-net-device.h b/src/devices/bridge/bridge-net-device.h index d316555e6..025624586 100644 --- a/src/devices/bridge/bridge-net-device.h +++ b/src/devices/bridge/bridge-net-device.h @@ -65,13 +65,12 @@ public: virtual void SetNode (Ptr node); virtual bool NeedsArp (void) const; virtual void SetReceiveCallback (NetDevice::ReceiveCallback cb); - virtual void SetPromiscuousReceiveCallback (PromiscuousReceiveCallback cb); protected: virtual void DoDispose (void); - void PromiscReceive (Ptr device, Ptr packet, uint16_t protocol, - Address const &source, Address const &destination, bool forMe); + void ReceiveFromDevice (Ptr device, Ptr packet, uint16_t protocol, + Address const &source, Address const &destination, PacketType packetType); void ForwardUnicast (Ptr incomingPort, Ptr packet, uint16_t protocol, Mac48Address src, Mac48Address dst); void ForwardBroadcast (Ptr incomingPort, Ptr packet, @@ -81,7 +80,6 @@ protected: private: NetDevice::ReceiveCallback m_rxCallback; - NetDevice::PromiscuousReceiveCallback m_promiscRxCallback; Mac48Address m_address; Time m_expirationTime; // time it takes for learned MAC state to expire diff --git a/src/devices/csma/csma-net-device.cc b/src/devices/csma/csma-net-device.cc index 77cf52312..b1e8fd317 100644 --- a/src/devices/csma/csma-net-device.cc +++ b/src/devices/csma/csma-net-device.cc @@ -481,8 +481,7 @@ CsmaNetDevice::Receive (Ptr packet, Ptr senderDevice) if (m_encapMode == RAW) { m_rxTrace (packet); - m_promiscRxCallback (this, packet->Copy (), 0, GetAddress (), GetBroadcast (), true); - m_rxCallback (this, packet, 0, GetBroadcast ()); + m_rxCallback (this, packet, 0, GetBroadcast (), GetAddress (), PACKET_HOST); return; } @@ -554,19 +553,29 @@ CsmaNetDevice::Receive (Ptr packet, Ptr senderDevice) break; } - if ((header.GetDestination () != broadcast) && - (mcDest != multicast) && - (header.GetDestination () != destination)) + PacketType packetType; + + if (header.GetDestination () == broadcast) { - NS_LOG_LOGIC ("Not for me: promisc rx, then dropping pkt "); - m_promiscRxCallback (this, packet->Copy (), protocol, header.GetSource (), header.GetDestination (), false); - m_dropTrace (packet); - return; + packetType = PACKET_BROADCAST; + m_rxTrace (originalPacket); } - - m_promiscRxCallback (this, packet->Copy (), protocol, header.GetSource (), header.GetDestination (), true); - m_rxTrace (originalPacket); - m_rxCallback (this, packet, protocol, header.GetSource ()); + else if (mcDest == multicast) + { + packetType = PACKET_MULTICAST; + m_rxTrace (originalPacket); + } + else if (header.GetDestination () == destination) + { + packetType = PACKET_HOST; + m_rxTrace (originalPacket); + } + else + { + packetType = PACKET_OTHERHOST; + } + + m_rxCallback (this, packet, protocol, header.GetSource (), header.GetDestination (), packetType); } } @@ -838,10 +847,4 @@ CsmaNetDevice::SetReceiveCallback (NetDevice::ReceiveCallback cb) m_rxCallback = cb; } -void -CsmaNetDevice::SetPromiscuousReceiveCallback (NetDevice::PromiscuousReceiveCallback cb) -{ - m_promiscRxCallback = cb; -} - } // namespace ns3 diff --git a/src/devices/csma/csma-net-device.h b/src/devices/csma/csma-net-device.h index bcfc70616..91e66517c 100644 --- a/src/devices/csma/csma-net-device.h +++ b/src/devices/csma/csma-net-device.h @@ -286,7 +286,6 @@ public: * \param cb The callback. */ virtual void SetReceiveCallback (NetDevice::ReceiveCallback cb); - virtual void SetPromiscuousReceiveCallback (PromiscuousReceiveCallback cb); protected: /** @@ -535,11 +534,6 @@ private: */ NetDevice::ReceiveCallback m_rxCallback; - /** - * The callback used to notify higher layers that a packet has been received in promiscuous mode. - */ - NetDevice::PromiscuousReceiveCallback m_promiscRxCallback; - /** * The interface index (really net evice index) that has been assigned to * this network device. diff --git a/src/devices/point-to-point/point-to-point-net-device.cc b/src/devices/point-to-point/point-to-point-net-device.cc index bdf424f3d..0ee8376de 100644 --- a/src/devices/point-to-point/point-to-point-net-device.cc +++ b/src/devices/point-to-point/point-to-point-net-device.cc @@ -241,7 +241,7 @@ PointToPointNetDevice::Receive (Ptr packet) // m_rxTrace (packet); ProcessHeader(packet, protocol); - m_rxCallback (this, packet, protocol, GetBroadcast ()); + m_rxCallback (this, packet, protocol, GetBroadcast (), m_address, PACKET_HOST); } } @@ -467,10 +467,4 @@ PointToPointNetDevice::SetReceiveCallback (NetDevice::ReceiveCallback cb) m_rxCallback = cb; } -void -PointToPointNetDevice::SetPromiscuousReceiveCallback (NetDevice::PromiscuousReceiveCallback cb) -{ - // TODO -} - } // namespace ns3 diff --git a/src/devices/point-to-point/point-to-point-net-device.h b/src/devices/point-to-point/point-to-point-net-device.h index 604e7a625..352050ec4 100644 --- a/src/devices/point-to-point/point-to-point-net-device.h +++ b/src/devices/point-to-point/point-to-point-net-device.h @@ -176,7 +176,6 @@ public: virtual bool NeedsArp (void) const; virtual void SetReceiveCallback (NetDevice::ReceiveCallback cb); - virtual void SetPromiscuousReceiveCallback (PromiscuousReceiveCallback cb); private: diff --git a/src/devices/wifi/wifi-net-device.cc b/src/devices/wifi/wifi-net-device.cc index fd9c0fb09..79672729e 100644 --- a/src/devices/wifi/wifi-net-device.cc +++ b/src/devices/wifi/wifi-net-device.cc @@ -310,19 +310,15 @@ WifiNetDevice::SetReceiveCallback (NetDevice::ReceiveCallback cb) m_forwardUp = cb; } -void -WifiNetDevice::SetPromiscuousReceiveCallback (NetDevice::PromiscuousReceiveCallback cb) -{ - // TODO -} - void WifiNetDevice::ForwardUp (Ptr packet, const Mac48Address &from) { m_rxLogger (packet, from); LlcSnapHeader llc; packet->RemoveHeader (llc); - m_forwardUp (this, packet, llc.GetType (), from); + Mac48Address to = from; // FIXME + PacketType packetType = PACKET_HOST; // FIXME + m_forwardUp (this, packet, llc.GetType (), from, to, packetType); } void diff --git a/src/devices/wifi/wifi-net-device.h b/src/devices/wifi/wifi-net-device.h index 903538df0..81d9046b3 100644 --- a/src/devices/wifi/wifi-net-device.h +++ b/src/devices/wifi/wifi-net-device.h @@ -101,7 +101,6 @@ public: virtual void SetNode (Ptr node); virtual bool NeedsArp (void) const; virtual void SetReceiveCallback (NetDevice::ReceiveCallback cb); - virtual void SetPromiscuousReceiveCallback (PromiscuousReceiveCallback cb); private: virtual void DoDispose (void); @@ -115,7 +114,7 @@ private: Ptr m_channel; Ptr m_mac; Ptr m_stationManager; - Callback ,Ptr,uint16_t,const Address &> m_forwardUp; + ReceiveCallback m_forwardUp; TracedCallback, Mac48Address> m_rxLogger; TracedCallback, Mac48Address> m_txLogger; uint32_t m_ifIndex; diff --git a/src/internet-stack/arp-l3-protocol.cc b/src/internet-stack/arp-l3-protocol.cc index bd27ce7c6..fa418deac 100644 --- a/src/internet-stack/arp-l3-protocol.cc +++ b/src/internet-stack/arp-l3-protocol.cc @@ -114,9 +114,16 @@ ArpL3Protocol::FindCache (Ptr device) } void -ArpL3Protocol::Receive(Ptr device, Ptr packet, uint16_t protocol, const Address &from) +ArpL3Protocol::Receive(Ptr device, Ptr packet, uint16_t protocol, const Address &from, + const Address &to, NetDevice::PacketType packetType) { NS_LOG_FUNCTION_NOARGS (); + + if (packetType == NetDevice::PACKET_OTHERHOST) + { + return; + } + Ptr cache = FindCache (device); ArpHeader arp; packet->RemoveHeader (arp); diff --git a/src/internet-stack/arp-l3-protocol.h b/src/internet-stack/arp-l3-protocol.h index 6815cdea0..0f131a71b 100644 --- a/src/internet-stack/arp-l3-protocol.h +++ b/src/internet-stack/arp-l3-protocol.h @@ -54,7 +54,8 @@ public: /** * \brief Recieve a packet */ - void Receive(Ptr device, Ptr p, uint16_t protocol, const Address &from); + void Receive(Ptr device, Ptr p, uint16_t protocol, const Address &from, const Address &to, + NetDevice::PacketType packetType); /** * \brief Perform an ARP lookup * \param p diff --git a/src/internet-stack/ipv4-l3-protocol.cc b/src/internet-stack/ipv4-l3-protocol.cc index affe814bb..81b023b6e 100644 --- a/src/internet-stack/ipv4-l3-protocol.cc +++ b/src/internet-stack/ipv4-l3-protocol.cc @@ -449,10 +449,16 @@ Ipv4L3Protocol::FindInterfaceForDevice (Ptr device) } void -Ipv4L3Protocol::Receive( Ptr device, Ptr packet, uint16_t protocol, const Address &from) +Ipv4L3Protocol::Receive( Ptr device, Ptr packet, uint16_t protocol, const Address &from, + const Address &to, NetDevice::PacketType packetType) { NS_LOG_FUNCTION (this << &device << packet << protocol << from); + if (packetType == NetDevice::PACKET_OTHERHOST) + { + return; + } + NS_LOG_LOGIC ("Packet from " << from << " received on node " << m_node->GetId ()); uint32_t index = 0; diff --git a/src/internet-stack/ipv4-l3-protocol.h b/src/internet-stack/ipv4-l3-protocol.h index 7b2879aaf..e009d2f43 100644 --- a/src/internet-stack/ipv4-l3-protocol.h +++ b/src/internet-stack/ipv4-l3-protocol.h @@ -25,6 +25,7 @@ #include #include "ns3/ipv4-address.h" #include "ns3/ptr.h" +#include "ns3/net-device.h" #include "ns3/ipv4.h" #include "ns3/traced-callback.h" #include "ns3/ipv4-header.h" @@ -82,7 +83,8 @@ public: * - implement a per-NetDevice ARP cache * - send back arp replies on the right device */ - void Receive( Ptr device, Ptr p, uint16_t protocol, const Address &from); + void Receive( Ptr device, Ptr p, uint16_t protocol, const Address &from, + const Address &to, NetDevice::PacketType packetType); /** * \param packet packet to send diff --git a/src/internet-stack/ipv4-loopback-interface.cc b/src/internet-stack/ipv4-loopback-interface.cc index 088634f04..a87495009 100644 --- a/src/internet-stack/ipv4-loopback-interface.cc +++ b/src/internet-stack/ipv4-loopback-interface.cc @@ -73,7 +73,10 @@ Ipv4LoopbackInterface::SendTo (Ptr packet, Ipv4Address dest) m_node->GetObject (); ipv4->Receive (0, packet, Ipv4L3Protocol::PROT_NUMBER, - Mac48Address ("ff:ff:ff:ff:ff:ff")); + Mac48Address ("ff:ff:ff:ff:ff:ff"), + Mac48Address ("ff:ff:ff:ff:ff:ff"), + NetDevice::PACKET_HOST // note: linux uses PACKET_LOOPBACK here + ); } }//namespace ns3 diff --git a/src/node/net-device.h b/src/node/net-device.h index 66b91de45..b90dd9ab4 100644 --- a/src/node/net-device.h +++ b/src/node/net-device.h @@ -254,17 +254,28 @@ public: */ virtual bool NeedsArp (void) const = 0; + + /** Packet types */ + enum PacketType + { + PACKET_HOST = 1, /* To us */ + PACKET_BROADCAST, /* To all */ + PACKET_MULTICAST, /* To group */ + PACKET_OTHERHOST, /* To someone else */ + }; + /** * \param device a pointer to the net device which is calling this callback * \param packet the packet received * \param protocol the 16 bit protocol number associated with this packet. * This protocol number is expected to be the same protocol number * given to the Send method by the user on the sender side. - * \param address the address of the sender + * \param sender the address of the sender + * \param receiver the address of the receiver * \returns true if the callback could handle the packet successfully, false * otherwise. */ - typedef Callback,Ptr,uint16_t,const Address &> ReceiveCallback; + typedef Callback,Ptr,uint16_t,const Address &,const Address &, PacketType> ReceiveCallback; /** * \param cb callback to invoke whenever a packet has been received and must @@ -273,32 +284,6 @@ public: */ virtual void SetReceiveCallback (ReceiveCallback cb) = 0; - /** - * \param device a pointer to the net device which is calling this callback - * \param packet the packet received - * \param protocol the 16 bit protocol number associated with this packet. - * This protocol number is expected to be the same protocol number - * given to the Send method by the user on the sender side. - * \param sourceAddress source address - * \param destinationAddress destination address - * \param forMe true if the packet is normally picked up also for - * the non-promiscuous callback, false if it is received exclusively - * by the promiscuous callback. - * \returns true if the callback could handle the packet successfully, false - * otherwise. - */ - typedef Callback,Ptr,uint16_t, - const Address &, const Address &, bool> PromiscuousReceiveCallback; - - /** - * \param cb callback to invoke whenever a packet has been received - * in promiscuous mode. Note that PromiscuousReceiveCallback - * handles both packets for the device and packets not for - * it. In that sense, it receives a superset of packets - * received by the normal ReceivedCallback. - */ - virtual void SetPromiscuousReceiveCallback (PromiscuousReceiveCallback cb) = 0; - }; } // namespace ns3 diff --git a/src/node/node.cc b/src/node/node.cc index 3646c8edb..91a996a74 100644 --- a/src/node/node.cc +++ b/src/node/node.cc @@ -96,7 +96,6 @@ Node::AddDevice (Ptr device) device->SetNode (this); device->SetIfIndex(index); device->SetReceiveCallback (MakeCallback (&Node::ReceiveFromDevice, this)); - device->SetPromiscuousReceiveCallback (MakeCallback (&Node::PromiscuousReceiveFromDevice, this)); NotifyDeviceAdded (device); return index; } @@ -182,35 +181,9 @@ Node::UnregisterProtocolHandler (ProtocolHandler handler) } } -void -Node::RegisterPromiscuousProtocolHandler (PromiscuousProtocolHandler handler, - uint16_t protocolType, - Ptr device) -{ - struct Node::PromiscuousProtocolHandlerEntry entry; - entry.handler = handler; - entry.protocol = protocolType; - entry.device = device; - m_promiscuousHandlers.push_back (entry); -} - -void -Node::UnregisterPromiscuousProtocolHandler (PromiscuousProtocolHandler handler) -{ - for (PromiscuousProtocolHandlerList::iterator i = m_promiscuousHandlers.begin (); - i != m_promiscuousHandlers.end (); i++) - { - if (i->handler.IsEqual (handler)) - { - m_promiscuousHandlers.erase (i); - break; - } - } -} - bool -Node::ReceiveFromDevice (Ptr device, Ptr packet, - uint16_t protocol, const Address &from) +Node::ReceiveFromDevice (Ptr device, Ptr packet, uint16_t protocol, + const Address &from, const Address &to, NetDevice::PacketType packetType) { bool found = false; // if there are (potentially) multiple handlers, we need to copy the @@ -227,35 +200,7 @@ Node::ReceiveFromDevice (Ptr device, Ptr packet, if (i->protocol == 0 || i->protocol == protocol) { - i->handler (device, (copyNeeded ? packet->Copy () : packet), protocol, from); - found = true; - } - } - } - return found; -} - - -bool -Node::PromiscuousReceiveFromDevice (Ptr device, Ptr packet, - uint16_t protocol, const Address &from, const Address &to, bool forMe) -{ - bool found = false; - // if there are (potentially) multiple handlers, we need to copy the - // packet before passing it to each handler, because handlers may - // modify it. - bool copyNeeded = (m_handlers.size () > 1); - - for (PromiscuousProtocolHandlerList::iterator i = m_promiscuousHandlers.begin (); - i != m_promiscuousHandlers.end (); i++) - { - if (i->device == 0 || - (i->device != 0 && i->device == device)) - { - if (i->protocol == 0 || - i->protocol == protocol) - { - i->handler (device, (copyNeeded ? packet->Copy () : packet), protocol, from, to, forMe); + i->handler (device, (copyNeeded ? packet->Copy () : packet), protocol, from, to, packetType); found = true; } } diff --git a/src/node/node.h b/src/node/node.h index c5104a7b1..84f4c31f9 100644 --- a/src/node/node.h +++ b/src/node/node.h @@ -26,10 +26,10 @@ #include "ns3/object.h" #include "ns3/callback.h" #include "ns3/ptr.h" +#include "ns3/net-device.h" namespace ns3 { -class NetDevice; class Application; class Packet; class Address; @@ -130,7 +130,8 @@ public: /** * A protocol handler */ - typedef Callback, Ptr,uint16_t,const Address &> ProtocolHandler; + typedef Callback, Ptr,uint16_t,const Address &, + const Address &, NetDevice::PacketType> ProtocolHandler; /** * \param handler the handler to register * \param protocolType the type of protocol this handler is @@ -199,10 +200,8 @@ private: */ virtual void NotifyDeviceAdded (Ptr device); - bool ReceiveFromDevice (Ptr device, Ptr, - uint16_t protocol, const Address &from); - bool PromiscuousReceiveFromDevice (Ptr device, Ptr, - uint16_t protocol, const Address &from, const Address &to, bool forMe); + bool ReceiveFromDevice (Ptr device, Ptr, uint16_t protocol, + const Address &from, const Address &to, NetDevice::PacketType packetType); void Construct (void); struct ProtocolHandlerEntry { @@ -217,14 +216,6 @@ private: std::vector > m_applications; ProtocolHandlerList m_handlers; - // promiscuous protocol handlers - struct PromiscuousProtocolHandlerEntry { - PromiscuousProtocolHandler handler; - uint16_t protocol; - Ptr device; - }; - typedef std::vector PromiscuousProtocolHandlerList; - PromiscuousProtocolHandlerList m_promiscuousHandlers; }; } //namespace ns3 diff --git a/src/node/packet-socket.cc b/src/node/packet-socket.cc index 8d6e8272c..05b8b14d9 100644 --- a/src/node/packet-socket.cc +++ b/src/node/packet-socket.cc @@ -345,13 +345,19 @@ PacketSocket::SendTo (Ptr p, uint32_t flags, const Address &address) void PacketSocket::ForwardUp (Ptr device, Ptr packet, - uint16_t protocol, const Address &from) + uint16_t protocol, const Address &from, + const Address &to, NetDevice::PacketType packetType) { NS_LOG_FUNCTION_NOARGS (); if (m_shutdownRecv) { return; } + if (packetType != NetDevice::PACKET_HOST) + { + return; + } + PacketSocketAddress address; address.SetPhysicalAddress (from); diff --git a/src/node/packet-socket.h b/src/node/packet-socket.h index 528ca740d..3bfc4ae3c 100644 --- a/src/node/packet-socket.h +++ b/src/node/packet-socket.h @@ -27,6 +27,7 @@ #include "ns3/traced-callback.h" #include "ns3/ptr.h" #include "ns3/socket.h" +#include "ns3/net-device.h" namespace ns3 { @@ -103,7 +104,8 @@ public: private: void ForwardUp (Ptr device, Ptr packet, - uint16_t protocol, const Address &from); + uint16_t protocol, const Address &from, const Address &to, + NetDevice::PacketType packetType); int DoBind (const PacketSocketAddress &address); uint32_t GetMinMtu (PacketSocketAddress ad) const; virtual void DoDispose (void); diff --git a/src/node/simple-net-device.cc b/src/node/simple-net-device.cc index b3fbf26f5..ba58688bb 100644 --- a/src/node/simple-net-device.cc +++ b/src/node/simple-net-device.cc @@ -46,10 +46,20 @@ void SimpleNetDevice::Receive (Ptr packet, uint16_t protocol, Mac48Address to, Mac48Address from) { - if (to == m_address || to == Mac48Address::GetBroadcast ()) + NetDevice::PacketType packetType; + if (to == m_address) { - m_rxCallback (this, packet, protocol, from); + packetType = NetDevice::PACKET_HOST; } + else if (to == Mac48Address::GetBroadcast ()) + { + packetType = NetDevice::PACKET_HOST; + } + else + { + NS_FATAL_ERROR ("Weird packet destination " << to); + } + m_rxCallback (this, packet, protocol, from, to, packetType); } void @@ -180,10 +190,6 @@ SimpleNetDevice::SetReceiveCallback (NetDevice::ReceiveCallback cb) { m_rxCallback = cb; } -void -SimpleNetDevice::SetPromiscuousReceiveCallback (NetDevice::PromiscuousReceiveCallback cb) -{ -} void SimpleNetDevice::DoDispose (void) diff --git a/src/node/simple-net-device.h b/src/node/simple-net-device.h index 455717871..ac77c5cc5 100644 --- a/src/node/simple-net-device.h +++ b/src/node/simple-net-device.h @@ -68,7 +68,6 @@ public: virtual void SetNode (Ptr node); virtual bool NeedsArp (void) const; virtual void SetReceiveCallback (NetDevice::ReceiveCallback cb); - virtual void SetPromiscuousReceiveCallback (PromiscuousReceiveCallback cb); protected: virtual void DoDispose (void); From c5ec154ea171644ab693970c14e379ee863d6b58 Mon Sep 17 00:00:00 2001 From: "Gustavo J. A. M. Carneiro" Date: Mon, 7 Jul 2008 12:52:48 +0100 Subject: [PATCH 129/495] Add BridgeChannel --- src/devices/bridge/bridge-channel.cc | 83 +++++++++++++++++++++++++ src/devices/bridge/bridge-channel.h | 52 ++++++++++++++++ src/devices/bridge/bridge-net-device.cc | 7 ++- src/devices/bridge/bridge-net-device.h | 2 + src/devices/bridge/wscript | 2 + 5 files changed, 144 insertions(+), 2 deletions(-) create mode 100644 src/devices/bridge/bridge-channel.cc create mode 100644 src/devices/bridge/bridge-channel.h diff --git a/src/devices/bridge/bridge-channel.cc b/src/devices/bridge/bridge-channel.cc new file mode 100644 index 000000000..e5eac7a54 --- /dev/null +++ b/src/devices/bridge/bridge-channel.cc @@ -0,0 +1,83 @@ +/* -*- 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 + * + * Author: Gustavo Carneiro + */ + +#include "ns3/log.h" +#include "bridge-channel.h" + +NS_LOG_COMPONENT_DEFINE ("BridgeChannel"); + +namespace ns3 { + +NS_OBJECT_ENSURE_REGISTERED (BridgeChannel); + +TypeId +BridgeChannel::GetTypeId (void) +{ + static TypeId tid = TypeId ("ns3::BridgeChannel") + .SetParent (); + return tid; +} + +BridgeChannel::BridgeChannel () + : Channel ("BridgeChannel") +{ + NS_LOG_FUNCTION_NOARGS (); +} + +BridgeChannel::~BridgeChannel () +{ + NS_LOG_FUNCTION_NOARGS (); +} + +void +BridgeChannel::AddChannel (Ptr bridgedChannel) +{ + m_bridgedChannels.push_back (bridgedChannel); +} + +uint32_t +BridgeChannel::GetNDevices (void) const +{ + uint32_t ndevices = 0; + for (std::vector< Ptr >::const_iterator iter = m_bridgedChannels.begin (); + iter != m_bridgedChannels.end (); iter++) + { + ndevices += (*iter)->GetNDevices (); + } + return ndevices; +} + + +Ptr +BridgeChannel::GetDevice (uint32_t i) const +{ + uint32_t ndevices = 0; + for (std::vector< Ptr >::const_iterator iter = m_bridgedChannels.begin (); + iter != m_bridgedChannels.end (); iter++) + { + if ((i - ndevices) < (*iter)->GetNDevices ()) + { + return (*iter)->GetDevice (i - ndevices); + } + ndevices += (*iter)->GetNDevices (); + } + return NULL; +} + + +} // namespace ns3 diff --git a/src/devices/bridge/bridge-channel.h b/src/devices/bridge/bridge-channel.h new file mode 100644 index 000000000..7a01a821c --- /dev/null +++ b/src/devices/bridge/bridge-channel.h @@ -0,0 +1,52 @@ +/* -*- 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 + * + * Author: Gustavo Carneiro + */ +#ifndef BRIDGE_CHANNEL_H +#define BRIDGE_CHANNEL_H + +#include "ns3/net-device.h" +#include "ns3/channel.h" +#include + +namespace ns3 { + +/** + * \ingroup netdevice + * + * \brief bridge net device for bridge things and testing + */ +class BridgeChannel : public Channel +{ +public: + static TypeId GetTypeId (void); + BridgeChannel (); + virtual ~BridgeChannel (); + + void AddChannel (Ptr bridgedChannel); + + // virtual methods implementation, from Channel + virtual uint32_t GetNDevices (void) const; + virtual Ptr GetDevice (uint32_t i) const; + +private: + std::vector< Ptr > m_bridgedChannels; + +}; + +} // namespace ns3 + +#endif /* BRIDGE_CHANNEL_H */ diff --git a/src/devices/bridge/bridge-net-device.cc b/src/devices/bridge/bridge-net-device.cc index 88709fd68..6529d4da2 100644 --- a/src/devices/bridge/bridge-net-device.cc +++ b/src/devices/bridge/bridge-net-device.cc @@ -54,7 +54,9 @@ BridgeNetDevice::BridgeNetDevice () m_name (""), m_ifIndex (0), m_mtu (0xffff) -{} +{ + m_channel = CreateObject (); +} void BridgeNetDevice::ReceiveFromDevice (Ptr incomingPort, Ptr packet, uint16_t protocol, @@ -188,6 +190,7 @@ BridgeNetDevice::AddBridgePort (Ptr bridgePort) m_node->RegisterProtocolHandler (MakeCallback (&BridgeNetDevice::ReceiveFromDevice, this), 0, bridgePort); m_ports.push_back (bridgePort); + m_channel->AddChannel (bridgePort->GetChannel ()); } void @@ -217,7 +220,7 @@ BridgeNetDevice::GetIfIndex(void) const Ptr BridgeNetDevice::GetChannel (void) const { - return 0; + return m_channel; } Address diff --git a/src/devices/bridge/bridge-net-device.h b/src/devices/bridge/bridge-net-device.h index 025624586..7a4475b1d 100644 --- a/src/devices/bridge/bridge-net-device.h +++ b/src/devices/bridge/bridge-net-device.h @@ -21,6 +21,7 @@ #include "ns3/net-device.h" #include "ns3/mac48-address.h" #include "ns3/nstime.h" +#include "ns3/bridge-channel.h" #include #include #include @@ -90,6 +91,7 @@ private: }; std::map m_learnState; Ptr m_node; + Ptr m_channel; std::string m_name; std::vector< Ptr > m_ports; uint32_t m_ifIndex; diff --git a/src/devices/bridge/wscript b/src/devices/bridge/wscript index 6b0f5134a..fec55457e 100644 --- a/src/devices/bridge/wscript +++ b/src/devices/bridge/wscript @@ -4,9 +4,11 @@ def build(bld): obj = bld.create_ns3_module('bridge', ['node']) obj.source = [ 'bridge-net-device.cc', + 'bridge-channel.cc', ] headers = bld.create_obj('ns3header') headers.module = 'bridge' headers.source = [ 'bridge-net-device.h', + 'bridge-channel.h', ] From eb3d502a492733b736711489eca46d564682870e Mon Sep 17 00:00:00 2001 From: "Gustavo J. A. M. Carneiro" Date: Tue, 8 Jul 2008 14:40:01 +0100 Subject: [PATCH 130/495] Adapt to evil API breakage --- examples/csma-bridge.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/csma-bridge.cc b/examples/csma-bridge.cc index 69077ac0a..7b90919f5 100644 --- a/examples/csma-bridge.cc +++ b/examples/csma-bridge.cc @@ -77,8 +77,8 @@ main (int argc, char *argv[]) NS_LOG_INFO ("Build Topology"); CsmaHelper csma; - csma.SetChannelParameter ("DataRate", DataRateValue (5000000)); - csma.SetChannelParameter ("Delay", TimeValue (MilliSeconds (2))); + csma.SetChannelAttribute ("DataRate", DataRateValue (5000000)); + csma.SetChannelAttribute ("Delay", TimeValue (MilliSeconds (2))); // Create the csma links, from each terminal to the switch From d236aad5e512d1307c66c38775f5df1c3480c430 Mon Sep 17 00:00:00 2001 From: Raj Bhattacharjea Date: Tue, 8 Jul 2008 11:09:22 -0400 Subject: [PATCH 131/495] Check in a tcp example which has rate error models --- examples/tcp-errors.cc | 150 +++++++++++++++++++++++++++++++++++++++++ examples/wscript | 4 ++ 2 files changed, 154 insertions(+) create mode 100644 examples/tcp-errors.cc diff --git a/examples/tcp-errors.cc b/examples/tcp-errors.cc new file mode 100644 index 000000000..8197accfe --- /dev/null +++ b/examples/tcp-errors.cc @@ -0,0 +1,150 @@ +/* -*- 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 + * + */ + +// +// Network topology +// +// 10Mb/s, 10ms 10Mb/s, 10ms +// n0-----------------n1-----------------n2 +// +// +// - CBR traffic for 1000 seconds +// - Tracing of queues and packet receptions to file +// "tcp-large-transfer.tr" +// - pcap traces also generated in the following files +// "tcp-large-transfer-$n-$i.pcap" where n and i represent node and interface +// numbers respectively +// Usage (e.g.): ./waf --run tcp-large-transfer + + +#include +#include +#include +#include +#include + +#include "ns3/core-module.h" +#include "ns3/common-module.h" +#include "ns3/helper-module.h" +#include "ns3/node-module.h" +#include "ns3/global-route-manager.h" +#include "ns3/simulator-module.h" + +using namespace ns3; + +NS_LOG_COMPONENT_DEFINE ("TcpErrors"); + +int main (int argc, char *argv[]) +{ + + // Users may find it convenient to turn on explicit debugging + // for selected modules; the below lines suggest how to do this + // LogComponentEnable("TcpL4Protocol", LOG_LEVEL_ALL); + // LogComponentEnable("TcpSocketImpl", LOG_LEVEL_ALL); + // LogComponentEnable("PacketSink", LOG_LEVEL_ALL); + // LogComponentEnable("TcpErrors", LOG_LEVEL_ALL); + + // + // Make the random number generators generate reproducible results. + // + RandomVariable::UseGlobalSeed (1, 1, 2, 3, 5, 8); + + // Allow the user to override any of the defaults and the above + // Bind()s at run-time, via command-line arguments + CommandLine cmd; + cmd.Parse (argc, argv); + + // Here, we will explicitly create three nodes. The first container contains + // nodes 0 and 1 from the diagram above, and the second one contains nodes + // 1 and 2. This reflects the channel connectivity, and will be used to + // install the network interfaces and connect them with a channel. + NodeContainer n0n1; + n0n1.Create (2); + + NodeContainer n1n2; + n1n2.Add (n0n1.Get (1)); + n1n2.Create (1); + + // We create the channels first without any IP addressing information + // First make and configure the helper, so that it will put the appropriate + // parameters on the network interfaces and channels we are about to install. + PointToPointHelper p2p; + p2p.SetDeviceAttribute ("DataRate", DataRateValue (DataRate(10000000))); + p2p.SetChannelAttribute ("Delay", TimeValue (MilliSeconds(10))); + + // And then install devices and channels connecting our topology. + NetDeviceContainer d0d1 = p2p.Install (n0n1); + NetDeviceContainer d1d2 = p2p.Install (n1n2); + + // Now add ip/tcp stack to all nodes. + NodeContainer allNodes = NodeContainer (n0n1, n1n2.Get (1)); + InternetStackHelper internet; + internet.Install (allNodes); + + // Later, we add IP addresses. + Ipv4AddressHelper ipv4; + ipv4.SetBase ("10.1.3.0", "255.255.255.0"); + Ipv4InterfaceContainer i0i1 = ipv4.Assign (d0d1); + ipv4.SetBase ("10.1.2.0", "255.255.255.0"); + Ipv4InterfaceContainer i1i2 = ipv4.Assign (d1d2); + + // and setup ip routing tables to get total ip-level connectivity. + GlobalRouteManager::PopulateRoutingTables (); + + // Set up the sending CBR application + uint16_t servPort = 50000; + Address remoteAddress(InetSocketAddress(i1i2.GetAddress (1), servPort)); + OnOffHelper clientHelper ("ns3::TcpSocketFactory", remoteAddress); + clientHelper.SetAttribute + ("OnTime", RandomVariableValue (ConstantVariable (1))); + clientHelper.SetAttribute + ("OffTime", RandomVariableValue (ConstantVariable (0))); + ApplicationContainer clientApp = clientHelper.Install(n0n1.Get(0)); + clientApp.Start (Seconds (1.0)); + clientApp.Stop (Seconds (10.0)); + + // Create a packet sink to receive at n2 + PacketSinkHelper sinkHelper ("ns3::TcpSocketFactory", + InetSocketAddress (Ipv4Address::GetAny (), servPort)); + ApplicationContainer sinkApp = sinkHelper.Install (n1n2.Get(1)); + sinkApp.Start (Seconds (1.0)); + sinkApp.Stop (Seconds (10.0)); + + // We're going to model a lossy channel + RandomVariableValue u01(UniformVariable (0.0, 1.0)); + DoubleValue rate(0.001); + Ptr em1 = + CreateObject ("RanVar", u01, "ErrorRate", rate); + Ptr em2 = + CreateObject ("RanVar", u01, "ErrorRate", rate); + //put error models on both netdevices of the router nodes so that there is + //loss of both data and acks + d0d1.Get(1)->SetAttribute("ReceiveErrorModel", PointerValue (em1)); + d1d2.Get(0)->SetAttribute("ReceiveErrorModel", PointerValue (em2)); + + //Ask for ASCII and pcap traces of network traffic + std::ofstream ascii; + ascii.open ("tcp-errors.tr"); + PointToPointHelper::EnableAsciiAll (ascii); + + PointToPointHelper::EnablePcapAll ("tcp-errors"); + + // Finally, set up the simulator to run for 1000 seconds. + Simulator::Stop (Seconds(1000)); + Simulator::Run (); + Simulator::Destroy (); +} diff --git a/examples/wscript b/examples/wscript index b40248b5b..1892e3f90 100644 --- a/examples/wscript +++ b/examples/wscript @@ -52,6 +52,10 @@ def build(bld): ['point-to-point', 'internet-stack']) obj.source = 'tcp-large-transfer.cc' + obj = bld.create_ns3_program('tcp-errors', + ['point-to-point', 'internet-stack']) + obj.source = 'tcp-errors.cc' + obj = bld.create_ns3_program('tcp-star-server', ['point-to-point', 'internet-stack']) obj.source = 'tcp-star-server.cc' From 3c16c7d6d003fe0b5909dd3103c8b3961b9f6111 Mon Sep 17 00:00:00 2001 From: Mathieu Lacage Date: Tue, 8 Jul 2008 10:01:42 -0700 Subject: [PATCH 132/495] kill dead code --- src/common/error-model.h | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/common/error-model.h b/src/common/error-model.h index bf3767637..69b04a9fa 100644 --- a/src/common/error-model.h +++ b/src/common/error-model.h @@ -72,12 +72,6 @@ class ErrorModel : public Object { public: static TypeId GetTypeId (void); - /** - * A factory method to generate a preconfigured default ErrorModel for use - * \return an ErrorModel smart pointer that is the default ErrorModel - * type defined - */ - static Ptr CreateDefault (void); ErrorModel (); virtual ~ErrorModel (); From dfc7509dd688143421f5a33e3f507fc792e49a6c Mon Sep 17 00:00:00 2001 From: Mathieu Lacage Date: Tue, 8 Jul 2008 10:01:53 -0700 Subject: [PATCH 133/495] kill dead code --- src/contrib/gnuplot.h | 9 --------- 1 file changed, 9 deletions(-) diff --git a/src/contrib/gnuplot.h b/src/contrib/gnuplot.h index da928307d..ff1b2b7fb 100644 --- a/src/contrib/gnuplot.h +++ b/src/contrib/gnuplot.h @@ -94,15 +94,6 @@ public: * Use this method with error bar style X or Y. */ void Add (double x, double y, double errorDelta); - /** - * \param x x coord to new data point - * \param y y coord to new data point - * \param errorDeltaX x delta for the new data point - * \param errorDeltaY y delta for the new data point - * - * Use this method with error bar style XY. - */ - void Add (double x, double y, double errorDeltaX, double errorDeltaY); private: friend class Gnuplot; struct Data { From 8b1b7b25a2db0125533877c2fcd885a7d0850e22 Mon Sep 17 00:00:00 2001 From: Mathieu Lacage Date: Tue, 8 Jul 2008 10:02:11 -0700 Subject: [PATCH 134/495] kill dead code --- src/devices/wifi/ideal-wifi-manager.h | 1 - src/devices/wifi/wifi-phy.h | 2 -- 2 files changed, 3 deletions(-) diff --git a/src/devices/wifi/ideal-wifi-manager.h b/src/devices/wifi/ideal-wifi-manager.h index 613bda65a..80d3b7503 100644 --- a/src/devices/wifi/ideal-wifi-manager.h +++ b/src/devices/wifi/ideal-wifi-manager.h @@ -50,7 +50,6 @@ public: virtual void SetupPhy (Ptr phy); - WifiMode GetMode (double snr) const; // return the min snr needed to successfully transmit // data with this mode at the specified ber. double GetSnrThreshold (WifiMode mode) const; diff --git a/src/devices/wifi/wifi-phy.h b/src/devices/wifi/wifi-phy.h index d804f65a7..c07240644 100644 --- a/src/devices/wifi/wifi-phy.h +++ b/src/devices/wifi/wifi-phy.h @@ -167,8 +167,6 @@ public: double GetEdThreshold (void) const; - Ptr GetDevice (void) const; - /** * \param channel the channel to connect to. */ From 8e0738b5ba975df0a7e4eea190acf092c69beca3 Mon Sep 17 00:00:00 2001 From: Mathieu Lacage Date: Tue, 8 Jul 2008 10:02:28 -0700 Subject: [PATCH 135/495] add missing implementations --- src/devices/wifi/propagation-loss-model.cc | 13 ++++++++++++- src/devices/wifi/propagation-loss-model.h | 5 +++++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/src/devices/wifi/propagation-loss-model.cc b/src/devices/wifi/propagation-loss-model.cc index 022f783b7..b9d09ff32 100644 --- a/src/devices/wifi/propagation-loss-model.cc +++ b/src/devices/wifi/propagation-loss-model.cc @@ -97,7 +97,8 @@ FriisPropagationLossModel::GetTypeId (void) .AddAttribute ("MinDistance", "The distance under which the propagation model refuses to give results (m)", DoubleValue (0.5), - MakeDoubleAccessor (&FriisPropagationLossModel::m_minDistance), + MakeDoubleAccessor (&FriisPropagationLossModel::SetMinDistance, + &FriisPropagationLossModel::GetMinDistance), MakeDoubleChecker ()) ; return tid; @@ -116,6 +117,16 @@ FriisPropagationLossModel::GetSystemLoss (void) const return m_systemLoss; } void +FriisPropagationLossModel::SetMinDistance (double minDistance) +{ + m_minDistance = minDistance; +} +double +FriisPropagationLossModel::GetMinDistance (void) const +{ + return m_minDistance; +} +void FriisPropagationLossModel::SetLambda (double frequency, double speed) { m_lambda = speed / frequency; diff --git a/src/devices/wifi/propagation-loss-model.h b/src/devices/wifi/propagation-loss-model.h index 4ff7eac25..4ae46aa22 100644 --- a/src/devices/wifi/propagation-loss-model.h +++ b/src/devices/wifi/propagation-loss-model.h @@ -133,6 +133,11 @@ public: */ void SetMinDistance (double minDistance); + /** + * \returns the minimum distance. + */ + double GetMinDistance (void) const; + /** * \returns the current wavelength (m) */ From 864923164b9dc85c7db149a2a6fc756883d0b7c2 Mon Sep 17 00:00:00 2001 From: Mathieu Lacage Date: Tue, 8 Jul 2008 10:02:46 -0700 Subject: [PATCH 136/495] add missing implementations --- src/devices/wifi/nqap-wifi-mac.cc | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/devices/wifi/nqap-wifi-mac.cc b/src/devices/wifi/nqap-wifi-mac.cc index db8add000..d40df21f1 100644 --- a/src/devices/wifi/nqap-wifi-mac.cc +++ b/src/devices/wifi/nqap-wifi-mac.cc @@ -45,7 +45,8 @@ NqapWifiMac::GetTypeId (void) .AddConstructor () .AddAttribute ("BeaconInterval", "Delay between two beacons", TimeValue (Seconds (0.1)), - MakeTimeAccessor (&NqapWifiMac::m_beaconInterval), + MakeTimeAccessor (&NqapWifiMac::GetBeaconInterval, + &NqapWifiMac::SetBeaconInterval), MakeTimeChecker ()) .AddAttribute ("BeaconGeneration", "Whether or not beacons are generated.", BooleanValue (false), @@ -119,6 +120,11 @@ NqapWifiMac::GetBeaconGeneration (void) const { return m_beaconEvent.IsRunning (); } +Time +NqapWifiMac::GetBeaconInterval (void) const +{ + return m_beaconInterval; +} void NqapWifiMac::SetSlot (Time slotTime) From c1f8cff710b28d5b56aefcb82345911f2549b656 Mon Sep 17 00:00:00 2001 From: Mathieu Lacage Date: Tue, 8 Jul 2008 10:02:57 -0700 Subject: [PATCH 137/495] kill dead unimplemented API --- src/simulator/simulator.h | 16 ++-------------- 1 file changed, 2 insertions(+), 14 deletions(-) diff --git a/src/simulator/simulator.h b/src/simulator/simulator.h index b2eed6685..6752b7644 100644 --- a/src/simulator/simulator.h +++ b/src/simulator/simulator.h @@ -52,14 +52,9 @@ class SchedulerFactory; * is shown below: * \include samples/main-simulator.cc */ -class Simulator { +class Simulator +{ public: - /** - * Enable ParallelSimulation. - * This method must be invoked before every other method exported - * by the Simulator class. - */ - static void EnableParallelSimulation (void); /** * \param scheduler a new event scheduler * @@ -69,13 +64,6 @@ public: */ static void SetScheduler (Ptr scheduler); - /** - * Force the use of a user-provided event scheduler. - * This method must be invoked before any other method exported - * by the Simulator class. - */ - static void SetExternal (const std::string &name); - /** * Enable logging to the file identified by filename. If the file * does not exist, it is created. If it exists, it is destroyed and From 7f8fcbc54760a3b1d8be2585225c249d9fa9d1d2 Mon Sep 17 00:00:00 2001 From: Mathieu Lacage Date: Tue, 8 Jul 2008 10:10:26 -0700 Subject: [PATCH 138/495] add CalbackImplBase::GetReferenceCount --- src/core/callback.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/core/callback.h b/src/core/callback.h index 9d72aeb84..30e278478 100644 --- a/src/core/callback.h +++ b/src/core/callback.h @@ -85,6 +85,7 @@ public: delete this; } } + uint32_t GetReferenceCount (void) const { return m_count; } virtual bool IsEqual (Ptr other) const = 0; private: mutable uint32_t m_count; From b07781eeadfabef3606bc6c1b326f2ab39827c4d Mon Sep 17 00:00:00 2001 From: Mathieu Lacage Date: Tue, 8 Jul 2008 10:11:55 -0700 Subject: [PATCH 139/495] coding style --- src/core/ref-count-base.h | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/core/ref-count-base.h b/src/core/ref-count-base.h index 4ce8440c9..4fa704488 100644 --- a/src/core/ref-count-base.h +++ b/src/core/ref-count-base.h @@ -50,14 +50,15 @@ public: * conjunction with the Ptr template which would make calling Ref * unecessary and dangerous. */ - inline void Ref () const; + inline void Ref (void) const; /** * Decrement the reference count. This method should not be called * by user code. RefCountBase instances are expected to be used in * conjunction with the Ptr template which would make calling Ref * unecessary and dangerous. */ - inline void Unref () const; + inline void Unref (void) const; + private: // Note we make this mutable so that the const methods can still // change it. @@ -70,15 +71,16 @@ namespace ns3 { // Implementation of the in-line methods void -RefCountBase::Ref () const +RefCountBase::Ref (void) const { m_count++; } void -RefCountBase::Unref () const +RefCountBase::Unref (void) const { - if (--m_count == 0) + m_count--; + if (m_count == 0) { // All references removed, ok to delete delete this; } From 5a35637ab9c5a2a0879df5950057cf5fa6a999c2 Mon Sep 17 00:00:00 2001 From: Mathieu Lacage Date: Tue, 8 Jul 2008 10:12:38 -0700 Subject: [PATCH 140/495] add RefCountBase::GetReferenceCount. --- src/core/ref-count-base.h | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/core/ref-count-base.h b/src/core/ref-count-base.h index 4fa704488..e0cc0387c 100644 --- a/src/core/ref-count-base.h +++ b/src/core/ref-count-base.h @@ -59,6 +59,11 @@ public: */ inline void Unref (void) const; + /** + * Get the reference count of the object. Normally not needed; for language bindings. + */ + inline uint32_t GetReferenceCount (void) const; + private: // Note we make this mutable so that the const methods can still // change it. @@ -86,6 +91,12 @@ RefCountBase::Unref (void) const } } +uint32_t +RefCountBase::GetReferenceCount (void) const +{ + return m_count; +} + } // namespace ns3 #endif /* __REF_COUNT_BASE_H__*/ From 24693d3bbd2e5a0a9c70dd49b560d425388edc97 Mon Sep 17 00:00:00 2001 From: Mathieu Lacage Date: Tue, 8 Jul 2008 10:16:53 -0700 Subject: [PATCH 141/495] add Object::GetReferenceCount --- src/core/object.cc | 5 +++++ src/core/object.h | 6 ++++++ 2 files changed, 11 insertions(+) diff --git a/src/core/object.cc b/src/core/object.cc index 4a1c98dad..1b11fc782 100644 --- a/src/core/object.cc +++ b/src/core/object.cc @@ -95,6 +95,11 @@ Object::Object (const Object &o) m_disposed (false), m_next (this) {} +uint32_t +Object::GetReferenceCount (void) const +{ + return m_count; +} void Object::Construct (const AttributeList &attributes) { diff --git a/src/core/object.h b/src/core/object.h index dcaf97e36..cb9dc5884 100644 --- a/src/core/object.h +++ b/src/core/object.h @@ -112,6 +112,12 @@ public: * dangerous. */ inline void Unref (void) const; + + /** + * Get the reference count of the object. Normally not needed; for language bindings. + */ + uint32_t GetReferenceCount (void) const; + /** * \returns a pointer to the requested interface or zero if it could not be found. */ From 11ddb61d967811a1a35015f769cfbb2ffa9d6e99 Mon Sep 17 00:00:00 2001 From: Mathieu Lacage Date: Tue, 8 Jul 2008 10:17:18 -0700 Subject: [PATCH 142/495] avoid uneeded inline --- src/core/ref-count-base.cc | 6 ++++++ src/core/ref-count-base.h | 8 +------- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/core/ref-count-base.cc b/src/core/ref-count-base.cc index d376894f6..06abf7c22 100644 --- a/src/core/ref-count-base.cc +++ b/src/core/ref-count-base.cc @@ -43,4 +43,10 @@ RefCountBase::~RefCountBase () { } +uint32_t +RefCountBase::GetReferenceCount (void) const +{ + return m_count; +} + } // namespace ns3 diff --git a/src/core/ref-count-base.h b/src/core/ref-count-base.h index e0cc0387c..08e9946fa 100644 --- a/src/core/ref-count-base.h +++ b/src/core/ref-count-base.h @@ -62,7 +62,7 @@ public: /** * Get the reference count of the object. Normally not needed; for language bindings. */ - inline uint32_t GetReferenceCount (void) const; + uint32_t GetReferenceCount (void) const; private: // Note we make this mutable so that the const methods can still @@ -91,12 +91,6 @@ RefCountBase::Unref (void) const } } -uint32_t -RefCountBase::GetReferenceCount (void) const -{ - return m_count; -} - } // namespace ns3 #endif /* __REF_COUNT_BASE_H__*/ From 178567b32b75feab56377f692232e36a24ff5d0e Mon Sep 17 00:00:00 2001 From: Mathieu Lacage Date: Tue, 8 Jul 2008 10:19:34 -0700 Subject: [PATCH 143/495] add PythonCompleteConstruct friend for python bindings --- src/core/object.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/core/object.h b/src/core/object.h index cb9dc5884..c28c3d6c8 100644 --- a/src/core/object.h +++ b/src/core/object.h @@ -198,6 +198,10 @@ private: friend Ptr CopyObject (Ptr object); template friend Ptr CopyObject (Ptr object); + // The following friend method declaration is used only + // by our python bindings to call the protected ObjectBase::Construct + // method. + friend void PythonCompleteConstruct (Ptr object, TypeId typeId, const AttributeList &attributes); friend class ObjectFactory; friend class AggregateIterator; From 5f994081d5ddeb02308a9f0c5c7db1b1de1abed3 Mon Sep 17 00:00:00 2001 From: "Gustavo J. A. M. Carneiro" Date: Tue, 8 Jul 2008 10:43:58 -0700 Subject: [PATCH 144/495] python bindings --- bindings/python/callbacks_list.py | 12 + bindings/python/my_extra_api_definitions.py | 13 + bindings/python/ns3/__init__.py | 4 + bindings/python/ns3_module_common.py | 575 +++++++ bindings/python/ns3_module_contrib.py | 155 ++ bindings/python/ns3_module_core.py | 1317 ++++++++++++++++ bindings/python/ns3_module_csma.py | 245 +++ bindings/python/ns3_module_global_routing.py | 184 +++ bindings/python/ns3_module_helper.py | 409 +++++ bindings/python/ns3_module_internet_stack.py | 355 +++++ bindings/python/ns3_module_mobility.py | 439 ++++++ bindings/python/ns3_module_node.py | 1380 +++++++++++++++++ bindings/python/ns3_module_olsr.py | 288 ++++ bindings/python/ns3_module_onoff.py | 87 ++ bindings/python/ns3_module_packet_sink.py | 85 + bindings/python/ns3_module_point_to_point.py | 157 ++ bindings/python/ns3_module_simulator.py | 456 ++++++ bindings/python/ns3_module_udp_echo.py | 103 ++ bindings/python/ns3_module_wifi.py | 1225 +++++++++++++++ bindings/python/ns3module_helpers.cc | 178 +++ bindings/python/ns3modulegen.py | 116 ++ .../ns3modulegen_core_customizations.py | 495 ++++++ bindings/python/ns3modulegen_generated.py | 642 ++++++++ bindings/python/ns3modulescan.py | 281 ++++ bindings/python/rad_util.py | 909 +++++++++++ bindings/python/topsort.py | 392 +++++ bindings/python/waf | 1 + bindings/python/wscript | 367 +++++ samples/sample-simulator.py | 28 + utils/python-unit-tests.py | 86 + wscript | 21 +- 31 files changed, 11004 insertions(+), 1 deletion(-) create mode 100644 bindings/python/callbacks_list.py create mode 100644 bindings/python/my_extra_api_definitions.py create mode 100644 bindings/python/ns3/__init__.py create mode 100644 bindings/python/ns3_module_common.py create mode 100644 bindings/python/ns3_module_contrib.py create mode 100644 bindings/python/ns3_module_core.py create mode 100644 bindings/python/ns3_module_csma.py create mode 100644 bindings/python/ns3_module_global_routing.py create mode 100644 bindings/python/ns3_module_helper.py create mode 100644 bindings/python/ns3_module_internet_stack.py create mode 100644 bindings/python/ns3_module_mobility.py create mode 100644 bindings/python/ns3_module_node.py create mode 100644 bindings/python/ns3_module_olsr.py create mode 100644 bindings/python/ns3_module_onoff.py create mode 100644 bindings/python/ns3_module_packet_sink.py create mode 100644 bindings/python/ns3_module_point_to_point.py create mode 100644 bindings/python/ns3_module_simulator.py create mode 100644 bindings/python/ns3_module_udp_echo.py create mode 100644 bindings/python/ns3_module_wifi.py create mode 100644 bindings/python/ns3module_helpers.cc create mode 100644 bindings/python/ns3modulegen.py create mode 100644 bindings/python/ns3modulegen_core_customizations.py create mode 100644 bindings/python/ns3modulegen_generated.py create mode 100644 bindings/python/ns3modulescan.py create mode 100644 bindings/python/rad_util.py create mode 100644 bindings/python/topsort.py create mode 100644 bindings/python/waf create mode 100644 bindings/python/wscript create mode 100644 samples/sample-simulator.py create mode 100644 utils/python-unit-tests.py diff --git a/bindings/python/callbacks_list.py b/bindings/python/callbacks_list.py new file mode 100644 index 000000000..718c72288 --- /dev/null +++ b/bindings/python/callbacks_list.py @@ -0,0 +1,12 @@ +callback_classes = [ + ['void', 'ns3::empty', 'ns3::empty', 'ns3::empty', 'ns3::empty', 'ns3::empty', 'ns3::empty'], + ['bool', 'ns3::Ptr', 'ns3::Ptr', 'unsigned short', 'ns3::Address const&', 'ns3::empty', 'ns3::empty'], + ['void', 'ns3::Ptr', 'ns3::empty', 'ns3::empty', 'ns3::empty', 'ns3::empty', 'ns3::empty'], + ['void', 'ns3::Ptr', 'unsigned int', 'ns3::empty', 'ns3::empty', 'ns3::empty', 'ns3::empty'], + ['void', 'ns3::Ptr', 'ns3::Address const&', 'ns3::empty', 'ns3::empty', 'ns3::empty', 'ns3::empty'], + ['bool', 'ns3::Ptr', 'ns3::Address const&', 'ns3::empty', 'ns3::empty', 'ns3::empty', 'ns3::empty'], + ['void', 'ns3::Ptr', 'ns3::Mac48Address const&', 'ns3::empty', 'ns3::empty', 'ns3::empty', 'ns3::empty'], + ['void', 'ns3::Ptr', 'ns3::Ptr', 'unsigned short', 'ns3::Address const&', 'ns3::empty', 'ns3::empty'], + ['void', 'ns3::Ptr', 'double', 'ns3::empty', 'ns3::empty', 'ns3::empty', 'ns3::empty'], + ['void', 'ns3::Ptr', 'double', 'ns3::WifiMode', 'ns3::WifiPreamble', 'ns3::empty', 'ns3::empty'], +] diff --git a/bindings/python/my_extra_api_definitions.py b/bindings/python/my_extra_api_definitions.py new file mode 100644 index 000000000..e8afeec5c --- /dev/null +++ b/bindings/python/my_extra_api_definitions.py @@ -0,0 +1,13 @@ +from pybindgen import Module, FileCodeSink, write_preamble, param, retval + +def register_types(module): + module.add_class('MyClass') + +def register_methods(root_module): + MyClass = root_module['MyClass'] + MyClass.add_constructor([], visibility='public') + MyClass.add_constructor([param('double', 's'), param('double', 'l'), param('double', 'mean')], visibility='public') + +def register_functions(module): + module.add_function('SomeFunction', 'int', [param('int', 'xpto')]) + diff --git a/bindings/python/ns3/__init__.py b/bindings/python/ns3/__init__.py new file mode 100644 index 000000000..943a01575 --- /dev/null +++ b/bindings/python/ns3/__init__.py @@ -0,0 +1,4 @@ + +from _ns3 import * + + diff --git a/bindings/python/ns3_module_common.py b/bindings/python/ns3_module_common.py new file mode 100644 index 000000000..367fc2d98 --- /dev/null +++ b/bindings/python/ns3_module_common.py @@ -0,0 +1,575 @@ +from pybindgen import Module, FileCodeSink, write_preamble, param, retval + +def register_types(module): + root_module = module.get_root() + + ## error-model.h: ns3::ErrorUnit [enumeration] + module.add_enum('ErrorUnit', ['EU_BIT', 'EU_BYTE', 'EU_PKT']) + ## packet.h: ns3::Packet [class] + module.add_class('Packet', incref_method='Ref', decref_method='Unref', peekref_method='GetReferenceCount') + ## packet.h: ns3::TagIterator [class] + module.add_class('TagIterator') + ## packet.h: ns3::TagIterator::Item [class] + module.add_class('Item', outer_class=root_module['ns3::TagIterator']) + ## tag-list.h: ns3::TagList [class] + module.add_class('TagList') + ## tag-list.h: ns3::TagList::Iterator [class] + module.add_class('Iterator', outer_class=root_module['ns3::TagList']) + ## tag-list.h: ns3::TagList::Iterator::Item [struct] + module.add_class('Item', outer_class=root_module['ns3::TagList::Iterator']) + ## tag-buffer.h: ns3::TagBuffer [class] + module.add_class('TagBuffer') + ## buffer.h: ns3::Buffer [class] + module.add_class('Buffer') + ## buffer.h: ns3::Buffer::Iterator [class] + module.add_class('Iterator', outer_class=root_module['ns3::Buffer']) + ## chunk.h: ns3::Chunk [class] + module.add_class('Chunk', allow_subclassing=True, parent=root_module['ns3::ObjectBase']) + ## data-rate.h: ns3::DataRate [class] + module.add_class('DataRate') + ## tag.h: ns3::Tag [class] + module.add_class('Tag', allow_subclassing=True, parent=root_module['ns3::ObjectBase']) + ## pcap-writer.h: ns3::PcapWriter [class] + module.add_class('PcapWriter', parent=root_module['ns3::RefCountBase']) + ## data-rate.h: ns3::DataRateChecker [class] + module.add_class('DataRateChecker', parent=root_module['ns3::AttributeChecker']) + ## error-model.h: ns3::ErrorModel [class] + module.add_class('ErrorModel', allow_subclassing=True, parent=root_module['ns3::Object']) + ## header.h: ns3::Header [class] + module.add_class('Header', allow_subclassing=True, parent=root_module['ns3::Chunk']) + ## trailer.h: ns3::Trailer [class] + module.add_class('Trailer', allow_subclassing=True, parent=root_module['ns3::Chunk']) + ## error-model.h: ns3::ListErrorModel [class] + module.add_class('ListErrorModel', allow_subclassing=True, parent=root_module['ns3::ErrorModel']) + ## data-rate.h: ns3::DataRateValue [class] + module.add_class('DataRateValue', allow_subclassing=True, parent=root_module['ns3::AttributeValue']) + ## error-model.h: ns3::RateErrorModel [class] + module.add_class('RateErrorModel', allow_subclassing=True, parent=root_module['ns3::ErrorModel']) + + ## Register a nested module for the namespace internal + + nested_module = module.add_cpp_namespace('internal') + register_types_ns3_internal(nested_module) + + + ## Register a nested module for the namespace TimeStepPrecision + + nested_module = module.add_cpp_namespace('TimeStepPrecision') + register_types_ns3_TimeStepPrecision(nested_module) + + + ## Register a nested module for the namespace Config + + nested_module = module.add_cpp_namespace('Config') + register_types_ns3_Config(nested_module) + + + ## Register a nested module for the namespace olsr + + nested_module = module.add_cpp_namespace('olsr') + register_types_ns3_olsr(nested_module) + + +def register_types_ns3_internal(module): + root_module = module.get_root() + + +def register_types_ns3_TimeStepPrecision(module): + root_module = module.get_root() + + +def register_types_ns3_Config(module): + root_module = module.get_root() + + +def register_types_ns3_olsr(module): + root_module = module.get_root() + + +def register_methods(root_module): + register_Ns3Packet_methods(root_module, root_module['ns3::Packet']) + register_Ns3TagIterator_methods(root_module, root_module['ns3::TagIterator']) + register_Ns3TagIteratorItem_methods(root_module, root_module['ns3::TagIterator::Item']) + register_Ns3TagList_methods(root_module, root_module['ns3::TagList']) + register_Ns3TagListIterator_methods(root_module, root_module['ns3::TagList::Iterator']) + register_Ns3TagListIteratorItem_methods(root_module, root_module['ns3::TagList::Iterator::Item']) + register_Ns3TagBuffer_methods(root_module, root_module['ns3::TagBuffer']) + register_Ns3Buffer_methods(root_module, root_module['ns3::Buffer']) + register_Ns3BufferIterator_methods(root_module, root_module['ns3::Buffer::Iterator']) + register_Ns3Chunk_methods(root_module, root_module['ns3::Chunk']) + register_Ns3DataRate_methods(root_module, root_module['ns3::DataRate']) + register_Ns3Tag_methods(root_module, root_module['ns3::Tag']) + register_Ns3PcapWriter_methods(root_module, root_module['ns3::PcapWriter']) + register_Ns3DataRateChecker_methods(root_module, root_module['ns3::DataRateChecker']) + register_Ns3ErrorModel_methods(root_module, root_module['ns3::ErrorModel']) + register_Ns3Header_methods(root_module, root_module['ns3::Header']) + register_Ns3Trailer_methods(root_module, root_module['ns3::Trailer']) + register_Ns3ListErrorModel_methods(root_module, root_module['ns3::ListErrorModel']) + register_Ns3DataRateValue_methods(root_module, root_module['ns3::DataRateValue']) + register_Ns3RateErrorModel_methods(root_module, root_module['ns3::RateErrorModel']) + return + +def register_Ns3Packet_methods(root_module, cls): + ## packet.h: ns3::Packet::Packet() [constructor] + cls.add_constructor([], visibility='public') + ## packet.h: ns3::Packet::Packet(ns3::Packet const & o) [copy constructor] + cls.add_constructor([param('ns3::Packet&', 'o', is_const=True)], visibility='public') + ## packet.h: ns3::Packet::Packet(uint32_t size) [constructor] + cls.add_constructor([param('uint32_t', 'size')], visibility='public') + ## packet.h: ns3::Packet::Packet(uint8_t const * buffer, uint32_t size) [constructor] + cls.add_constructor([param('uint8_t *', 'buffer', transfer_ownership=False, is_const=True), param('uint32_t', 'size')], visibility='public') + ## packet.h: void ns3::Packet::AddAtEnd(ns3::Ptr packet) [member function] + cls.add_method('AddAtEnd', 'void', [param('ns3::Ptr< const ns3::Packet >', 'packet')]) + ## packet.h: void ns3::Packet::AddHeader(ns3::Header const & header) [member function] + cls.add_method('AddHeader', 'void', [param('ns3::Header&', 'header', is_const=True)]) + ## packet.h: void ns3::Packet::AddPaddingAtEnd(uint32_t size) [member function] + cls.add_method('AddPaddingAtEnd', 'void', [param('uint32_t', 'size')]) + ## packet.h: void ns3::Packet::AddTag(ns3::Tag const & tag) const [member function] + cls.add_method('AddTag', 'void', [param('ns3::Tag&', 'tag', is_const=True)], is_const=True) + ## packet.h: void ns3::Packet::AddTrailer(ns3::Trailer const & trailer) [member function] + cls.add_method('AddTrailer', 'void', [param('ns3::Trailer&', 'trailer', is_const=True)]) + ## packet.h: ns3::PacketMetadata::ItemIterator ns3::Packet::BeginItem() const [member function] + cls.add_method('BeginItem', 'ns3::PacketMetadata::ItemIterator', [], is_const=True) + ## packet.h: ns3::Ptr ns3::Packet::Copy() const [member function] + cls.add_method('Copy', 'ns3::Ptr< ns3::Packet >', [], is_const=True) + ## packet.h: ns3::Ptr ns3::Packet::CreateFragment(uint32_t start, uint32_t length) const [member function] + cls.add_method('CreateFragment', 'ns3::Ptr< ns3::Packet >', [param('uint32_t', 'start'), param('uint32_t', 'length')], is_const=True) + ## packet.h: void ns3::Packet::Deserialize(ns3::Buffer buffer) [member function] + cls.add_method('Deserialize', 'void', [param('ns3::Buffer', 'buffer')]) + ## packet.h: static void ns3::Packet::EnableMetadata() [member function] + cls.add_method('EnableMetadata', 'void', [], is_static=True) + ## packet.h: bool ns3::Packet::FindFirstMatchingTag(ns3::Tag & tag) const [member function] + cls.add_method('FindFirstMatchingTag', 'bool', [param('ns3::Tag&', 'tag')], is_const=True) + ## packet.h: uint32_t ns3::Packet::GetSize() const [member function] + cls.add_method('GetSize', 'uint32_t', [], is_const=True) + ## packet.h: ns3::TagIterator ns3::Packet::GetTagIterator() const [member function] + cls.add_method('GetTagIterator', 'ns3::TagIterator', [], is_const=True) + ## packet.h: uint32_t ns3::Packet::GetUid() const [member function] + cls.add_method('GetUid', 'uint32_t', [], is_const=True) + ## packet.h: uint8_t const * ns3::Packet::PeekData() const [member function] + cls.add_method('PeekData', retval('uint8_t *', is_const=True, caller_owns_return=False), [], is_const=True) + ## packet.h: uint32_t ns3::Packet::PeekHeader(ns3::Header & header) [member function] + cls.add_method('PeekHeader', 'uint32_t', [param('ns3::Header&', 'header')]) + ## packet.h: uint32_t ns3::Packet::PeekTrailer(ns3::Trailer & trailer) [member function] + cls.add_method('PeekTrailer', 'uint32_t', [param('ns3::Trailer&', 'trailer')]) + ## packet.h: void ns3::Packet::Print(std::ostream & os) const [member function] + cls.add_method('Print', 'void', [param('std::ostream&', 'os')], is_const=True) + ## packet.h: void ns3::Packet::PrintTags(std::ostream & os) const [member function] + cls.add_method('PrintTags', 'void', [param('std::ostream&', 'os')], is_const=True) + ## packet.h: void ns3::Packet::RemoveAllTags() [member function] + cls.add_method('RemoveAllTags', 'void', []) + ## packet.h: void ns3::Packet::RemoveAtEnd(uint32_t size) [member function] + cls.add_method('RemoveAtEnd', 'void', [param('uint32_t', 'size')]) + ## packet.h: void ns3::Packet::RemoveAtStart(uint32_t size) [member function] + cls.add_method('RemoveAtStart', 'void', [param('uint32_t', 'size')]) + ## packet.h: uint32_t ns3::Packet::RemoveHeader(ns3::Header & header) [member function] + cls.add_method('RemoveHeader', 'uint32_t', [param('ns3::Header&', 'header')]) + ## packet.h: uint32_t ns3::Packet::RemoveTrailer(ns3::Trailer & trailer) [member function] + cls.add_method('RemoveTrailer', 'uint32_t', [param('ns3::Trailer&', 'trailer')]) + ## packet.h: ns3::Buffer ns3::Packet::Serialize() const [member function] + cls.add_method('Serialize', 'ns3::Buffer', [], is_const=True) + cls.add_output_stream_operator() + return + +def register_Ns3TagIterator_methods(root_module, cls): + ## packet.h: bool ns3::TagIterator::HasNext() const [member function] + cls.add_method('HasNext', 'bool', [], is_const=True) + ## packet.h: ns3::TagIterator::Item ns3::TagIterator::Next() [member function] + cls.add_method('Next', 'ns3::TagIterator::Item', []) + return + +def register_Ns3TagIteratorItem_methods(root_module, cls): + ## packet.h: ns3::TypeId ns3::TagIterator::Item::GetTypeId() const [member function] + cls.add_method('GetTypeId', 'ns3::TypeId', [], is_const=True) + ## packet.h: uint32_t ns3::TagIterator::Item::GetStart() const [member function] + cls.add_method('GetStart', 'uint32_t', [], is_const=True) + ## packet.h: uint32_t ns3::TagIterator::Item::GetEnd() const [member function] + cls.add_method('GetEnd', 'uint32_t', [], is_const=True) + ## packet.h: void ns3::TagIterator::Item::GetTag(ns3::Tag & tag) const [member function] + cls.add_method('GetTag', 'void', [param('ns3::Tag&', 'tag')], is_const=True) + return + +def register_Ns3TagList_methods(root_module, cls): + ## tag-list.h: ns3::TagList::TagList() [constructor] + cls.add_constructor([], visibility='public') + ## tag-list.h: ns3::TagList::TagList(ns3::TagList const & o) [copy constructor] + cls.add_constructor([param('ns3::TagList&', 'o', is_const=True)], visibility='public') + ## tag-list.h: ns3::TagBuffer ns3::TagList::Add(ns3::TypeId tid, uint32_t bufferSize, int32_t start, int32_t end) [member function] + cls.add_method('Add', 'ns3::TagBuffer', [param('ns3::TypeId', 'tid'), param('uint32_t', 'bufferSize'), param('int32_t', 'start'), param('int32_t', 'end')]) + ## tag-list.h: void ns3::TagList::Add(ns3::TagList const & o) [member function] + cls.add_method('Add', 'void', [param('ns3::TagList&', 'o', is_const=True)]) + ## tag-list.h: void ns3::TagList::RemoveAll() [member function] + cls.add_method('RemoveAll', 'void', []) + ## tag-list.h: ns3::TagList::Iterator ns3::TagList::Begin(int32_t offsetStart, int32_t offsetEnd) const [member function] + cls.add_method('Begin', 'ns3::TagList::Iterator', [param('int32_t', 'offsetStart'), param('int32_t', 'offsetEnd')], is_const=True) + ## tag-list.h: void ns3::TagList::AddAtEnd(int32_t adjustment, int32_t appendOffset) [member function] + cls.add_method('AddAtEnd', 'void', [param('int32_t', 'adjustment'), param('int32_t', 'appendOffset')]) + ## tag-list.h: void ns3::TagList::AddAtStart(int32_t adjustment, int32_t prependOffset) [member function] + cls.add_method('AddAtStart', 'void', [param('int32_t', 'adjustment'), param('int32_t', 'prependOffset')]) + return + +def register_Ns3TagListIterator_methods(root_module, cls): + ## tag-list.h: bool ns3::TagList::Iterator::HasNext() const [member function] + cls.add_method('HasNext', 'bool', [], is_const=True) + ## tag-list.h: ns3::TagList::Iterator::Item ns3::TagList::Iterator::Next() [member function] + cls.add_method('Next', 'ns3::TagList::Iterator::Item', []) + ## tag-list.h: uint32_t ns3::TagList::Iterator::GetOffsetStart() const [member function] + cls.add_method('GetOffsetStart', 'uint32_t', [], is_const=True) + return + +def register_Ns3TagListIteratorItem_methods(root_module, cls): + ## tag-list.h: ns3::TagList::Iterator::Item::tid [variable] + cls.add_instance_attribute('tid', 'ns3::TypeId', is_const=False) + ## tag-list.h: ns3::TagList::Iterator::Item::size [variable] + cls.add_instance_attribute('size', 'uint32_t', is_const=False) + ## tag-list.h: ns3::TagList::Iterator::Item::start [variable] + cls.add_instance_attribute('start', 'int32_t', is_const=False) + ## tag-list.h: ns3::TagList::Iterator::Item::end [variable] + cls.add_instance_attribute('end', 'int32_t', is_const=False) + ## tag-list.h: ns3::TagList::Iterator::Item::buf [variable] + cls.add_instance_attribute('buf', 'ns3::TagBuffer', is_const=False) + ## tag-list.h: ns3::TagList::Iterator::Item::Item(ns3::TagBuffer buf) [constructor] + cls.add_constructor([param('ns3::TagBuffer', 'buf')], visibility='public') + return + +def register_Ns3TagBuffer_methods(root_module, cls): + ## tag-buffer.h: ns3::TagBuffer::TagBuffer(uint8_t * start, uint8_t * end) [constructor] + cls.add_constructor([param('uint8_t *', 'start'), param('uint8_t *', 'end')], visibility='public') + ## tag-buffer.h: void ns3::TagBuffer::TrimAtEnd(uint32_t trim) [member function] + cls.add_method('TrimAtEnd', 'void', [param('uint32_t', 'trim')]) + ## tag-buffer.h: void ns3::TagBuffer::CopyFrom(ns3::TagBuffer o) [member function] + cls.add_method('CopyFrom', 'void', [param('ns3::TagBuffer', 'o')]) + ## tag-buffer.h: void ns3::TagBuffer::WriteU8(uint8_t v) [member function] + cls.add_method('WriteU8', 'void', [param('uint8_t', 'v')]) + ## tag-buffer.h: void ns3::TagBuffer::WriteU16(uint16_t data) [member function] + cls.add_method('WriteU16', 'void', [param('uint16_t', 'data')]) + ## tag-buffer.h: void ns3::TagBuffer::WriteU32(uint32_t data) [member function] + cls.add_method('WriteU32', 'void', [param('uint32_t', 'data')]) + ## tag-buffer.h: void ns3::TagBuffer::WriteU64(uint64_t v) [member function] + cls.add_method('WriteU64', 'void', [param('uint64_t', 'v')]) + ## tag-buffer.h: void ns3::TagBuffer::WriteDouble(double v) [member function] + cls.add_method('WriteDouble', 'void', [param('double', 'v')]) + ## tag-buffer.h: void ns3::TagBuffer::Write(uint8_t const * buffer, uint32_t size) [member function] + cls.add_method('Write', 'void', [param('uint8_t *', 'buffer', transfer_ownership=False, is_const=True), param('uint32_t', 'size')]) + ## tag-buffer.h: uint8_t ns3::TagBuffer::ReadU8() [member function] + cls.add_method('ReadU8', 'uint8_t', []) + ## tag-buffer.h: uint16_t ns3::TagBuffer::ReadU16() [member function] + cls.add_method('ReadU16', 'uint16_t', []) + ## tag-buffer.h: uint32_t ns3::TagBuffer::ReadU32() [member function] + cls.add_method('ReadU32', 'uint32_t', []) + ## tag-buffer.h: uint64_t ns3::TagBuffer::ReadU64() [member function] + cls.add_method('ReadU64', 'uint64_t', []) + ## tag-buffer.h: double ns3::TagBuffer::ReadDouble() [member function] + cls.add_method('ReadDouble', 'double', []) + ## tag-buffer.h: void ns3::TagBuffer::Read(uint8_t * buffer, uint32_t size) [member function] + cls.add_method('Read', 'void', [param('uint8_t *', 'buffer'), param('uint32_t', 'size')]) + return + +def register_Ns3Buffer_methods(root_module, cls): + ## buffer.h: uint32_t ns3::Buffer::GetSize() const [member function] + cls.add_method('GetSize', 'uint32_t', [], is_const=True) + ## buffer.h: uint8_t const * ns3::Buffer::PeekData() const [member function] + cls.add_method('PeekData', retval('uint8_t *', is_const=True, caller_owns_return=False), [], is_const=True) + ## buffer.h: bool ns3::Buffer::AddAtStart(uint32_t start) [member function] + cls.add_method('AddAtStart', 'bool', [param('uint32_t', 'start')]) + ## buffer.h: bool ns3::Buffer::AddAtEnd(uint32_t end) [member function] + cls.add_method('AddAtEnd', 'bool', [param('uint32_t', 'end')]) + ## buffer.h: void ns3::Buffer::AddAtEnd(ns3::Buffer const & o) [member function] + cls.add_method('AddAtEnd', 'void', [param('ns3::Buffer&', 'o', is_const=True)]) + ## buffer.h: void ns3::Buffer::RemoveAtStart(uint32_t start) [member function] + cls.add_method('RemoveAtStart', 'void', [param('uint32_t', 'start')]) + ## buffer.h: void ns3::Buffer::RemoveAtEnd(uint32_t end) [member function] + cls.add_method('RemoveAtEnd', 'void', [param('uint32_t', 'end')]) + ## buffer.h: ns3::Buffer ns3::Buffer::CreateFragment(uint32_t start, uint32_t length) const [member function] + cls.add_method('CreateFragment', 'ns3::Buffer', [param('uint32_t', 'start'), param('uint32_t', 'length')], is_const=True) + ## buffer.h: ns3::Buffer::Iterator ns3::Buffer::Begin() const [member function] + cls.add_method('Begin', 'ns3::Buffer::Iterator', [], is_const=True) + ## buffer.h: ns3::Buffer::Iterator ns3::Buffer::End() const [member function] + cls.add_method('End', 'ns3::Buffer::Iterator', [], is_const=True) + ## buffer.h: ns3::Buffer ns3::Buffer::CreateFullCopy() const [member function] + cls.add_method('CreateFullCopy', 'ns3::Buffer', [], is_const=True) + ## buffer.h: int32_t ns3::Buffer::GetCurrentStartOffset() const [member function] + cls.add_method('GetCurrentStartOffset', 'int32_t', [], is_const=True) + ## buffer.h: int32_t ns3::Buffer::GetCurrentEndOffset() const [member function] + cls.add_method('GetCurrentEndOffset', 'int32_t', [], is_const=True) + ## buffer.h: ns3::Buffer::Buffer(ns3::Buffer const & o) [copy constructor] + cls.add_constructor([param('ns3::Buffer&', 'o', is_const=True)], visibility='public') + ## buffer.h: ns3::Buffer::Buffer() [constructor] + cls.add_constructor([], visibility='public') + ## buffer.h: ns3::Buffer::Buffer(uint32_t dataSize) [constructor] + cls.add_constructor([param('uint32_t', 'dataSize')], visibility='public') + return + +def register_Ns3BufferIterator_methods(root_module, cls): + ## buffer.h: ns3::Buffer::Iterator::Iterator() [constructor] + cls.add_constructor([], visibility='public') + ## buffer.h: void ns3::Buffer::Iterator::Next() [member function] + cls.add_method('Next', 'void', []) + ## buffer.h: void ns3::Buffer::Iterator::Prev() [member function] + cls.add_method('Prev', 'void', []) + ## buffer.h: void ns3::Buffer::Iterator::Next(uint32_t delta) [member function] + cls.add_method('Next', 'void', [param('uint32_t', 'delta')]) + ## buffer.h: void ns3::Buffer::Iterator::Prev(uint32_t delta) [member function] + cls.add_method('Prev', 'void', [param('uint32_t', 'delta')]) + ## buffer.h: uint32_t ns3::Buffer::Iterator::GetDistanceFrom(ns3::Buffer::Iterator const & o) const [member function] + cls.add_method('GetDistanceFrom', 'uint32_t', [param('ns3::Buffer::Iterator&', 'o', is_const=True)], is_const=True) + ## buffer.h: bool ns3::Buffer::Iterator::IsEnd() const [member function] + cls.add_method('IsEnd', 'bool', [], is_const=True) + ## buffer.h: bool ns3::Buffer::Iterator::IsStart() const [member function] + cls.add_method('IsStart', 'bool', [], is_const=True) + ## buffer.h: void ns3::Buffer::Iterator::WriteU8(uint8_t data) [member function] + cls.add_method('WriteU8', 'void', [param('uint8_t', 'data')]) + ## buffer.h: void ns3::Buffer::Iterator::WriteU8(uint8_t data, uint32_t len) [member function] + cls.add_method('WriteU8', 'void', [param('uint8_t', 'data'), param('uint32_t', 'len')]) + ## buffer.h: void ns3::Buffer::Iterator::WriteU16(uint16_t data) [member function] + cls.add_method('WriteU16', 'void', [param('uint16_t', 'data')]) + ## buffer.h: void ns3::Buffer::Iterator::WriteU32(uint32_t data) [member function] + cls.add_method('WriteU32', 'void', [param('uint32_t', 'data')]) + ## buffer.h: void ns3::Buffer::Iterator::WriteU64(uint64_t data) [member function] + cls.add_method('WriteU64', 'void', [param('uint64_t', 'data')]) + ## buffer.h: void ns3::Buffer::Iterator::WriteHtolsbU16(uint16_t data) [member function] + cls.add_method('WriteHtolsbU16', 'void', [param('uint16_t', 'data')]) + ## buffer.h: void ns3::Buffer::Iterator::WriteHtolsbU32(uint32_t data) [member function] + cls.add_method('WriteHtolsbU32', 'void', [param('uint32_t', 'data')]) + ## buffer.h: void ns3::Buffer::Iterator::WriteHtolsbU64(uint64_t data) [member function] + cls.add_method('WriteHtolsbU64', 'void', [param('uint64_t', 'data')]) + ## buffer.h: void ns3::Buffer::Iterator::WriteHtonU16(uint16_t data) [member function] + cls.add_method('WriteHtonU16', 'void', [param('uint16_t', 'data')]) + ## buffer.h: void ns3::Buffer::Iterator::WriteHtonU32(uint32_t data) [member function] + cls.add_method('WriteHtonU32', 'void', [param('uint32_t', 'data')]) + ## buffer.h: void ns3::Buffer::Iterator::WriteHtonU64(uint64_t data) [member function] + cls.add_method('WriteHtonU64', 'void', [param('uint64_t', 'data')]) + ## buffer.h: void ns3::Buffer::Iterator::Write(uint8_t const * buffer, uint32_t size) [member function] + cls.add_method('Write', 'void', [param('uint8_t *', 'buffer', transfer_ownership=False, is_const=True), param('uint32_t', 'size')]) + ## buffer.h: void ns3::Buffer::Iterator::Write(ns3::Buffer::Iterator start, ns3::Buffer::Iterator end) [member function] + cls.add_method('Write', 'void', [param('ns3::Buffer::Iterator', 'start'), param('ns3::Buffer::Iterator', 'end')]) + ## buffer.h: uint8_t ns3::Buffer::Iterator::ReadU8() [member function] + cls.add_method('ReadU8', 'uint8_t', []) + ## buffer.h: uint16_t ns3::Buffer::Iterator::ReadU16() [member function] + cls.add_method('ReadU16', 'uint16_t', []) + ## buffer.h: uint32_t ns3::Buffer::Iterator::ReadU32() [member function] + cls.add_method('ReadU32', 'uint32_t', []) + ## buffer.h: uint64_t ns3::Buffer::Iterator::ReadU64() [member function] + cls.add_method('ReadU64', 'uint64_t', []) + ## buffer.h: uint16_t ns3::Buffer::Iterator::ReadNtohU16() [member function] + cls.add_method('ReadNtohU16', 'uint16_t', []) + ## buffer.h: uint32_t ns3::Buffer::Iterator::ReadNtohU32() [member function] + cls.add_method('ReadNtohU32', 'uint32_t', []) + ## buffer.h: uint64_t ns3::Buffer::Iterator::ReadNtohU64() [member function] + cls.add_method('ReadNtohU64', 'uint64_t', []) + ## buffer.h: uint16_t ns3::Buffer::Iterator::ReadLsbtohU16() [member function] + cls.add_method('ReadLsbtohU16', 'uint16_t', []) + ## buffer.h: uint32_t ns3::Buffer::Iterator::ReadLsbtohU32() [member function] + cls.add_method('ReadLsbtohU32', 'uint32_t', []) + ## buffer.h: uint64_t ns3::Buffer::Iterator::ReadLsbtohU64() [member function] + cls.add_method('ReadLsbtohU64', 'uint64_t', []) + ## buffer.h: void ns3::Buffer::Iterator::Read(uint8_t * buffer, uint32_t size) [member function] + cls.add_method('Read', 'void', [param('uint8_t *', 'buffer'), param('uint32_t', 'size')]) + ## buffer.h: uint16_t ns3::Buffer::Iterator::CalculateIpChecksum(uint16_t size) [member function] + cls.add_method('CalculateIpChecksum', 'uint16_t', [param('uint16_t', 'size')]) + ## buffer.h: uint16_t ns3::Buffer::Iterator::CalculateIpChecksum(uint16_t size, uint32_t initialChecksum) [member function] + cls.add_method('CalculateIpChecksum', 'uint16_t', [param('uint16_t', 'size'), param('uint32_t', 'initialChecksum')]) + return + +def register_Ns3Chunk_methods(root_module, cls): + ## chunk.h: ns3::Chunk::Chunk() [constructor] + cls.add_constructor([], visibility='public') + ## chunk.h: ns3::Chunk::Chunk(ns3::Chunk const & arg0) [copy constructor] + cls.add_constructor([param('ns3::Chunk&', 'arg0', is_const=True)], visibility='public') + ## chunk.h: static ns3::TypeId ns3::Chunk::GetTypeId() [member function] + cls.add_method('GetTypeId', 'ns3::TypeId', [], is_static=True) + ## chunk.h: uint32_t ns3::Chunk::Deserialize(ns3::Buffer::Iterator start) [member function] + cls.add_method('Deserialize', 'uint32_t', [param('ns3::Buffer::Iterator', 'start')], is_pure_virtual=True, is_virtual=True) + ## chunk.h: void ns3::Chunk::Print(std::ostream & os) const [member function] + cls.add_method('Print', 'void', [param('std::ostream&', 'os')], is_pure_virtual=True, is_const=True, is_virtual=True) + return + +def register_Ns3DataRate_methods(root_module, cls): + ## data-rate.h: ns3::DataRate::DataRate(ns3::DataRate const & arg0) [copy constructor] + cls.add_constructor([param('ns3::DataRate&', 'arg0', is_const=True)], visibility='public') + ## data-rate.h: ns3::DataRate::DataRate() [constructor] + cls.add_constructor([], visibility='public') + ## data-rate.h: ns3::DataRate::DataRate(uint64_t bps) [constructor] + cls.add_constructor([param('uint64_t', 'bps')], visibility='public') + ## data-rate.h: ns3::DataRate::DataRate(std::string rate) [constructor] + cls.add_constructor([param('std::string', 'rate')], visibility='public') + ## data-rate.h: double ns3::DataRate::CalculateTxTime(uint32_t bytes) const [member function] + cls.add_method('CalculateTxTime', 'double', [param('uint32_t', 'bytes')], is_const=True) + ## data-rate.h: uint64_t ns3::DataRate::GetBitRate() const [member function] + cls.add_method('GetBitRate', 'uint64_t', [], is_const=True) + cls.add_output_stream_operator() + return + +def register_Ns3Tag_methods(root_module, cls): + ## tag.h: static ns3::TypeId ns3::Tag::GetTypeId() [member function] + cls.add_method('GetTypeId', 'ns3::TypeId', [], is_static=True) + ## tag.h: uint32_t ns3::Tag::GetSerializedSize() const [member function] + cls.add_method('GetSerializedSize', 'uint32_t', [], is_pure_virtual=True, is_const=True, is_virtual=True) + ## tag.h: void ns3::Tag::Serialize(ns3::TagBuffer i) const [member function] + cls.add_method('Serialize', 'void', [param('ns3::TagBuffer', 'i')], is_pure_virtual=True, is_const=True, is_virtual=True) + ## tag.h: void ns3::Tag::Deserialize(ns3::TagBuffer i) [member function] + cls.add_method('Deserialize', 'void', [param('ns3::TagBuffer', 'i')], is_pure_virtual=True, is_virtual=True) + ## tag.h: void ns3::Tag::Print(std::ostream & os) const [member function] + cls.add_method('Print', 'void', [param('std::ostream&', 'os')], is_pure_virtual=True, is_const=True, is_virtual=True) + cls.add_constructor([]) + return + +def register_Ns3PcapWriter_methods(root_module, cls): + ## pcap-writer.h: ns3::PcapWriter::PcapWriter() [constructor] + cls.add_constructor([], visibility='public') + ## pcap-writer.h: void ns3::PcapWriter::Open(std::string const & name) [member function] + cls.add_method('Open', 'void', [param('std::string&', 'name', is_const=True)]) + ## pcap-writer.h: void ns3::PcapWriter::WriteEthernetHeader() [member function] + cls.add_method('WriteEthernetHeader', 'void', []) + ## pcap-writer.h: void ns3::PcapWriter::WriteIpHeader() [member function] + cls.add_method('WriteIpHeader', 'void', []) + ## pcap-writer.h: void ns3::PcapWriter::WriteWifiHeader() [member function] + cls.add_method('WriteWifiHeader', 'void', []) + ## pcap-writer.h: void ns3::PcapWriter::WritePppHeader() [member function] + cls.add_method('WritePppHeader', 'void', []) + ## pcap-writer.h: void ns3::PcapWriter::WritePacket(ns3::Ptr packet) [member function] + cls.add_method('WritePacket', 'void', [param('ns3::Ptr< const ns3::Packet >', 'packet')]) + return + +def register_Ns3DataRateChecker_methods(root_module, cls): + cls.add_constructor([]) + return + +def register_Ns3ErrorModel_methods(root_module, cls): + ## error-model.h: static ns3::TypeId ns3::ErrorModel::GetTypeId() [member function] + cls.add_method('GetTypeId', 'ns3::TypeId', [], is_static=True) + ## error-model.h: ns3::ErrorModel::ErrorModel() [constructor] + cls.add_constructor([], visibility='public') + ## error-model.h: bool ns3::ErrorModel::IsCorrupt(ns3::Ptr pkt) [member function] + cls.add_method('IsCorrupt', 'bool', [param('ns3::Ptr< ns3::Packet >', 'pkt')]) + ## error-model.h: void ns3::ErrorModel::Reset() [member function] + cls.add_method('Reset', 'void', []) + ## error-model.h: void ns3::ErrorModel::Enable() [member function] + cls.add_method('Enable', 'void', []) + ## error-model.h: void ns3::ErrorModel::Disable() [member function] + cls.add_method('Disable', 'void', []) + ## error-model.h: bool ns3::ErrorModel::IsEnabled() const [member function] + cls.add_method('IsEnabled', 'bool', [], is_const=True) + ## error-model.h: bool ns3::ErrorModel::DoCorrupt(ns3::Ptr arg0) [member function] + cls.add_method('DoCorrupt', 'bool', [param('ns3::Ptr< ns3::Packet >', 'arg0')], is_pure_virtual=True, visibility='private', is_virtual=True) + ## error-model.h: void ns3::ErrorModel::DoReset() [member function] + cls.add_method('DoReset', 'void', [], is_pure_virtual=True, visibility='private', is_virtual=True) + return + +def register_Ns3Header_methods(root_module, cls): + ## header.h: ns3::Header::Header() [constructor] + cls.add_constructor([], visibility='public') + ## header.h: ns3::Header::Header(ns3::Header const & arg0) [copy constructor] + cls.add_constructor([param('ns3::Header&', 'arg0', is_const=True)], visibility='public') + ## header.h: uint32_t ns3::Header::Deserialize(ns3::Buffer::Iterator start) [member function] + cls.add_method('Deserialize', 'uint32_t', [param('ns3::Buffer::Iterator', 'start')], is_pure_virtual=True, is_virtual=True) + ## header.h: uint32_t ns3::Header::GetSerializedSize() const [member function] + cls.add_method('GetSerializedSize', 'uint32_t', [], is_pure_virtual=True, is_const=True, is_virtual=True) + ## header.h: static ns3::TypeId ns3::Header::GetTypeId() [member function] + cls.add_method('GetTypeId', 'ns3::TypeId', [], is_static=True) + ## header.h: void ns3::Header::Print(std::ostream & os) const [member function] + cls.add_method('Print', 'void', [param('std::ostream&', 'os')], is_pure_virtual=True, is_const=True, is_virtual=True) + ## header.h: void ns3::Header::Serialize(ns3::Buffer::Iterator start) const [member function] + cls.add_method('Serialize', 'void', [param('ns3::Buffer::Iterator', 'start')], is_pure_virtual=True, is_const=True, is_virtual=True) + cls.add_output_stream_operator() + return + +def register_Ns3Trailer_methods(root_module, cls): + ## trailer.h: ns3::Trailer::Trailer() [constructor] + cls.add_constructor([], visibility='public') + ## trailer.h: ns3::Trailer::Trailer(ns3::Trailer const & arg0) [copy constructor] + cls.add_constructor([param('ns3::Trailer&', 'arg0', is_const=True)], visibility='public') + ## trailer.h: uint32_t ns3::Trailer::Deserialize(ns3::Buffer::Iterator end) [member function] + cls.add_method('Deserialize', 'uint32_t', [param('ns3::Buffer::Iterator', 'end')], is_pure_virtual=True, is_virtual=True) + ## trailer.h: uint32_t ns3::Trailer::GetSerializedSize() const [member function] + cls.add_method('GetSerializedSize', 'uint32_t', [], is_pure_virtual=True, is_const=True, is_virtual=True) + ## trailer.h: static ns3::TypeId ns3::Trailer::GetTypeId() [member function] + cls.add_method('GetTypeId', 'ns3::TypeId', [], is_static=True) + ## trailer.h: void ns3::Trailer::Print(std::ostream & os) const [member function] + cls.add_method('Print', 'void', [param('std::ostream&', 'os')], is_pure_virtual=True, is_const=True, is_virtual=True) + ## trailer.h: void ns3::Trailer::Serialize(ns3::Buffer::Iterator start) const [member function] + cls.add_method('Serialize', 'void', [param('ns3::Buffer::Iterator', 'start')], is_pure_virtual=True, is_const=True, is_virtual=True) + cls.add_output_stream_operator() + return + +def register_Ns3ListErrorModel_methods(root_module, cls): + ## error-model.h: static ns3::TypeId ns3::ListErrorModel::GetTypeId() [member function] + cls.add_method('GetTypeId', 'ns3::TypeId', [], is_static=True) + ## error-model.h: ns3::ListErrorModel::ListErrorModel() [constructor] + cls.add_constructor([], visibility='public') + ## error-model.h: std::list > ns3::ListErrorModel::GetList() const [member function] + cls.add_method('GetList', 'std::list< unsigned int, std::allocator< unsigned int > >', [], is_const=True) + ## error-model.h: void ns3::ListErrorModel::SetList(std::list > const & packetlist) [member function] + cls.add_method('SetList', 'void', [param('std::list< unsigned int, std::allocator< unsigned int > >&', 'packetlist', is_const=True)]) + ## error-model.h: bool ns3::ListErrorModel::DoCorrupt(ns3::Ptr p) [member function] + cls.add_method('DoCorrupt', 'bool', [param('ns3::Ptr< ns3::Packet >', 'p')], visibility='private', is_virtual=True) + ## error-model.h: void ns3::ListErrorModel::DoReset() [member function] + cls.add_method('DoReset', 'void', [], visibility='private', is_virtual=True) + return + +def register_Ns3DataRateValue_methods(root_module, cls): + ## data-rate.h: ns3::DataRateValue::DataRateValue() [constructor] + cls.add_constructor([], visibility='public') + ## data-rate.h: ns3::DataRateValue::DataRateValue(ns3::DataRate const & value) [constructor] + cls.add_constructor([param('ns3::DataRate&', 'value', is_const=True)], visibility='public') + ## data-rate.h: void ns3::DataRateValue::Set(ns3::DataRate const & value) [member function] + cls.add_method('Set', 'void', [param('ns3::DataRate&', 'value', is_const=True)]) + ## data-rate.h: ns3::DataRate ns3::DataRateValue::Get() const [member function] + cls.add_method('Get', 'ns3::DataRate', [], is_const=True) + ## data-rate.h: ns3::Ptr ns3::DataRateValue::Copy() const [member function] + cls.add_method('Copy', 'ns3::Ptr< ns3::AttributeValue >', [], is_const=True, is_virtual=True) + ## data-rate.h: std::string ns3::DataRateValue::SerializeToString(ns3::Ptr checker) const [member function] + cls.add_method('SerializeToString', 'std::string', [param('ns3::Ptr< ns3::AttributeChecker const >', 'checker')], is_const=True, is_virtual=True) + ## data-rate.h: bool ns3::DataRateValue::DeserializeFromString(std::string value, ns3::Ptr checker) [member function] + cls.add_method('DeserializeFromString', 'bool', [param('std::string', 'value'), param('ns3::Ptr< ns3::AttributeChecker const >', 'checker')], is_virtual=True) + return + +def register_Ns3RateErrorModel_methods(root_module, cls): + ## error-model.h: static ns3::TypeId ns3::RateErrorModel::GetTypeId() [member function] + cls.add_method('GetTypeId', 'ns3::TypeId', [], is_static=True) + ## error-model.h: ns3::RateErrorModel::RateErrorModel() [constructor] + cls.add_constructor([], visibility='public') + ## error-model.h: ns3::ErrorUnit ns3::RateErrorModel::GetUnit() const [member function] + cls.add_method('GetUnit', 'ns3::ErrorUnit', [], is_const=True) + ## error-model.h: void ns3::RateErrorModel::SetUnit(ns3::ErrorUnit error_unit) [member function] + cls.add_method('SetUnit', 'void', [param('ns3::ErrorUnit', 'error_unit')]) + ## error-model.h: double ns3::RateErrorModel::GetRate() const [member function] + cls.add_method('GetRate', 'double', [], is_const=True) + ## error-model.h: void ns3::RateErrorModel::SetRate(double rate) [member function] + cls.add_method('SetRate', 'void', [param('double', 'rate')]) + ## error-model.h: void ns3::RateErrorModel::SetRandomVariable(ns3::RandomVariable const & ranvar) [member function] + cls.add_method('SetRandomVariable', 'void', [param('ns3::RandomVariable&', 'ranvar', is_const=True)]) + ## error-model.h: bool ns3::RateErrorModel::DoCorrupt(ns3::Ptr p) [member function] + cls.add_method('DoCorrupt', 'bool', [param('ns3::Ptr< ns3::Packet >', 'p')], visibility='private', is_virtual=True) + ## error-model.h: bool ns3::RateErrorModel::DoCorruptPkt(ns3::Ptr p) [member function] + cls.add_method('DoCorruptPkt', 'bool', [param('ns3::Ptr< ns3::Packet >', 'p')], visibility='private', is_virtual=True) + ## error-model.h: bool ns3::RateErrorModel::DoCorruptByte(ns3::Ptr p) [member function] + cls.add_method('DoCorruptByte', 'bool', [param('ns3::Ptr< ns3::Packet >', 'p')], visibility='private', is_virtual=True) + ## error-model.h: bool ns3::RateErrorModel::DoCorruptBit(ns3::Ptr p) [member function] + cls.add_method('DoCorruptBit', 'bool', [param('ns3::Ptr< ns3::Packet >', 'p')], visibility='private', is_virtual=True) + ## error-model.h: void ns3::RateErrorModel::DoReset() [member function] + cls.add_method('DoReset', 'void', [], visibility='private', is_virtual=True) + return + +def register_functions(root_module): + module = root_module + ## data-rate.h: extern ns3::Ptr ns3::MakeDataRateChecker() [free function] + module.add_function('MakeDataRateChecker', 'ns3::Ptr< ns3::AttributeChecker const >', []) + register_functions_ns3_internal(module.get_submodule('internal'), root_module) + register_functions_ns3_TimeStepPrecision(module.get_submodule('TimeStepPrecision'), root_module) + register_functions_ns3_Config(module.get_submodule('Config'), root_module) + register_functions_ns3_olsr(module.get_submodule('olsr'), root_module) + return + +def register_functions_ns3_internal(module, root_module): + return + +def register_functions_ns3_TimeStepPrecision(module, root_module): + return + +def register_functions_ns3_Config(module, root_module): + return + +def register_functions_ns3_olsr(module, root_module): + return + diff --git a/bindings/python/ns3_module_contrib.py b/bindings/python/ns3_module_contrib.py new file mode 100644 index 000000000..852b23750 --- /dev/null +++ b/bindings/python/ns3_module_contrib.py @@ -0,0 +1,155 @@ +from pybindgen import Module, FileCodeSink, write_preamble, param, retval + +def register_types(module): + root_module = module.get_root() + + ## gnuplot.h: ns3::Gnuplot [class] + module.add_class('Gnuplot') + ## event-garbage-collector.h: ns3::EventGarbageCollector [class] + module.add_class('EventGarbageCollector') + ## gnuplot.h: ns3::GnuplotDataset [class] + module.add_class('GnuplotDataset') + ## gnuplot.h: ns3::GnuplotDataset::Style [enumeration] + module.add_enum('Style', ['LINES', 'POINTS', 'LINES_POINTS', 'DOTS', 'IMPULSES', 'STEPS', 'FSTEPS', 'HISTEPS'], outer_class=root_module['ns3::GnuplotDataset']) + ## gnuplot.h: ns3::GnuplotDataset::ErrorBars [enumeration] + module.add_enum('ErrorBars', ['NONE', 'X', 'Y', 'XY'], outer_class=root_module['ns3::GnuplotDataset']) + ## gtk-config-store.h: ns3::GtkConfigStore [class] + module.add_class('GtkConfigStore') + ## config-store.h: ns3::ConfigStore [class] + module.add_class('ConfigStore', allow_subclassing=True, parent=root_module['ns3::ObjectBase']) + ## delay-jitter-estimation.h: ns3::DelayJitterEstimation [class] + module.add_class('DelayJitterEstimation') + + ## Register a nested module for the namespace internal + + nested_module = module.add_cpp_namespace('internal') + register_types_ns3_internal(nested_module) + + + ## Register a nested module for the namespace TimeStepPrecision + + nested_module = module.add_cpp_namespace('TimeStepPrecision') + register_types_ns3_TimeStepPrecision(nested_module) + + + ## Register a nested module for the namespace Config + + nested_module = module.add_cpp_namespace('Config') + register_types_ns3_Config(nested_module) + + + ## Register a nested module for the namespace olsr + + nested_module = module.add_cpp_namespace('olsr') + register_types_ns3_olsr(nested_module) + + +def register_types_ns3_internal(module): + root_module = module.get_root() + + +def register_types_ns3_TimeStepPrecision(module): + root_module = module.get_root() + + +def register_types_ns3_Config(module): + root_module = module.get_root() + + +def register_types_ns3_olsr(module): + root_module = module.get_root() + + +def register_methods(root_module): + register_Ns3Gnuplot_methods(root_module, root_module['ns3::Gnuplot']) + register_Ns3EventGarbageCollector_methods(root_module, root_module['ns3::EventGarbageCollector']) + register_Ns3GnuplotDataset_methods(root_module, root_module['ns3::GnuplotDataset']) + register_Ns3GtkConfigStore_methods(root_module, root_module['ns3::GtkConfigStore']) + register_Ns3ConfigStore_methods(root_module, root_module['ns3::ConfigStore']) + register_Ns3DelayJitterEstimation_methods(root_module, root_module['ns3::DelayJitterEstimation']) + return + +def register_Ns3Gnuplot_methods(root_module, cls): + ## gnuplot.h: ns3::Gnuplot::Gnuplot(std::string pngFilename) [constructor] + cls.add_constructor([param('std::string', 'pngFilename')], visibility='public') + ## gnuplot.h: void ns3::Gnuplot::SetLegend(std::string xLegend, std::string yLegend) [member function] + cls.add_method('SetLegend', 'void', [param('std::string', 'xLegend'), param('std::string', 'yLegend')]) + ## gnuplot.h: void ns3::Gnuplot::AddDataset(ns3::GnuplotDataset const & dataset) [member function] + cls.add_method('AddDataset', 'void', [param('ns3::GnuplotDataset&', 'dataset', is_const=True)]) + ## gnuplot.h: void ns3::Gnuplot::GenerateOutput(std::ostream & os) [member function] + cls.add_method('GenerateOutput', 'void', [param('std::ostream&', 'os')]) + return + +def register_Ns3EventGarbageCollector_methods(root_module, cls): + ## event-garbage-collector.h: ns3::EventGarbageCollector::EventGarbageCollector() [constructor] + cls.add_constructor([], visibility='public') + ## event-garbage-collector.h: void ns3::EventGarbageCollector::Track(ns3::EventId event) [member function] + cls.add_method('Track', 'void', [param('ns3::EventId', 'event')]) + return + +def register_Ns3GnuplotDataset_methods(root_module, cls): + ## gnuplot.h: ns3::GnuplotDataset::GnuplotDataset() [constructor] + cls.add_constructor([], visibility='public') + ## gnuplot.h: ns3::GnuplotDataset::GnuplotDataset(std::string title) [constructor] + cls.add_constructor([param('std::string', 'title')], visibility='public') + ## gnuplot.h: void ns3::GnuplotDataset::SetStyle(ns3::GnuplotDataset::Style style) [member function] + cls.add_method('SetStyle', 'void', [param('ns3::GnuplotDataset::Style', 'style')]) + ## gnuplot.h: void ns3::GnuplotDataset::SetErrorBars(ns3::GnuplotDataset::ErrorBars errorBars) [member function] + cls.add_method('SetErrorBars', 'void', [param('ns3::GnuplotDataset::ErrorBars', 'errorBars')]) + ## gnuplot.h: void ns3::GnuplotDataset::Add(double x, double y) [member function] + cls.add_method('Add', 'void', [param('double', 'x'), param('double', 'y')]) + ## gnuplot.h: void ns3::GnuplotDataset::Add(double x, double y, double errorDelta) [member function] + cls.add_method('Add', 'void', [param('double', 'x'), param('double', 'y'), param('double', 'errorDelta')]) + return + +def register_Ns3GtkConfigStore_methods(root_module, cls): + ## gtk-config-store.h: ns3::GtkConfigStore::GtkConfigStore() [constructor] + cls.add_constructor([], visibility='public') + ## gtk-config-store.h: void ns3::GtkConfigStore::Configure() [member function] + cls.add_method('Configure', 'void', []) + return + +def register_Ns3ConfigStore_methods(root_module, cls): + ## config-store.h: static ns3::TypeId ns3::ConfigStore::GetTypeId() [member function] + cls.add_method('GetTypeId', 'ns3::TypeId', [], is_static=True) + ## config-store.h: ns3::TypeId ns3::ConfigStore::GetInstanceTypeId() const [member function] + cls.add_method('GetInstanceTypeId', 'ns3::TypeId', [], is_const=True, is_virtual=True) + ## config-store.h: ns3::ConfigStore::ConfigStore() [constructor] + cls.add_constructor([], visibility='public') + ## config-store.h: void ns3::ConfigStore::Configure() [member function] + cls.add_method('Configure', 'void', []) + return + +def register_Ns3DelayJitterEstimation_methods(root_module, cls): + ## delay-jitter-estimation.h: ns3::DelayJitterEstimation::DelayJitterEstimation() [constructor] + cls.add_constructor([], visibility='public') + ## delay-jitter-estimation.h: static void ns3::DelayJitterEstimation::PrepareTx(ns3::Ptr packet) [member function] + cls.add_method('PrepareTx', 'void', [param('ns3::Ptr< const ns3::Packet >', 'packet')], is_static=True) + ## delay-jitter-estimation.h: void ns3::DelayJitterEstimation::RecordRx(ns3::Ptr packet) [member function] + cls.add_method('RecordRx', 'void', [param('ns3::Ptr< const ns3::Packet >', 'packet')]) + ## delay-jitter-estimation.h: ns3::Time ns3::DelayJitterEstimation::GetLastDelay() const [member function] + cls.add_method('GetLastDelay', 'ns3::Time', [], is_const=True) + ## delay-jitter-estimation.h: ns3::Time ns3::DelayJitterEstimation::GetLastJitter() const [member function] + cls.add_method('GetLastJitter', 'ns3::Time', [], is_const=True) + return + +def register_functions(root_module): + module = root_module + register_functions_ns3_internal(module.get_submodule('internal'), root_module) + register_functions_ns3_TimeStepPrecision(module.get_submodule('TimeStepPrecision'), root_module) + register_functions_ns3_Config(module.get_submodule('Config'), root_module) + register_functions_ns3_olsr(module.get_submodule('olsr'), root_module) + return + +def register_functions_ns3_internal(module, root_module): + return + +def register_functions_ns3_TimeStepPrecision(module, root_module): + return + +def register_functions_ns3_Config(module, root_module): + return + +def register_functions_ns3_olsr(module, root_module): + return + diff --git a/bindings/python/ns3_module_core.py b/bindings/python/ns3_module_core.py new file mode 100644 index 000000000..6020f63c7 --- /dev/null +++ b/bindings/python/ns3_module_core.py @@ -0,0 +1,1317 @@ +from pybindgen import Module, FileCodeSink, write_preamble, param, retval + +def register_types(module): + root_module = module.get_root() + + ## random-variable.h: ns3::RandomVariable [class] + module.add_class('RandomVariable') + ## random-variable.h: ns3::TriangularVariable [class] + module.add_class('TriangularVariable', parent=root_module['ns3::RandomVariable']) + ## global-value.h: ns3::GlobalValue [class] + module.add_class('GlobalValue') + ## ref-count-base.h: ns3::RefCountBase [class] + module.add_class('RefCountBase', incref_method='Ref', automatic_type_narrowing=True, decref_method='Unref', peekref_method='GetReferenceCount') + ## type-id.h: ns3::TypeId [class] + module.add_class('TypeId') + ## type-id.h: ns3::TypeId::AttributeFlag [enumeration] + module.add_enum('AttributeFlag', ['ATTR_GET', 'ATTR_SET', 'ATTR_CONSTRUCT', 'ATTR_SGC'], outer_class=root_module['ns3::TypeId']) + ## type-id.h: ns3::TypeId::AttributeInfo [struct] + module.add_class('AttributeInfo', outer_class=root_module['ns3::TypeId']) + ## system-wall-clock-ms.h: ns3::SystemWallClockMs [class] + module.add_class('SystemWallClockMs') + ## callback.h: ns3::CallbackImplBase [class] + module.add_class('CallbackImplBase', incref_method='Ref', allow_subclassing=True, decref_method='Unref', peekref_method='GetReferenceCount') + ## trace-source-accessor.h: ns3::TraceSourceAccessor [class] + module.add_class('TraceSourceAccessor', allow_subclassing=True) + ## attribute.h: ns3::AttributeChecker [class] + module.add_class('AttributeChecker', incref_method='Ref', allow_subclassing=False, automatic_type_narrowing=True, decref_method='Unref', parent=root_module['ns3::RefCountBase']) + ## random-variable.h: ns3::RandomVariableChecker [class] + module.add_class('RandomVariableChecker', parent=root_module['ns3::AttributeChecker']) + ## random-variable.h: ns3::NormalVariable [class] + module.add_class('NormalVariable', parent=root_module['ns3::RandomVariable']) + ## object-factory.h: ns3::ObjectFactory [class] + module.add_class('ObjectFactory') + ## attribute.h: ns3::AttributeAccessor [class] + module.add_class('AttributeAccessor', allow_subclassing=True, parent=root_module['ns3::RefCountBase']) + ## random-variable.h: ns3::ParetoVariable [class] + module.add_class('ParetoVariable', parent=root_module['ns3::RandomVariable']) + ## random-variable.h: ns3::ConstantVariable [class] + module.add_class('ConstantVariable', parent=root_module['ns3::RandomVariable']) + ## random-variable.h: ns3::EmpiricalVariable [class] + module.add_class('EmpiricalVariable', parent=root_module['ns3::RandomVariable']) + ## enum.h: ns3::EnumChecker [class] + module.add_class('EnumChecker', allow_subclassing=True, parent=root_module['ns3::AttributeChecker']) + ## empty.h: ns3::empty [class] + module.add_class('empty') + ## object-base.h: ns3::ObjectBase [class] + module.add_class('ObjectBase', allow_subclassing=True) + ## command-line.h: ns3::CommandLine [class] + module.add_class('CommandLine') + ## int-to-type.h: ns3::IntToType<6> [struct] + module.add_class('IntToType', template_parameters=['6']) + ## int-to-type.h: ns3::IntToType<6>::v_e [enumeration] + module.add_enum('v_e', ['value'], outer_class=root_module['ns3::IntToType< 6 >']) + ## int-to-type.h: ns3::IntToType<5> [struct] + module.add_class('IntToType', template_parameters=['5']) + ## int-to-type.h: ns3::IntToType<5>::v_e [enumeration] + module.add_enum('v_e', ['value'], outer_class=root_module['ns3::IntToType< 5 >']) + ## int-to-type.h: ns3::IntToType<4> [struct] + module.add_class('IntToType', template_parameters=['4']) + ## int-to-type.h: ns3::IntToType<4>::v_e [enumeration] + module.add_enum('v_e', ['value'], outer_class=root_module['ns3::IntToType< 4 >']) + ## int-to-type.h: ns3::IntToType<3> [struct] + module.add_class('IntToType', template_parameters=['3']) + ## int-to-type.h: ns3::IntToType<3>::v_e [enumeration] + module.add_enum('v_e', ['value'], outer_class=root_module['ns3::IntToType< 3 >']) + ## int-to-type.h: ns3::IntToType<2> [struct] + module.add_class('IntToType', template_parameters=['2']) + ## int-to-type.h: ns3::IntToType<2>::v_e [enumeration] + module.add_enum('v_e', ['value'], outer_class=root_module['ns3::IntToType< 2 >']) + ## int-to-type.h: ns3::IntToType<1> [struct] + module.add_class('IntToType', template_parameters=['1']) + ## int-to-type.h: ns3::IntToType<1>::v_e [enumeration] + module.add_enum('v_e', ['value'], outer_class=root_module['ns3::IntToType< 1 >']) + ## int-to-type.h: ns3::IntToType<0> [struct] + module.add_class('IntToType', template_parameters=['0']) + ## int-to-type.h: ns3::IntToType<0>::v_e [enumeration] + module.add_enum('v_e', ['value'], outer_class=root_module['ns3::IntToType< 0 >']) + ## rng-stream.h: ns3::RngStream [class] + module.add_class('RngStream') + ## random-variable.h: ns3::LogNormalVariable [class] + module.add_class('LogNormalVariable', parent=root_module['ns3::RandomVariable']) + ## random-variable.h: ns3::IntEmpiricalVariable [class] + module.add_class('IntEmpiricalVariable', parent=root_module['ns3::EmpiricalVariable']) + ## pointer.h: ns3::PointerChecker [class] + module.add_class('PointerChecker', allow_subclassing=True, parent=root_module['ns3::AttributeChecker']) + ## random-variable.h: ns3::WeibullVariable [class] + module.add_class('WeibullVariable', parent=root_module['ns3::RandomVariable']) + ## callback.h: ns3::CallbackBase [class] + module.add_class('CallbackBase') + ## random-variable.h: ns3::ExponentialVariable [class] + module.add_class('ExponentialVariable', parent=root_module['ns3::RandomVariable']) + ## traced-callback.h: ns3::TracedCallback, ns3::Mac48Address, ns3::empty, ns3::empty> [class] + module.add_class('TracedCallback', template_parameters=['ns3::Ptr', 'ns3::Mac48Address', 'ns3::empty', 'ns3::empty']) + ## traced-callback.h: ns3::TracedCallback, ns3::empty, ns3::empty, ns3::empty> [class] + module.add_class('TracedCallback', template_parameters=['ns3::Ptr', 'ns3::empty', 'ns3::empty', 'ns3::empty']) + ## traced-callback.h: ns3::TracedCallback, ns3::Address const&, ns3::empty, ns3::empty> [class] + module.add_class('TracedCallback', template_parameters=['ns3::Ptr', 'ns3::Address const&', 'ns3::empty', 'ns3::empty']) + ## traced-callback.h: ns3::TracedCallback, unsigned int, ns3::empty, ns3::empty> [class] + module.add_class('TracedCallback', template_parameters=['ns3::Ptr', 'unsigned int', 'ns3::empty', 'ns3::empty']) + ## traced-callback.h: ns3::TracedCallback, ns3::empty, ns3::empty, ns3::empty> [class] + module.add_class('TracedCallback', template_parameters=['ns3::Ptr', 'ns3::empty', 'ns3::empty', 'ns3::empty']) + ## traced-callback.h: ns3::TracedCallback, ns3::TimeUnit<1>, ns3::WifiPhy::State, ns3::empty> [class] + module.add_class('TracedCallback', template_parameters=['ns3::TimeUnit<1>', 'ns3::TimeUnit<1>', 'ns3::WifiPhy::State', 'ns3::empty']) + ## traced-callback.h: ns3::TracedCallback, ns3::WifiMode, ns3::WifiPreamble, unsigned char> [class] + module.add_class('TracedCallback', template_parameters=['ns3::Ptr', 'ns3::WifiMode', 'ns3::WifiPreamble', 'unsigned char']) + ## traced-callback.h: ns3::TracedCallback, double, ns3::empty, ns3::empty> [class] + module.add_class('TracedCallback', template_parameters=['ns3::Ptr', 'double', 'ns3::empty', 'ns3::empty']) + ## traced-callback.h: ns3::TracedCallback, double, ns3::WifiMode, ns3::WifiPreamble> [class] + module.add_class('TracedCallback', template_parameters=['ns3::Ptr', 'double', 'ns3::WifiMode', 'ns3::WifiPreamble']) + ## traced-callback.h: ns3::TracedCallback [class] + module.add_class('TracedCallback', template_parameters=['unsigned int', 'unsigned int', 'ns3::empty', 'ns3::empty']) + ## random-variable.h: ns3::DeterministicVariable [class] + module.add_class('DeterministicVariable', parent=root_module['ns3::RandomVariable']) + ## attribute-list.h: ns3::AttributeList [class] + module.add_class('AttributeList') + ## attribute.h: ns3::AttributeValue [class] + module.add_class('AttributeValue', incref_method='Ref', allow_subclassing=False, automatic_type_narrowing=True, decref_method='Unref', parent=root_module['ns3::RefCountBase']) + ## random-variable.h: ns3::UniformVariable [class] + module.add_class('UniformVariable', parent=root_module['ns3::RandomVariable']) + ## object.h: ns3::Object [class] + module.add_class('Object', peekref_method='GetReferenceCount', parent=root_module['ns3::ObjectBase'], incref_method='Ref', decref_method='Unref', allow_subclassing=True, automatic_type_narrowing=True) + ## object.h: ns3::Object::AggregateIterator [class] + module.add_class('AggregateIterator', outer_class=root_module['ns3::Object']) + ## random-variable.h: ns3::SequentialVariable [class] + module.add_class('SequentialVariable', parent=root_module['ns3::RandomVariable']) + ## object-vector.h: ns3::ObjectVectorChecker [class] + module.add_class('ObjectVectorChecker', allow_subclassing=True, parent=root_module['ns3::AttributeChecker']) + ## string.h: ns3::StringChecker [class] + module.add_class('StringChecker', parent=root_module['ns3::AttributeChecker']) + ## object-vector.h: ns3::ObjectVectorValue [class] + module.add_class('ObjectVectorValue', allow_subclassing=True, parent=root_module['ns3::AttributeValue']) + ## boolean.h: ns3::BooleanChecker [class] + module.add_class('BooleanChecker', parent=root_module['ns3::AttributeChecker']) + ## uinteger.h: ns3::UintegerValue [class] + module.add_class('UintegerValue', allow_subclassing=True, parent=root_module['ns3::AttributeValue']) + ## object-vector.h: ns3::ObjectVectorAccessor [class] + module.add_class('ObjectVectorAccessor', allow_subclassing=True, parent=root_module['ns3::AttributeAccessor']) + ## pointer.h: ns3::PointerValue [class] + module.add_class('PointerValue', allow_subclassing=True, parent=root_module['ns3::AttributeValue']) + ## object-factory.h: ns3::ObjectFactoryChecker [class] + module.add_class('ObjectFactoryChecker', parent=root_module['ns3::AttributeChecker']) + ## type-id.h: ns3::TypeIdChecker [class] + module.add_class('TypeIdChecker', parent=root_module['ns3::AttributeChecker']) + ## double.h: ns3::DoubleValue [class] + module.add_class('DoubleValue', allow_subclassing=True, parent=root_module['ns3::AttributeValue']) + ## string.h: ns3::StringValue [class] + module.add_class('StringValue', allow_subclassing=True, parent=root_module['ns3::AttributeValue']) + ## type-id.h: ns3::TypeIdValue [class] + module.add_class('TypeIdValue', allow_subclassing=True, parent=root_module['ns3::AttributeValue']) + ## enum.h: ns3::EnumValue [class] + module.add_class('EnumValue', allow_subclassing=True, parent=root_module['ns3::AttributeValue']) + ## random-variable.h: ns3::RandomVariableValue [class] + module.add_class('RandomVariableValue', allow_subclassing=True, parent=root_module['ns3::AttributeValue']) + ## object-factory.h: ns3::ObjectFactoryValue [class] + module.add_class('ObjectFactoryValue', allow_subclassing=True, parent=root_module['ns3::AttributeValue']) + ## integer.h: ns3::IntegerValue [class] + module.add_class('IntegerValue', allow_subclassing=True, parent=root_module['ns3::AttributeValue']) + ## attribute.h: ns3::EmptyAttributeValue [class] + module.add_class('EmptyAttributeValue', allow_subclassing=True, parent=root_module['ns3::AttributeValue']) + ## boolean.h: ns3::BooleanValue [class] + module.add_class('BooleanValue', allow_subclassing=True, parent=root_module['ns3::AttributeValue']) + ## traced-value.h: ns3::TracedValue [class] + module.add_class('TracedValue', template_parameters=['unsigned int']) + ## traced-value.h: ns3::TracedValue [class] + root_module['ns3::TracedValue< unsigned int >'].implicitly_converts_to(root_module['ns3::IntegerValue']) + ## traced-value.h: ns3::TracedValue [class] + root_module['ns3::TracedValue< unsigned int >'].implicitly_converts_to(root_module['ns3::UintegerValue']) + ## traced-value.h: ns3::TracedValue [class] + root_module['ns3::TracedValue< unsigned int >'].implicitly_converts_to(root_module['ns3::BooleanValue']) + ## traced-value.h: ns3::TracedValue [class] + root_module['ns3::TracedValue< unsigned int >'].implicitly_converts_to(root_module['ns3::EnumValue']) + + ## Register a nested module for the namespace internal + + nested_module = module.add_cpp_namespace('internal') + register_types_ns3_internal(nested_module) + + + ## Register a nested module for the namespace TimeStepPrecision + + nested_module = module.add_cpp_namespace('TimeStepPrecision') + register_types_ns3_TimeStepPrecision(nested_module) + + + ## Register a nested module for the namespace Config + + nested_module = module.add_cpp_namespace('Config') + register_types_ns3_Config(nested_module) + + + ## Register a nested module for the namespace olsr + + nested_module = module.add_cpp_namespace('olsr') + register_types_ns3_olsr(nested_module) + + +def register_types_ns3_internal(module): + root_module = module.get_root() + + +def register_types_ns3_TimeStepPrecision(module): + root_module = module.get_root() + + +def register_types_ns3_Config(module): + root_module = module.get_root() + + +def register_types_ns3_olsr(module): + root_module = module.get_root() + + +def register_methods(root_module): + register_Ns3RandomVariable_methods(root_module, root_module['ns3::RandomVariable']) + register_Ns3TriangularVariable_methods(root_module, root_module['ns3::TriangularVariable']) + register_Ns3GlobalValue_methods(root_module, root_module['ns3::GlobalValue']) + register_Ns3RefCountBase_methods(root_module, root_module['ns3::RefCountBase']) + register_Ns3TypeId_methods(root_module, root_module['ns3::TypeId']) + register_Ns3TypeIdAttributeInfo_methods(root_module, root_module['ns3::TypeId::AttributeInfo']) + register_Ns3SystemWallClockMs_methods(root_module, root_module['ns3::SystemWallClockMs']) + register_Ns3CallbackImplBase_methods(root_module, root_module['ns3::CallbackImplBase']) + register_Ns3TraceSourceAccessor_methods(root_module, root_module['ns3::TraceSourceAccessor']) + register_Ns3AttributeChecker_methods(root_module, root_module['ns3::AttributeChecker']) + register_Ns3RandomVariableChecker_methods(root_module, root_module['ns3::RandomVariableChecker']) + register_Ns3NormalVariable_methods(root_module, root_module['ns3::NormalVariable']) + register_Ns3ObjectFactory_methods(root_module, root_module['ns3::ObjectFactory']) + register_Ns3AttributeAccessor_methods(root_module, root_module['ns3::AttributeAccessor']) + register_Ns3ParetoVariable_methods(root_module, root_module['ns3::ParetoVariable']) + register_Ns3ConstantVariable_methods(root_module, root_module['ns3::ConstantVariable']) + register_Ns3EmpiricalVariable_methods(root_module, root_module['ns3::EmpiricalVariable']) + register_Ns3EnumChecker_methods(root_module, root_module['ns3::EnumChecker']) + register_Ns3Empty_methods(root_module, root_module['ns3::empty']) + register_Ns3ObjectBase_methods(root_module, root_module['ns3::ObjectBase']) + register_Ns3CommandLine_methods(root_module, root_module['ns3::CommandLine']) + register_Ns3IntToType__6_methods(root_module, root_module['ns3::IntToType< 6 >']) + register_Ns3IntToType__5_methods(root_module, root_module['ns3::IntToType< 5 >']) + register_Ns3IntToType__4_methods(root_module, root_module['ns3::IntToType< 4 >']) + register_Ns3IntToType__3_methods(root_module, root_module['ns3::IntToType< 3 >']) + register_Ns3IntToType__2_methods(root_module, root_module['ns3::IntToType< 2 >']) + register_Ns3IntToType__1_methods(root_module, root_module['ns3::IntToType< 1 >']) + register_Ns3IntToType__0_methods(root_module, root_module['ns3::IntToType< 0 >']) + register_Ns3RngStream_methods(root_module, root_module['ns3::RngStream']) + register_Ns3LogNormalVariable_methods(root_module, root_module['ns3::LogNormalVariable']) + register_Ns3IntEmpiricalVariable_methods(root_module, root_module['ns3::IntEmpiricalVariable']) + register_Ns3PointerChecker_methods(root_module, root_module['ns3::PointerChecker']) + register_Ns3WeibullVariable_methods(root_module, root_module['ns3::WeibullVariable']) + register_Ns3CallbackBase_methods(root_module, root_module['ns3::CallbackBase']) + register_Ns3ExponentialVariable_methods(root_module, root_module['ns3::ExponentialVariable']) + register_Ns3TracedCallback__Ns3Ptr__lt__ns3Packet_const__gt___Ns3Mac48Address_Ns3Empty_Ns3Empty_methods(root_module, root_module['ns3::TracedCallback< ns3::Ptr, ns3::Mac48Address, ns3::empty, ns3::empty >']) + register_Ns3TracedCallback__Ns3Ptr__lt__ns3Packet_const__gt___Ns3Empty_Ns3Empty_Ns3Empty_methods(root_module, root_module['ns3::TracedCallback< ns3::Ptr, ns3::empty, ns3::empty, ns3::empty >']) + register_Ns3TracedCallback__Ns3Ptr__lt__ns3Packet_const__gt___Ns3Address_const__amp___Ns3Empty_Ns3Empty_methods(root_module, root_module['ns3::TracedCallback< ns3::Ptr, ns3::Address const&, ns3::empty, ns3::empty >']) + register_Ns3TracedCallback__Ns3Ptr__lt__ns3Packet_const__gt___Unsigned_int_Ns3Empty_Ns3Empty_methods(root_module, root_module['ns3::TracedCallback< ns3::Ptr, unsigned int, ns3::empty, ns3::empty >']) + register_Ns3TracedCallback__Ns3Ptr__lt__ns3MobilityModel_const__gt___Ns3Empty_Ns3Empty_Ns3Empty_methods(root_module, root_module['ns3::TracedCallback< ns3::Ptr, ns3::empty, ns3::empty, ns3::empty >']) + register_Ns3TracedCallback__Ns3TimeUnit__lt__1__gt___Ns3TimeUnit__lt__1__gt___Ns3WifiPhyState_Ns3Empty_methods(root_module, root_module['ns3::TracedCallback< ns3::TimeUnit<1>, ns3::TimeUnit<1>, ns3::WifiPhy::State, ns3::empty >']) + register_Ns3TracedCallback__Ns3Ptr__lt__ns3Packet_const__gt___Ns3WifiMode_Ns3WifiPreamble_Unsigned_char_methods(root_module, root_module['ns3::TracedCallback< ns3::Ptr, ns3::WifiMode, ns3::WifiPreamble, unsigned char >']) + register_Ns3TracedCallback__Ns3Ptr__lt__ns3Packet_const__gt___Double_Ns3Empty_Ns3Empty_methods(root_module, root_module['ns3::TracedCallback< ns3::Ptr, double, ns3::empty, ns3::empty >']) + register_Ns3TracedCallback__Ns3Ptr__lt__ns3Packet_const__gt___Double_Ns3WifiMode_Ns3WifiPreamble_methods(root_module, root_module['ns3::TracedCallback< ns3::Ptr, double, ns3::WifiMode, ns3::WifiPreamble >']) + register_Ns3TracedCallback__Unsigned_int_Unsigned_int_Ns3Empty_Ns3Empty_methods(root_module, root_module['ns3::TracedCallback< unsigned int, unsigned int, ns3::empty, ns3::empty >']) + register_Ns3DeterministicVariable_methods(root_module, root_module['ns3::DeterministicVariable']) + register_Ns3AttributeList_methods(root_module, root_module['ns3::AttributeList']) + register_Ns3AttributeValue_methods(root_module, root_module['ns3::AttributeValue']) + register_Ns3UniformVariable_methods(root_module, root_module['ns3::UniformVariable']) + register_Ns3Object_methods(root_module, root_module['ns3::Object']) + register_Ns3ObjectAggregateIterator_methods(root_module, root_module['ns3::Object::AggregateIterator']) + register_Ns3SequentialVariable_methods(root_module, root_module['ns3::SequentialVariable']) + register_Ns3ObjectVectorChecker_methods(root_module, root_module['ns3::ObjectVectorChecker']) + register_Ns3StringChecker_methods(root_module, root_module['ns3::StringChecker']) + register_Ns3ObjectVectorValue_methods(root_module, root_module['ns3::ObjectVectorValue']) + register_Ns3BooleanChecker_methods(root_module, root_module['ns3::BooleanChecker']) + register_Ns3UintegerValue_methods(root_module, root_module['ns3::UintegerValue']) + register_Ns3ObjectVectorAccessor_methods(root_module, root_module['ns3::ObjectVectorAccessor']) + register_Ns3PointerValue_methods(root_module, root_module['ns3::PointerValue']) + register_Ns3ObjectFactoryChecker_methods(root_module, root_module['ns3::ObjectFactoryChecker']) + register_Ns3TypeIdChecker_methods(root_module, root_module['ns3::TypeIdChecker']) + register_Ns3DoubleValue_methods(root_module, root_module['ns3::DoubleValue']) + register_Ns3StringValue_methods(root_module, root_module['ns3::StringValue']) + register_Ns3TypeIdValue_methods(root_module, root_module['ns3::TypeIdValue']) + register_Ns3EnumValue_methods(root_module, root_module['ns3::EnumValue']) + register_Ns3RandomVariableValue_methods(root_module, root_module['ns3::RandomVariableValue']) + register_Ns3ObjectFactoryValue_methods(root_module, root_module['ns3::ObjectFactoryValue']) + register_Ns3IntegerValue_methods(root_module, root_module['ns3::IntegerValue']) + register_Ns3EmptyAttributeValue_methods(root_module, root_module['ns3::EmptyAttributeValue']) + register_Ns3BooleanValue_methods(root_module, root_module['ns3::BooleanValue']) + register_Ns3TracedValue__Unsigned_int_methods(root_module, root_module['ns3::TracedValue< unsigned int >']) + return + +def register_Ns3RandomVariable_methods(root_module, cls): + ## random-variable.h: ns3::RandomVariable::RandomVariable() [constructor] + cls.add_constructor([], visibility='public') + ## random-variable.h: ns3::RandomVariable::RandomVariable(ns3::RandomVariable const & o) [copy constructor] + cls.add_constructor([param('ns3::RandomVariable&', 'o', is_const=True)], visibility='public') + ## random-variable.h: uint32_t ns3::RandomVariable::GetInteger() const [member function] + cls.add_method('GetInteger', 'uint32_t', [], is_const=True) + ## random-variable.h: void ns3::RandomVariable::GetSeed(uint32_t * seed) const [member function] + cls.add_method('GetSeed', 'void', [param('uint32_t *', 'seed', direction=2, array_length=6)], is_const=True) + ## random-variable.h: double ns3::RandomVariable::GetValue() const [member function] + cls.add_method('GetValue', 'double', [], is_const=True) + ## random-variable.h: static void ns3::RandomVariable::SetRunNumber(uint32_t n) [member function] + cls.add_method('SetRunNumber', 'void', [param('uint32_t', 'n')], is_static=True) + ## random-variable.h: static void ns3::RandomVariable::UseDevRandom(bool udr=true) [member function] + cls.add_method('UseDevRandom', 'void', [param('bool', 'udr', default_value='true')], is_static=True) + ## random-variable.h: static void ns3::RandomVariable::UseGlobalSeed(uint32_t s0, uint32_t s1, uint32_t s2, uint32_t s3, uint32_t s4, uint32_t s5) [member function] + cls.add_method('UseGlobalSeed', 'void', [param('uint32_t', 's0'), param('uint32_t', 's1'), param('uint32_t', 's2'), param('uint32_t', 's3'), param('uint32_t', 's4'), param('uint32_t', 's5')], is_static=True) + cls.add_output_stream_operator() + return + +def register_Ns3TriangularVariable_methods(root_module, cls): + ## random-variable.h: ns3::TriangularVariable::TriangularVariable() [constructor] + cls.add_constructor([], visibility='public') + ## random-variable.h: ns3::TriangularVariable::TriangularVariable(double s, double l, double mean) [constructor] + cls.add_constructor([param('double', 's'), param('double', 'l'), param('double', 'mean')], visibility='public') + ## random-variable.h: static double ns3::TriangularVariable::GetSingleValue(double s, double l, double mean) [member function] + cls.add_method('GetSingleValue', 'double', [param('double', 's'), param('double', 'l'), param('double', 'mean')], is_static=True) + return + +def register_Ns3GlobalValue_methods(root_module, cls): + ## global-value.h: ns3::GlobalValue::GlobalValue(std::string name, std::string help, ns3::AttributeValue const & initialValue, ns3::Ptr checker) [constructor] + cls.add_constructor([param('std::string', 'name'), param('std::string', 'help'), param('ns3::AttributeValue&', 'initialValue', is_const=True), param('ns3::Ptr< ns3::AttributeChecker const >', 'checker')], visibility='public') + ## global-value.h: std::string ns3::GlobalValue::GetName() const [member function] + cls.add_method('GetName', 'std::string', [], is_const=True) + ## global-value.h: std::string ns3::GlobalValue::GetHelp() const [member function] + cls.add_method('GetHelp', 'std::string', [], is_const=True) + ## global-value.h: void ns3::GlobalValue::GetValue(ns3::AttributeValue & value) const [member function] + cls.add_method('GetValue', 'void', [param('ns3::AttributeValue&', 'value')], is_const=True) + ## global-value.h: ns3::Ptr ns3::GlobalValue::GetChecker() const [member function] + cls.add_method('GetChecker', 'ns3::Ptr< ns3::AttributeChecker const >', [], is_const=True) + ## global-value.h: bool ns3::GlobalValue::SetValue(ns3::AttributeValue const & value) [member function] + cls.add_method('SetValue', 'bool', [param('ns3::AttributeValue&', 'value', is_const=True)]) + ## global-value.h: static void ns3::GlobalValue::Bind(std::string name, ns3::AttributeValue const & value) [member function] + cls.add_method('Bind', 'void', [param('std::string', 'name'), param('ns3::AttributeValue&', 'value', is_const=True)], is_static=True) + ## global-value.h: static bool ns3::GlobalValue::BindFailSafe(std::string name, ns3::AttributeValue const & value) [member function] + cls.add_method('BindFailSafe', 'bool', [param('std::string', 'name'), param('ns3::AttributeValue&', 'value', is_const=True)], is_static=True) + ## global-value.h: static __gnu_cxx::__normal_iterator > > ns3::GlobalValue::Begin() [member function] + cls.add_method('Begin', '__gnu_cxx::__normal_iterator< ns3::GlobalValue* const*, std::vector< ns3::GlobalValue*, std::allocator< ns3::GlobalValue* > > >', [], is_static=True) + ## global-value.h: static __gnu_cxx::__normal_iterator > > ns3::GlobalValue::End() [member function] + cls.add_method('End', '__gnu_cxx::__normal_iterator< ns3::GlobalValue* const*, std::vector< ns3::GlobalValue*, std::allocator< ns3::GlobalValue* > > >', [], is_static=True) + return + +def register_Ns3RefCountBase_methods(root_module, cls): + ## ref-count-base.h: ns3::RefCountBase::RefCountBase() [constructor] + cls.add_constructor([], visibility='public') + ## ref-count-base.h: ns3::RefCountBase::RefCountBase(ns3::RefCountBase const & o) [copy constructor] + cls.add_constructor([param('ns3::RefCountBase&', 'o', is_const=True)], visibility='public') + return + +def register_Ns3TypeId_methods(root_module, cls): + ## type-id.h: ns3::TypeId::TypeId(ns3::TypeId const & arg0) [copy constructor] + cls.add_constructor([param('ns3::TypeId&', 'arg0', is_const=True)], visibility='public') + ## type-id.h: ns3::TypeId::TypeId(char const * name) [constructor] + cls.add_constructor([param('char *', 'name', transfer_ownership=False, is_const=True)], visibility='public') + ## type-id.h: ns3::TypeId::TypeId() [constructor] + cls.add_constructor([], visibility='public') + ## type-id.h: ns3::TypeId ns3::TypeId::AddAttribute(std::string name, std::string help, ns3::AttributeValue const & initialValue, ns3::Ptr accessor, ns3::Ptr checker) [member function] + cls.add_method('AddAttribute', 'ns3::TypeId', [param('std::string', 'name'), param('std::string', 'help'), param('ns3::AttributeValue&', 'initialValue', is_const=True), param('ns3::Ptr< ns3::AttributeAccessor const >', 'accessor'), param('ns3::Ptr< ns3::AttributeChecker const >', 'checker')]) + ## type-id.h: ns3::TypeId ns3::TypeId::AddAttribute(std::string name, std::string help, uint32_t flags, ns3::AttributeValue const & initialValue, ns3::Ptr accessor, ns3::Ptr checker) [member function] + cls.add_method('AddAttribute', 'ns3::TypeId', [param('std::string', 'name'), param('std::string', 'help'), param('uint32_t', 'flags'), param('ns3::AttributeValue&', 'initialValue', is_const=True), param('ns3::Ptr< ns3::AttributeAccessor const >', 'accessor'), param('ns3::Ptr< ns3::AttributeChecker const >', 'checker')]) + ## type-id.h: ns3::TypeId ns3::TypeId::AddTraceSource(std::string name, std::string help, ns3::Ptr accessor) [member function] + cls.add_method('AddTraceSource', 'ns3::TypeId', [param('std::string', 'name'), param('std::string', 'help'), param('ns3::Ptr< ns3::TraceSourceAccessor const >', 'accessor')]) + ## type-id.h: ns3::Ptr ns3::TypeId::GetAttributeAccessor(uint32_t i) const [member function] + cls.add_method('GetAttributeAccessor', 'ns3::Ptr< ns3::AttributeAccessor const >', [param('uint32_t', 'i')], is_const=True) + ## type-id.h: ns3::Ptr ns3::TypeId::GetAttributeChecker(uint32_t i) const [member function] + cls.add_method('GetAttributeChecker', 'ns3::Ptr< ns3::AttributeChecker const >', [param('uint32_t', 'i')], is_const=True) + ## type-id.h: uint32_t ns3::TypeId::GetAttributeFlags(uint32_t i) const [member function] + cls.add_method('GetAttributeFlags', 'uint32_t', [param('uint32_t', 'i')], is_const=True) + ## type-id.h: std::string ns3::TypeId::GetAttributeFullName(uint32_t i) const [member function] + cls.add_method('GetAttributeFullName', 'std::string', [param('uint32_t', 'i')], is_const=True) + ## type-id.h: std::string ns3::TypeId::GetAttributeHelp(uint32_t i) const [member function] + cls.add_method('GetAttributeHelp', 'std::string', [param('uint32_t', 'i')], is_const=True) + ## type-id.h: ns3::Ptr ns3::TypeId::GetAttributeInitialValue(uint32_t i) const [member function] + cls.add_method('GetAttributeInitialValue', 'ns3::Ptr< ns3::AttributeValue const >', [param('uint32_t', 'i')], is_const=True) + ## type-id.h: uint32_t ns3::TypeId::GetAttributeN() const [member function] + cls.add_method('GetAttributeN', 'uint32_t', [], is_const=True) + ## type-id.h: std::string ns3::TypeId::GetAttributeName(uint32_t i) const [member function] + cls.add_method('GetAttributeName', 'std::string', [param('uint32_t', 'i')], is_const=True) + ## type-id.h: ns3::Callback ns3::TypeId::GetConstructor() const [member function] + cls.add_method('GetConstructor', 'ns3::Callback< ns3::ObjectBase*, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty >', [], is_const=True) + ## type-id.h: std::string ns3::TypeId::GetGroupName() const [member function] + cls.add_method('GetGroupName', 'std::string', [], is_const=True) + ## type-id.h: std::string ns3::TypeId::GetName() const [member function] + cls.add_method('GetName', 'std::string', [], is_const=True) + ## type-id.h: ns3::TypeId ns3::TypeId::GetParent() const [member function] + cls.add_method('GetParent', 'ns3::TypeId', [], is_const=True) + ## type-id.h: static ns3::TypeId ns3::TypeId::GetRegistered(uint32_t i) [member function] + cls.add_method('GetRegistered', 'ns3::TypeId', [param('uint32_t', 'i')], is_static=True) + ## type-id.h: static uint32_t ns3::TypeId::GetRegisteredN() [member function] + cls.add_method('GetRegisteredN', 'uint32_t', [], is_static=True) + ## type-id.h: ns3::Ptr ns3::TypeId::GetTraceSourceAccessor(uint32_t i) const [member function] + cls.add_method('GetTraceSourceAccessor', 'ns3::Ptr< ns3::TraceSourceAccessor const >', [param('uint32_t', 'i')], is_const=True) + ## type-id.h: std::string ns3::TypeId::GetTraceSourceHelp(uint32_t i) const [member function] + cls.add_method('GetTraceSourceHelp', 'std::string', [param('uint32_t', 'i')], is_const=True) + ## type-id.h: uint32_t ns3::TypeId::GetTraceSourceN() const [member function] + cls.add_method('GetTraceSourceN', 'uint32_t', [], is_const=True) + ## type-id.h: std::string ns3::TypeId::GetTraceSourceName(uint32_t i) const [member function] + cls.add_method('GetTraceSourceName', 'std::string', [param('uint32_t', 'i')], is_const=True) + ## type-id.h: uint16_t ns3::TypeId::GetUid() const [member function] + cls.add_method('GetUid', 'uint16_t', [], is_const=True) + ## type-id.h: bool ns3::TypeId::HasConstructor() const [member function] + cls.add_method('HasConstructor', 'bool', [], is_const=True) + ## type-id.h: bool ns3::TypeId::HasParent() const [member function] + cls.add_method('HasParent', 'bool', [], is_const=True) + ## type-id.h: ns3::TypeId ns3::TypeId::HideFromDocumentation() [member function] + cls.add_method('HideFromDocumentation', 'ns3::TypeId', []) + ## type-id.h: bool ns3::TypeId::IsChildOf(ns3::TypeId other) const [member function] + cls.add_method('IsChildOf', 'bool', [param('ns3::TypeId', 'other')], is_const=True) + ## type-id.h: bool ns3::TypeId::LookupAttributeByName(std::string name, ns3::TypeId::AttributeInfo * info) const [member function] + cls.add_method('LookupAttributeByName', 'bool', [param('std::string', 'name'), param('ns3::TypeId::AttributeInfo *', 'info', transfer_ownership=False)], is_const=True) + ## type-id.h: static ns3::TypeId ns3::TypeId::LookupByName(std::string name) [member function] + cls.add_method('LookupByName', 'ns3::TypeId', [param('std::string', 'name')], is_static=True) + ## type-id.h: static bool ns3::TypeId::LookupByNameFailSafe(std::string name, ns3::TypeId * tid) [member function] + cls.add_method('LookupByNameFailSafe', 'bool', [param('std::string', 'name'), param('ns3::TypeId *', 'tid', transfer_ownership=False)], is_static=True) + ## type-id.h: ns3::Ptr ns3::TypeId::LookupTraceSourceByName(std::string name) const [member function] + cls.add_method('LookupTraceSourceByName', 'ns3::Ptr< ns3::TraceSourceAccessor const >', [param('std::string', 'name')], is_const=True) + ## type-id.h: bool ns3::TypeId::MustHideFromDocumentation() const [member function] + cls.add_method('MustHideFromDocumentation', 'bool', [], is_const=True) + ## type-id.h: ns3::TypeId ns3::TypeId::SetGroupName(std::string groupName) [member function] + cls.add_method('SetGroupName', 'ns3::TypeId', [param('std::string', 'groupName')]) + ## type-id.h: ns3::TypeId ns3::TypeId::SetParent(ns3::TypeId tid) [member function] + cls.add_method('SetParent', 'ns3::TypeId', [param('ns3::TypeId', 'tid')]) + ## type-id.h: void ns3::TypeId::SetUid(uint16_t tid) [member function] + cls.add_method('SetUid', 'void', [param('uint16_t', 'tid')]) + cls.add_output_stream_operator() + return + +def register_Ns3TypeIdAttributeInfo_methods(root_module, cls): + ## type-id.h: ns3::TypeId::AttributeInfo::accessor [variable] + cls.add_instance_attribute('accessor', 'ns3::Ptr< ns3::AttributeAccessor const >', is_const=False) + ## type-id.h: ns3::TypeId::AttributeInfo::initialValue [variable] + cls.add_instance_attribute('initialValue', 'ns3::Ptr< ns3::AttributeValue const >', is_const=False) + ## type-id.h: ns3::TypeId::AttributeInfo::flags [variable] + cls.add_instance_attribute('flags', 'uint32_t', is_const=False) + ## type-id.h: ns3::TypeId::AttributeInfo::checker [variable] + cls.add_instance_attribute('checker', 'ns3::Ptr< ns3::AttributeChecker const >', is_const=False) + cls.add_constructor([]) + return + +def register_Ns3SystemWallClockMs_methods(root_module, cls): + ## system-wall-clock-ms.h: ns3::SystemWallClockMs::SystemWallClockMs() [constructor] + cls.add_constructor([], visibility='public') + ## system-wall-clock-ms.h: void ns3::SystemWallClockMs::Start() [member function] + cls.add_method('Start', 'void', []) + ## system-wall-clock-ms.h: long long unsigned int ns3::SystemWallClockMs::End() [member function] + cls.add_method('End', 'long long unsigned int', []) + return + +def register_Ns3CallbackImplBase_methods(root_module, cls): + ## callback.h: ns3::CallbackImplBase::CallbackImplBase() [constructor] + cls.add_constructor([], visibility='public') + ## callback.h: bool ns3::CallbackImplBase::IsEqual(ns3::Ptr other) const [member function] + cls.add_method('IsEqual', 'bool', [param('ns3::Ptr< ns3::CallbackImplBase const >', 'other')], is_pure_virtual=True, is_const=True, is_virtual=True) + return + +def register_Ns3TraceSourceAccessor_methods(root_module, cls): + ## trace-source-accessor.h: ns3::TraceSourceAccessor::TraceSourceAccessor() [constructor] + cls.add_constructor([], visibility='public') + ## trace-source-accessor.h: void ns3::TraceSourceAccessor::Ref() const [member function] + cls.add_method('Ref', 'void', [], is_const=True) + ## trace-source-accessor.h: void ns3::TraceSourceAccessor::Unref() const [member function] + cls.add_method('Unref', 'void', [], is_const=True) + ## trace-source-accessor.h: bool ns3::TraceSourceAccessor::ConnectWithoutContext(ns3::ObjectBase * obj, ns3::CallbackBase const & cb) const [member function] + cls.add_method('ConnectWithoutContext', 'bool', [param('ns3::ObjectBase *', 'obj', transfer_ownership=False), param('ns3::CallbackBase&', 'cb', is_const=True)], is_pure_virtual=True, is_const=True, is_virtual=True) + ## trace-source-accessor.h: bool ns3::TraceSourceAccessor::Connect(ns3::ObjectBase * obj, std::string context, ns3::CallbackBase const & cb) const [member function] + cls.add_method('Connect', 'bool', [param('ns3::ObjectBase *', 'obj', transfer_ownership=False), param('std::string', 'context'), param('ns3::CallbackBase&', 'cb', is_const=True)], is_pure_virtual=True, is_const=True, is_virtual=True) + ## trace-source-accessor.h: bool ns3::TraceSourceAccessor::DisconnectWithoutContext(ns3::ObjectBase * obj, ns3::CallbackBase const & cb) const [member function] + cls.add_method('DisconnectWithoutContext', 'bool', [param('ns3::ObjectBase *', 'obj', transfer_ownership=False), param('ns3::CallbackBase&', 'cb', is_const=True)], is_pure_virtual=True, is_const=True, is_virtual=True) + ## trace-source-accessor.h: bool ns3::TraceSourceAccessor::Disconnect(ns3::ObjectBase * obj, std::string context, ns3::CallbackBase const & cb) const [member function] + cls.add_method('Disconnect', 'bool', [param('ns3::ObjectBase *', 'obj', transfer_ownership=False), param('std::string', 'context'), param('ns3::CallbackBase&', 'cb', is_const=True)], is_pure_virtual=True, is_const=True, is_virtual=True) + return + +def register_Ns3AttributeChecker_methods(root_module, cls): + ## attribute.h: ns3::AttributeChecker::AttributeChecker() [constructor] + cls.add_constructor([], visibility='public') + ## attribute.h: bool ns3::AttributeChecker::Check(ns3::AttributeValue const & value) const [member function] + cls.add_method('Check', 'bool', [param('ns3::AttributeValue&', 'value', is_const=True)], is_pure_virtual=True, is_const=True, is_virtual=True) + ## attribute.h: std::string ns3::AttributeChecker::GetValueTypeName() const [member function] + cls.add_method('GetValueTypeName', 'std::string', [], is_pure_virtual=True, is_const=True, is_virtual=True) + ## attribute.h: bool ns3::AttributeChecker::HasUnderlyingTypeInformation() const [member function] + cls.add_method('HasUnderlyingTypeInformation', 'bool', [], is_pure_virtual=True, is_const=True, is_virtual=True) + ## attribute.h: std::string ns3::AttributeChecker::GetUnderlyingTypeInformation() const [member function] + cls.add_method('GetUnderlyingTypeInformation', 'std::string', [], is_pure_virtual=True, is_const=True, is_virtual=True) + ## attribute.h: ns3::Ptr ns3::AttributeChecker::Create() const [member function] + cls.add_method('Create', 'ns3::Ptr< ns3::AttributeValue >', [], is_pure_virtual=True, is_const=True, is_virtual=True) + ## attribute.h: bool ns3::AttributeChecker::Copy(ns3::AttributeValue const & source, ns3::AttributeValue & destination) const [member function] + cls.add_method('Copy', 'bool', [param('ns3::AttributeValue&', 'source', is_const=True), param('ns3::AttributeValue&', 'destination')], is_pure_virtual=True, is_const=True, is_virtual=True) + return + +def register_Ns3RandomVariableChecker_methods(root_module, cls): + cls.add_constructor([]) + return + +def register_Ns3NormalVariable_methods(root_module, cls): + ## random-variable.h: ns3::NormalVariable::NormalVariable() [constructor] + cls.add_constructor([], visibility='public') + ## random-variable.h: ns3::NormalVariable::NormalVariable(double m, double v) [constructor] + cls.add_constructor([param('double', 'm'), param('double', 'v')], visibility='public') + ## random-variable.h: ns3::NormalVariable::NormalVariable(double m, double v, double b) [constructor] + cls.add_constructor([param('double', 'm'), param('double', 'v'), param('double', 'b')], visibility='public') + ## random-variable.h: static double ns3::NormalVariable::GetSingleValue(double m, double v) [member function] + cls.add_method('GetSingleValue', 'double', [param('double', 'm'), param('double', 'v')], is_static=True) + ## random-variable.h: static double ns3::NormalVariable::GetSingleValue(double m, double v, double b) [member function] + cls.add_method('GetSingleValue', 'double', [param('double', 'm'), param('double', 'v'), param('double', 'b')], is_static=True) + return + +def register_Ns3ObjectFactory_methods(root_module, cls): + ## object-factory.h: ns3::ObjectFactory::ObjectFactory(ns3::ObjectFactory const & arg0) [copy constructor] + cls.add_constructor([param('ns3::ObjectFactory&', 'arg0', is_const=True)], visibility='public') + ## object-factory.h: ns3::ObjectFactory::ObjectFactory() [constructor] + cls.add_constructor([], visibility='public') + ## object-factory.h: ns3::Ptr ns3::ObjectFactory::Create() const [member function] + cls.add_method('Create', 'ns3::Ptr< ns3::Object >', [], is_const=True) + ## object-factory.h: ns3::TypeId ns3::ObjectFactory::GetTypeId() const [member function] + cls.add_method('GetTypeId', 'ns3::TypeId', [], is_const=True) + ## object-factory.h: void ns3::ObjectFactory::Set(std::string name, ns3::AttributeValue const & value) [member function] + cls.add_method('Set', 'void', [param('std::string', 'name'), param('ns3::AttributeValue&', 'value', is_const=True)]) + ## object-factory.h: void ns3::ObjectFactory::SetTypeId(ns3::TypeId tid) [member function] + cls.add_method('SetTypeId', 'void', [param('ns3::TypeId', 'tid')]) + ## object-factory.h: void ns3::ObjectFactory::SetTypeId(char const * tid) [member function] + cls.add_method('SetTypeId', 'void', [param('char *', 'tid', transfer_ownership=False, is_const=True)]) + ## object-factory.h: void ns3::ObjectFactory::SetTypeId(std::string tid) [member function] + cls.add_method('SetTypeId', 'void', [param('std::string', 'tid')]) + cls.add_output_stream_operator() + return + +def register_Ns3AttributeAccessor_methods(root_module, cls): + ## attribute.h: ns3::AttributeAccessor::AttributeAccessor() [constructor] + cls.add_constructor([], visibility='public') + ## attribute.h: bool ns3::AttributeAccessor::Set(ns3::ObjectBase * object, ns3::AttributeValue const & value) const [member function] + cls.add_method('Set', 'bool', [param('ns3::ObjectBase *', 'object', transfer_ownership=False), param('ns3::AttributeValue&', 'value', is_const=True)], is_pure_virtual=True, is_const=True, is_virtual=True) + ## attribute.h: bool ns3::AttributeAccessor::Get(ns3::ObjectBase const * object, ns3::AttributeValue & attribute) const [member function] + cls.add_method('Get', 'bool', [param('ns3::ObjectBase *', 'object', transfer_ownership=False, is_const=True), param('ns3::AttributeValue&', 'attribute')], is_pure_virtual=True, is_const=True, is_virtual=True) + ## attribute.h: bool ns3::AttributeAccessor::HasGetter() const [member function] + cls.add_method('HasGetter', 'bool', [], is_pure_virtual=True, is_const=True, is_virtual=True) + ## attribute.h: bool ns3::AttributeAccessor::HasSetter() const [member function] + cls.add_method('HasSetter', 'bool', [], is_pure_virtual=True, is_const=True, is_virtual=True) + return + +def register_Ns3ParetoVariable_methods(root_module, cls): + ## random-variable.h: ns3::ParetoVariable::ParetoVariable() [constructor] + cls.add_constructor([], visibility='public') + ## random-variable.h: ns3::ParetoVariable::ParetoVariable(double m) [constructor] + cls.add_constructor([param('double', 'm')], visibility='public') + ## random-variable.h: ns3::ParetoVariable::ParetoVariable(double m, double s) [constructor] + cls.add_constructor([param('double', 'm'), param('double', 's')], visibility='public') + ## random-variable.h: ns3::ParetoVariable::ParetoVariable(double m, double s, double b) [constructor] + cls.add_constructor([param('double', 'm'), param('double', 's'), param('double', 'b')], visibility='public') + ## random-variable.h: static double ns3::ParetoVariable::GetSingleValue(double m, double s, double b=0) [member function] + cls.add_method('GetSingleValue', 'double', [param('double', 'm'), param('double', 's'), param('double', 'b', default_value='0')], is_static=True) + return + +def register_Ns3ConstantVariable_methods(root_module, cls): + ## random-variable.h: ns3::ConstantVariable::ConstantVariable() [constructor] + cls.add_constructor([], visibility='public') + ## random-variable.h: ns3::ConstantVariable::ConstantVariable(double c) [constructor] + cls.add_constructor([param('double', 'c')], visibility='public') + ## random-variable.h: void ns3::ConstantVariable::SetConstant(double c) [member function] + cls.add_method('SetConstant', 'void', [param('double', 'c')]) + return + +def register_Ns3EmpiricalVariable_methods(root_module, cls): + ## random-variable.h: ns3::EmpiricalVariable::EmpiricalVariable() [constructor] + cls.add_constructor([], visibility='public') + ## random-variable.h: void ns3::EmpiricalVariable::CDF(double v, double c) [member function] + cls.add_method('CDF', 'void', [param('double', 'v'), param('double', 'c')]) + return + +def register_Ns3EnumChecker_methods(root_module, cls): + ## enum.h: ns3::EnumChecker::EnumChecker() [constructor] + cls.add_constructor([], visibility='public') + ## enum.h: void ns3::EnumChecker::AddDefault(int v, std::string name) [member function] + cls.add_method('AddDefault', 'void', [param('int', 'v'), param('std::string', 'name')]) + ## enum.h: void ns3::EnumChecker::Add(int v, std::string name) [member function] + cls.add_method('Add', 'void', [param('int', 'v'), param('std::string', 'name')]) + ## enum.h: bool ns3::EnumChecker::Check(ns3::AttributeValue const & value) const [member function] + cls.add_method('Check', 'bool', [param('ns3::AttributeValue&', 'value', is_const=True)], is_const=True, is_virtual=True) + ## enum.h: std::string ns3::EnumChecker::GetValueTypeName() const [member function] + cls.add_method('GetValueTypeName', 'std::string', [], is_const=True, is_virtual=True) + ## enum.h: bool ns3::EnumChecker::HasUnderlyingTypeInformation() const [member function] + cls.add_method('HasUnderlyingTypeInformation', 'bool', [], is_const=True, is_virtual=True) + ## enum.h: std::string ns3::EnumChecker::GetUnderlyingTypeInformation() const [member function] + cls.add_method('GetUnderlyingTypeInformation', 'std::string', [], is_const=True, is_virtual=True) + ## enum.h: ns3::Ptr ns3::EnumChecker::Create() const [member function] + cls.add_method('Create', 'ns3::Ptr< ns3::AttributeValue >', [], is_const=True, is_virtual=True) + ## enum.h: bool ns3::EnumChecker::Copy(ns3::AttributeValue const & src, ns3::AttributeValue & dst) const [member function] + cls.add_method('Copy', 'bool', [param('ns3::AttributeValue&', 'src', is_const=True), param('ns3::AttributeValue&', 'dst')], is_const=True, is_virtual=True) + return + +def register_Ns3Empty_methods(root_module, cls): + cls.add_constructor([]) + return + +def register_Ns3ObjectBase_methods(root_module, cls): + ## object-base.h: ns3::ObjectBase::ObjectBase() [constructor] + cls.add_constructor([], visibility='public') + ## object-base.h: ns3::ObjectBase::ObjectBase(ns3::ObjectBase const & arg0) [copy constructor] + cls.add_constructor([param('ns3::ObjectBase&', 'arg0', is_const=True)], visibility='public') + ## object-base.h: static ns3::TypeId ns3::ObjectBase::GetTypeId() [member function] + cls.add_method('GetTypeId', 'ns3::TypeId', [], is_static=True) + ## object-base.h: ns3::TypeId ns3::ObjectBase::GetInstanceTypeId() const [member function] + cls.add_method('GetInstanceTypeId', 'ns3::TypeId', [], is_pure_virtual=True, is_const=True, is_virtual=True) + ## object-base.h: void ns3::ObjectBase::SetAttribute(std::string name, ns3::AttributeValue const & value) [member function] + cls.add_method('SetAttribute', 'void', [param('std::string', 'name'), param('ns3::AttributeValue&', 'value', is_const=True)]) + ## object-base.h: bool ns3::ObjectBase::SetAttributeFailSafe(std::string name, ns3::AttributeValue const & value) [member function] + cls.add_method('SetAttributeFailSafe', 'bool', [param('std::string', 'name'), param('ns3::AttributeValue&', 'value', is_const=True)]) + ## object-base.h: void ns3::ObjectBase::GetAttribute(std::string name, ns3::AttributeValue & value) const [member function] + cls.add_method('GetAttribute', 'void', [param('std::string', 'name'), param('ns3::AttributeValue&', 'value')], is_const=True) + ## object-base.h: bool ns3::ObjectBase::GetAttributeFailSafe(std::string name, ns3::AttributeValue & attribute) const [member function] + cls.add_method('GetAttributeFailSafe', 'bool', [param('std::string', 'name'), param('ns3::AttributeValue&', 'attribute')], is_const=True) + ## object-base.h: bool ns3::ObjectBase::TraceConnect(std::string name, std::string context, ns3::CallbackBase const & cb) [member function] + cls.add_method('TraceConnect', 'bool', [param('std::string', 'name'), param('std::string', 'context'), param('ns3::CallbackBase&', 'cb', is_const=True)]) + ## object-base.h: bool ns3::ObjectBase::TraceConnectWithoutContext(std::string name, ns3::CallbackBase const & cb) [member function] + cls.add_method('TraceConnectWithoutContext', 'bool', [param('std::string', 'name'), param('ns3::CallbackBase&', 'cb', is_const=True)]) + ## object-base.h: bool ns3::ObjectBase::TraceDisconnect(std::string name, std::string context, ns3::CallbackBase const & cb) [member function] + cls.add_method('TraceDisconnect', 'bool', [param('std::string', 'name'), param('std::string', 'context'), param('ns3::CallbackBase&', 'cb', is_const=True)]) + ## object-base.h: bool ns3::ObjectBase::TraceDisconnectWithoutContext(std::string name, ns3::CallbackBase const & cb) [member function] + cls.add_method('TraceDisconnectWithoutContext', 'bool', [param('std::string', 'name'), param('ns3::CallbackBase&', 'cb', is_const=True)]) + ## object-base.h: void ns3::ObjectBase::NotifyConstructionCompleted() [member function] + cls.add_method('NotifyConstructionCompleted', 'void', [], visibility='protected', is_virtual=True) + ## object-base.h: void ns3::ObjectBase::ConstructSelf(ns3::AttributeList const & attributes) [member function] + cls.add_method('ConstructSelf', 'void', [param('ns3::AttributeList&', 'attributes', is_const=True)], visibility='protected') + return + +def register_Ns3CommandLine_methods(root_module, cls): + cls.add_constructor([]) + return + +def register_Ns3IntToType__6_methods(root_module, cls): + cls.add_constructor([]) + return + +def register_Ns3IntToType__5_methods(root_module, cls): + cls.add_constructor([]) + return + +def register_Ns3IntToType__4_methods(root_module, cls): + cls.add_constructor([]) + return + +def register_Ns3IntToType__3_methods(root_module, cls): + cls.add_constructor([]) + return + +def register_Ns3IntToType__2_methods(root_module, cls): + cls.add_constructor([]) + return + +def register_Ns3IntToType__1_methods(root_module, cls): + cls.add_constructor([]) + return + +def register_Ns3IntToType__0_methods(root_module, cls): + cls.add_constructor([]) + return + +def register_Ns3RngStream_methods(root_module, cls): + ## rng-stream.h: ns3::RngStream::RngStream() [constructor] + cls.add_constructor([], visibility='public') + ## rng-stream.h: ns3::RngStream::RngStream(ns3::RngStream const & arg0) [copy constructor] + cls.add_constructor([param('ns3::RngStream&', 'arg0', is_const=True)], visibility='public') + ## rng-stream.h: void ns3::RngStream::InitializeStream() [member function] + cls.add_method('InitializeStream', 'void', []) + ## rng-stream.h: void ns3::RngStream::ResetStartStream() [member function] + cls.add_method('ResetStartStream', 'void', []) + ## rng-stream.h: void ns3::RngStream::ResetStartSubstream() [member function] + cls.add_method('ResetStartSubstream', 'void', []) + ## rng-stream.h: void ns3::RngStream::ResetNextSubstream() [member function] + cls.add_method('ResetNextSubstream', 'void', []) + ## rng-stream.h: void ns3::RngStream::ResetNthSubstream(uint32_t N) [member function] + cls.add_method('ResetNthSubstream', 'void', [param('uint32_t', 'N')]) + ## rng-stream.h: void ns3::RngStream::SetAntithetic(bool a) [member function] + cls.add_method('SetAntithetic', 'void', [param('bool', 'a')]) + ## rng-stream.h: void ns3::RngStream::IncreasedPrecis(bool incp) [member function] + cls.add_method('IncreasedPrecis', 'void', [param('bool', 'incp')]) + ## rng-stream.h: bool ns3::RngStream::SetSeeds(uint32_t const * seed) [member function] + cls.add_method('SetSeeds', 'bool', [param('uint32_t *', 'seed', transfer_ownership=False, is_const=True)]) + ## rng-stream.h: void ns3::RngStream::AdvanceState(int32_t e, int32_t c) [member function] + cls.add_method('AdvanceState', 'void', [param('int32_t', 'e'), param('int32_t', 'c')]) + ## rng-stream.h: void ns3::RngStream::GetState(uint32_t * seed) const [member function] + cls.add_method('GetState', 'void', [param('uint32_t *', 'seed')], is_const=True) + ## rng-stream.h: double ns3::RngStream::RandU01() [member function] + cls.add_method('RandU01', 'double', []) + ## rng-stream.h: int32_t ns3::RngStream::RandInt(int32_t i, int32_t j) [member function] + cls.add_method('RandInt', 'int32_t', [param('int32_t', 'i'), param('int32_t', 'j')]) + ## rng-stream.h: static bool ns3::RngStream::SetPackageSeed(uint32_t const * seed) [member function] + cls.add_method('SetPackageSeed', 'bool', [param('uint32_t *', 'seed', transfer_ownership=False, is_const=True)], is_static=True) + ## rng-stream.h: static bool ns3::RngStream::CheckSeed(uint32_t const * seed) [member function] + cls.add_method('CheckSeed', 'bool', [param('uint32_t *', 'seed', transfer_ownership=False, is_const=True)], is_static=True) + return + +def register_Ns3LogNormalVariable_methods(root_module, cls): + ## random-variable.h: ns3::LogNormalVariable::LogNormalVariable(double mu, double sigma) [constructor] + cls.add_constructor([param('double', 'mu'), param('double', 'sigma')], visibility='public') + ## random-variable.h: static double ns3::LogNormalVariable::GetSingleValue(double mu, double sigma) [member function] + cls.add_method('GetSingleValue', 'double', [param('double', 'mu'), param('double', 'sigma')], is_static=True) + return + +def register_Ns3IntEmpiricalVariable_methods(root_module, cls): + ## random-variable.h: ns3::IntEmpiricalVariable::IntEmpiricalVariable() [constructor] + cls.add_constructor([], visibility='public') + return + +def register_Ns3PointerChecker_methods(root_module, cls): + ## pointer.h: ns3::TypeId ns3::PointerChecker::GetPointeeTypeId() const [member function] + cls.add_method('GetPointeeTypeId', 'ns3::TypeId', [], is_pure_virtual=True, is_const=True, is_virtual=True) + cls.add_constructor([]) + return + +def register_Ns3WeibullVariable_methods(root_module, cls): + ## random-variable.h: ns3::WeibullVariable::WeibullVariable() [constructor] + cls.add_constructor([], visibility='public') + ## random-variable.h: ns3::WeibullVariable::WeibullVariable(double m) [constructor] + cls.add_constructor([param('double', 'm')], visibility='public') + ## random-variable.h: ns3::WeibullVariable::WeibullVariable(double m, double s) [constructor] + cls.add_constructor([param('double', 'm'), param('double', 's')], visibility='public') + ## random-variable.h: ns3::WeibullVariable::WeibullVariable(double m, double s, double b) [constructor] + cls.add_constructor([param('double', 'm'), param('double', 's'), param('double', 'b')], visibility='public') + ## random-variable.h: static double ns3::WeibullVariable::GetSingleValue(double m, double s, double b=0) [member function] + cls.add_method('GetSingleValue', 'double', [param('double', 'm'), param('double', 's'), param('double', 'b', default_value='0')], is_static=True) + return + +def register_Ns3CallbackBase_methods(root_module, cls): + ## callback.h: ns3::CallbackBase::CallbackBase() [constructor] + cls.add_constructor([], visibility='public') + ## callback.h: ns3::Ptr ns3::CallbackBase::GetImpl() const [member function] + cls.add_method('GetImpl', 'ns3::Ptr< ns3::CallbackImplBase >', [], is_const=True) + ## callback.h: ns3::CallbackBase::CallbackBase(ns3::Ptr impl) [constructor] + cls.add_constructor([param('ns3::Ptr< ns3::CallbackImplBase >', 'impl')], visibility='protected') + return + +def register_Ns3ExponentialVariable_methods(root_module, cls): + ## random-variable.h: ns3::ExponentialVariable::ExponentialVariable() [constructor] + cls.add_constructor([], visibility='public') + ## random-variable.h: ns3::ExponentialVariable::ExponentialVariable(double m) [constructor] + cls.add_constructor([param('double', 'm')], visibility='public') + ## random-variable.h: ns3::ExponentialVariable::ExponentialVariable(double m, double b) [constructor] + cls.add_constructor([param('double', 'm'), param('double', 'b')], visibility='public') + ## random-variable.h: static double ns3::ExponentialVariable::GetSingleValue(double m, double b=0) [member function] + cls.add_method('GetSingleValue', 'double', [param('double', 'm'), param('double', 'b', default_value='0')], is_static=True) + return + +def register_Ns3TracedCallback__Ns3Ptr__lt__ns3Packet_const__gt___Ns3Mac48Address_Ns3Empty_Ns3Empty_methods(root_module, cls): + ## traced-callback.h: ns3::TracedCallback, ns3::Mac48Address, ns3::empty, ns3::empty>::TracedCallback() [constructor] + cls.add_constructor([], visibility='public') + ## traced-callback.h: void ns3::TracedCallback, ns3::Mac48Address, ns3::empty, ns3::empty>::ConnectWithoutContext(ns3::CallbackBase const & callback) [member function] + cls.add_method('ConnectWithoutContext', 'void', [param('ns3::CallbackBase&', 'callback', is_const=True)]) + ## traced-callback.h: void ns3::TracedCallback, ns3::Mac48Address, ns3::empty, ns3::empty>::Connect(ns3::CallbackBase const & callback, std::string path) [member function] + cls.add_method('Connect', 'void', [param('ns3::CallbackBase&', 'callback', is_const=True), param('std::string', 'path')]) + ## traced-callback.h: void ns3::TracedCallback, ns3::Mac48Address, ns3::empty, ns3::empty>::DisconnectWithoutContext(ns3::CallbackBase const & callback) [member function] + cls.add_method('DisconnectWithoutContext', 'void', [param('ns3::CallbackBase&', 'callback', is_const=True)]) + ## traced-callback.h: void ns3::TracedCallback, ns3::Mac48Address, ns3::empty, ns3::empty>::Disconnect(ns3::CallbackBase const & callback, std::string path) [member function] + cls.add_method('Disconnect', 'void', [param('ns3::CallbackBase&', 'callback', is_const=True), param('std::string', 'path')]) + return + +def register_Ns3TracedCallback__Ns3Ptr__lt__ns3Packet_const__gt___Ns3Empty_Ns3Empty_Ns3Empty_methods(root_module, cls): + ## traced-callback.h: ns3::TracedCallback, ns3::empty, ns3::empty, ns3::empty>::TracedCallback() [constructor] + cls.add_constructor([], visibility='public') + ## traced-callback.h: void ns3::TracedCallback, ns3::empty, ns3::empty, ns3::empty>::ConnectWithoutContext(ns3::CallbackBase const & callback) [member function] + cls.add_method('ConnectWithoutContext', 'void', [param('ns3::CallbackBase&', 'callback', is_const=True)]) + ## traced-callback.h: void ns3::TracedCallback, ns3::empty, ns3::empty, ns3::empty>::Connect(ns3::CallbackBase const & callback, std::string path) [member function] + cls.add_method('Connect', 'void', [param('ns3::CallbackBase&', 'callback', is_const=True), param('std::string', 'path')]) + ## traced-callback.h: void ns3::TracedCallback, ns3::empty, ns3::empty, ns3::empty>::DisconnectWithoutContext(ns3::CallbackBase const & callback) [member function] + cls.add_method('DisconnectWithoutContext', 'void', [param('ns3::CallbackBase&', 'callback', is_const=True)]) + ## traced-callback.h: void ns3::TracedCallback, ns3::empty, ns3::empty, ns3::empty>::Disconnect(ns3::CallbackBase const & callback, std::string path) [member function] + cls.add_method('Disconnect', 'void', [param('ns3::CallbackBase&', 'callback', is_const=True), param('std::string', 'path')]) + return + +def register_Ns3TracedCallback__Ns3Ptr__lt__ns3Packet_const__gt___Ns3Address_const__amp___Ns3Empty_Ns3Empty_methods(root_module, cls): + ## traced-callback.h: ns3::TracedCallback, ns3::Address const&, ns3::empty, ns3::empty>::TracedCallback() [constructor] + cls.add_constructor([], visibility='public') + ## traced-callback.h: void ns3::TracedCallback, ns3::Address const&, ns3::empty, ns3::empty>::ConnectWithoutContext(ns3::CallbackBase const & callback) [member function] + cls.add_method('ConnectWithoutContext', 'void', [param('ns3::CallbackBase&', 'callback', is_const=True)]) + ## traced-callback.h: void ns3::TracedCallback, ns3::Address const&, ns3::empty, ns3::empty>::Connect(ns3::CallbackBase const & callback, std::string path) [member function] + cls.add_method('Connect', 'void', [param('ns3::CallbackBase&', 'callback', is_const=True), param('std::string', 'path')]) + ## traced-callback.h: void ns3::TracedCallback, ns3::Address const&, ns3::empty, ns3::empty>::DisconnectWithoutContext(ns3::CallbackBase const & callback) [member function] + cls.add_method('DisconnectWithoutContext', 'void', [param('ns3::CallbackBase&', 'callback', is_const=True)]) + ## traced-callback.h: void ns3::TracedCallback, ns3::Address const&, ns3::empty, ns3::empty>::Disconnect(ns3::CallbackBase const & callback, std::string path) [member function] + cls.add_method('Disconnect', 'void', [param('ns3::CallbackBase&', 'callback', is_const=True), param('std::string', 'path')]) + return + +def register_Ns3TracedCallback__Ns3Ptr__lt__ns3Packet_const__gt___Unsigned_int_Ns3Empty_Ns3Empty_methods(root_module, cls): + ## traced-callback.h: ns3::TracedCallback, unsigned int, ns3::empty, ns3::empty>::TracedCallback() [constructor] + cls.add_constructor([], visibility='public') + ## traced-callback.h: void ns3::TracedCallback, unsigned int, ns3::empty, ns3::empty>::ConnectWithoutContext(ns3::CallbackBase const & callback) [member function] + cls.add_method('ConnectWithoutContext', 'void', [param('ns3::CallbackBase&', 'callback', is_const=True)]) + ## traced-callback.h: void ns3::TracedCallback, unsigned int, ns3::empty, ns3::empty>::Connect(ns3::CallbackBase const & callback, std::string path) [member function] + cls.add_method('Connect', 'void', [param('ns3::CallbackBase&', 'callback', is_const=True), param('std::string', 'path')]) + ## traced-callback.h: void ns3::TracedCallback, unsigned int, ns3::empty, ns3::empty>::DisconnectWithoutContext(ns3::CallbackBase const & callback) [member function] + cls.add_method('DisconnectWithoutContext', 'void', [param('ns3::CallbackBase&', 'callback', is_const=True)]) + ## traced-callback.h: void ns3::TracedCallback, unsigned int, ns3::empty, ns3::empty>::Disconnect(ns3::CallbackBase const & callback, std::string path) [member function] + cls.add_method('Disconnect', 'void', [param('ns3::CallbackBase&', 'callback', is_const=True), param('std::string', 'path')]) + return + +def register_Ns3TracedCallback__Ns3Ptr__lt__ns3MobilityModel_const__gt___Ns3Empty_Ns3Empty_Ns3Empty_methods(root_module, cls): + ## traced-callback.h: ns3::TracedCallback, ns3::empty, ns3::empty, ns3::empty>::TracedCallback() [constructor] + cls.add_constructor([], visibility='public') + ## traced-callback.h: void ns3::TracedCallback, ns3::empty, ns3::empty, ns3::empty>::ConnectWithoutContext(ns3::CallbackBase const & callback) [member function] + cls.add_method('ConnectWithoutContext', 'void', [param('ns3::CallbackBase&', 'callback', is_const=True)]) + ## traced-callback.h: void ns3::TracedCallback, ns3::empty, ns3::empty, ns3::empty>::Connect(ns3::CallbackBase const & callback, std::string path) [member function] + cls.add_method('Connect', 'void', [param('ns3::CallbackBase&', 'callback', is_const=True), param('std::string', 'path')]) + ## traced-callback.h: void ns3::TracedCallback, ns3::empty, ns3::empty, ns3::empty>::DisconnectWithoutContext(ns3::CallbackBase const & callback) [member function] + cls.add_method('DisconnectWithoutContext', 'void', [param('ns3::CallbackBase&', 'callback', is_const=True)]) + ## traced-callback.h: void ns3::TracedCallback, ns3::empty, ns3::empty, ns3::empty>::Disconnect(ns3::CallbackBase const & callback, std::string path) [member function] + cls.add_method('Disconnect', 'void', [param('ns3::CallbackBase&', 'callback', is_const=True), param('std::string', 'path')]) + return + +def register_Ns3TracedCallback__Ns3TimeUnit__lt__1__gt___Ns3TimeUnit__lt__1__gt___Ns3WifiPhyState_Ns3Empty_methods(root_module, cls): + ## traced-callback.h: ns3::TracedCallback, ns3::TimeUnit<1>, ns3::WifiPhy::State, ns3::empty>::TracedCallback() [constructor] + cls.add_constructor([], visibility='public') + ## traced-callback.h: void ns3::TracedCallback, ns3::TimeUnit<1>, ns3::WifiPhy::State, ns3::empty>::ConnectWithoutContext(ns3::CallbackBase const & callback) [member function] + cls.add_method('ConnectWithoutContext', 'void', [param('ns3::CallbackBase&', 'callback', is_const=True)]) + ## traced-callback.h: void ns3::TracedCallback, ns3::TimeUnit<1>, ns3::WifiPhy::State, ns3::empty>::Connect(ns3::CallbackBase const & callback, std::string path) [member function] + cls.add_method('Connect', 'void', [param('ns3::CallbackBase&', 'callback', is_const=True), param('std::string', 'path')]) + ## traced-callback.h: void ns3::TracedCallback, ns3::TimeUnit<1>, ns3::WifiPhy::State, ns3::empty>::DisconnectWithoutContext(ns3::CallbackBase const & callback) [member function] + cls.add_method('DisconnectWithoutContext', 'void', [param('ns3::CallbackBase&', 'callback', is_const=True)]) + ## traced-callback.h: void ns3::TracedCallback, ns3::TimeUnit<1>, ns3::WifiPhy::State, ns3::empty>::Disconnect(ns3::CallbackBase const & callback, std::string path) [member function] + cls.add_method('Disconnect', 'void', [param('ns3::CallbackBase&', 'callback', is_const=True), param('std::string', 'path')]) + return + +def register_Ns3TracedCallback__Ns3Ptr__lt__ns3Packet_const__gt___Ns3WifiMode_Ns3WifiPreamble_Unsigned_char_methods(root_module, cls): + ## traced-callback.h: ns3::TracedCallback, ns3::WifiMode, ns3::WifiPreamble, unsigned char>::TracedCallback() [constructor] + cls.add_constructor([], visibility='public') + ## traced-callback.h: void ns3::TracedCallback, ns3::WifiMode, ns3::WifiPreamble, unsigned char>::ConnectWithoutContext(ns3::CallbackBase const & callback) [member function] + cls.add_method('ConnectWithoutContext', 'void', [param('ns3::CallbackBase&', 'callback', is_const=True)]) + ## traced-callback.h: void ns3::TracedCallback, ns3::WifiMode, ns3::WifiPreamble, unsigned char>::Connect(ns3::CallbackBase const & callback, std::string path) [member function] + cls.add_method('Connect', 'void', [param('ns3::CallbackBase&', 'callback', is_const=True), param('std::string', 'path')]) + ## traced-callback.h: void ns3::TracedCallback, ns3::WifiMode, ns3::WifiPreamble, unsigned char>::DisconnectWithoutContext(ns3::CallbackBase const & callback) [member function] + cls.add_method('DisconnectWithoutContext', 'void', [param('ns3::CallbackBase&', 'callback', is_const=True)]) + ## traced-callback.h: void ns3::TracedCallback, ns3::WifiMode, ns3::WifiPreamble, unsigned char>::Disconnect(ns3::CallbackBase const & callback, std::string path) [member function] + cls.add_method('Disconnect', 'void', [param('ns3::CallbackBase&', 'callback', is_const=True), param('std::string', 'path')]) + return + +def register_Ns3TracedCallback__Ns3Ptr__lt__ns3Packet_const__gt___Double_Ns3Empty_Ns3Empty_methods(root_module, cls): + ## traced-callback.h: ns3::TracedCallback, double, ns3::empty, ns3::empty>::TracedCallback() [constructor] + cls.add_constructor([], visibility='public') + ## traced-callback.h: void ns3::TracedCallback, double, ns3::empty, ns3::empty>::ConnectWithoutContext(ns3::CallbackBase const & callback) [member function] + cls.add_method('ConnectWithoutContext', 'void', [param('ns3::CallbackBase&', 'callback', is_const=True)]) + ## traced-callback.h: void ns3::TracedCallback, double, ns3::empty, ns3::empty>::Connect(ns3::CallbackBase const & callback, std::string path) [member function] + cls.add_method('Connect', 'void', [param('ns3::CallbackBase&', 'callback', is_const=True), param('std::string', 'path')]) + ## traced-callback.h: void ns3::TracedCallback, double, ns3::empty, ns3::empty>::DisconnectWithoutContext(ns3::CallbackBase const & callback) [member function] + cls.add_method('DisconnectWithoutContext', 'void', [param('ns3::CallbackBase&', 'callback', is_const=True)]) + ## traced-callback.h: void ns3::TracedCallback, double, ns3::empty, ns3::empty>::Disconnect(ns3::CallbackBase const & callback, std::string path) [member function] + cls.add_method('Disconnect', 'void', [param('ns3::CallbackBase&', 'callback', is_const=True), param('std::string', 'path')]) + return + +def register_Ns3TracedCallback__Ns3Ptr__lt__ns3Packet_const__gt___Double_Ns3WifiMode_Ns3WifiPreamble_methods(root_module, cls): + ## traced-callback.h: ns3::TracedCallback, double, ns3::WifiMode, ns3::WifiPreamble>::TracedCallback() [constructor] + cls.add_constructor([], visibility='public') + ## traced-callback.h: void ns3::TracedCallback, double, ns3::WifiMode, ns3::WifiPreamble>::ConnectWithoutContext(ns3::CallbackBase const & callback) [member function] + cls.add_method('ConnectWithoutContext', 'void', [param('ns3::CallbackBase&', 'callback', is_const=True)]) + ## traced-callback.h: void ns3::TracedCallback, double, ns3::WifiMode, ns3::WifiPreamble>::Connect(ns3::CallbackBase const & callback, std::string path) [member function] + cls.add_method('Connect', 'void', [param('ns3::CallbackBase&', 'callback', is_const=True), param('std::string', 'path')]) + ## traced-callback.h: void ns3::TracedCallback, double, ns3::WifiMode, ns3::WifiPreamble>::DisconnectWithoutContext(ns3::CallbackBase const & callback) [member function] + cls.add_method('DisconnectWithoutContext', 'void', [param('ns3::CallbackBase&', 'callback', is_const=True)]) + ## traced-callback.h: void ns3::TracedCallback, double, ns3::WifiMode, ns3::WifiPreamble>::Disconnect(ns3::CallbackBase const & callback, std::string path) [member function] + cls.add_method('Disconnect', 'void', [param('ns3::CallbackBase&', 'callback', is_const=True), param('std::string', 'path')]) + return + +def register_Ns3TracedCallback__Unsigned_int_Unsigned_int_Ns3Empty_Ns3Empty_methods(root_module, cls): + ## traced-callback.h: ns3::TracedCallback::TracedCallback() [constructor] + cls.add_constructor([], visibility='public') + ## traced-callback.h: void ns3::TracedCallback::ConnectWithoutContext(ns3::CallbackBase const & callback) [member function] + cls.add_method('ConnectWithoutContext', 'void', [param('ns3::CallbackBase&', 'callback', is_const=True)]) + ## traced-callback.h: void ns3::TracedCallback::Connect(ns3::CallbackBase const & callback, std::string path) [member function] + cls.add_method('Connect', 'void', [param('ns3::CallbackBase&', 'callback', is_const=True), param('std::string', 'path')]) + ## traced-callback.h: void ns3::TracedCallback::DisconnectWithoutContext(ns3::CallbackBase const & callback) [member function] + cls.add_method('DisconnectWithoutContext', 'void', [param('ns3::CallbackBase&', 'callback', is_const=True)]) + ## traced-callback.h: void ns3::TracedCallback::Disconnect(ns3::CallbackBase const & callback, std::string path) [member function] + cls.add_method('Disconnect', 'void', [param('ns3::CallbackBase&', 'callback', is_const=True), param('std::string', 'path')]) + return + +def register_Ns3DeterministicVariable_methods(root_module, cls): + ## random-variable.h: ns3::DeterministicVariable::DeterministicVariable(double * d, uint32_t c) [constructor] + cls.add_constructor([param('double *', 'd'), param('uint32_t', 'c')], visibility='public') + return + +def register_Ns3AttributeList_methods(root_module, cls): + ## attribute-list.h: ns3::AttributeList::AttributeList() [constructor] + cls.add_constructor([], visibility='public') + ## attribute-list.h: ns3::AttributeList::AttributeList(ns3::AttributeList const & o) [copy constructor] + cls.add_constructor([param('ns3::AttributeList&', 'o', is_const=True)], visibility='public') + ## attribute-list.h: void ns3::AttributeList::Set(std::string name, ns3::AttributeValue const & value) [member function] + cls.add_method('Set', 'void', [param('std::string', 'name'), param('ns3::AttributeValue&', 'value', is_const=True)]) + ## attribute-list.h: bool ns3::AttributeList::SetFailSafe(std::string name, ns3::AttributeValue const & value) [member function] + cls.add_method('SetFailSafe', 'bool', [param('std::string', 'name'), param('ns3::AttributeValue&', 'value', is_const=True)]) + ## attribute-list.h: void ns3::AttributeList::SetWithTid(ns3::TypeId tid, std::string name, ns3::AttributeValue const & value) [member function] + cls.add_method('SetWithTid', 'void', [param('ns3::TypeId', 'tid'), param('std::string', 'name'), param('ns3::AttributeValue&', 'value', is_const=True)]) + ## attribute-list.h: void ns3::AttributeList::Reset() [member function] + cls.add_method('Reset', 'void', []) + ## attribute-list.h: static ns3::AttributeList * ns3::AttributeList::GetGlobal() [member function] + cls.add_method('GetGlobal', 'ns3::AttributeList *', [], is_static=True) + ## attribute-list.h: std::string ns3::AttributeList::SerializeToString() const [member function] + cls.add_method('SerializeToString', 'std::string', [], is_const=True) + ## attribute-list.h: bool ns3::AttributeList::DeserializeFromString(std::string value) [member function] + cls.add_method('DeserializeFromString', 'bool', [param('std::string', 'value')]) + return + +def register_Ns3AttributeValue_methods(root_module, cls): + ## attribute.h: ns3::AttributeValue::AttributeValue(ns3::AttributeValue const & arg0) [copy constructor] + cls.add_constructor([param('ns3::AttributeValue&', 'arg0', is_const=True)], visibility='public') + ## attribute.h: ns3::AttributeValue::AttributeValue() [constructor] + cls.add_constructor([], visibility='public') + ## attribute.h: ns3::Ptr ns3::AttributeValue::Copy() const [member function] + cls.add_method('Copy', 'ns3::Ptr< ns3::AttributeValue >', [], is_pure_virtual=True, is_const=True, is_virtual=True) + ## attribute.h: std::string ns3::AttributeValue::SerializeToString(ns3::Ptr checker) const [member function] + cls.add_method('SerializeToString', 'std::string', [param('ns3::Ptr< ns3::AttributeChecker const >', 'checker')], is_pure_virtual=True, is_const=True, is_virtual=True) + ## attribute.h: bool ns3::AttributeValue::DeserializeFromString(std::string value, ns3::Ptr checker) [member function] + cls.add_method('DeserializeFromString', 'bool', [param('std::string', 'value'), param('ns3::Ptr< ns3::AttributeChecker const >', 'checker')], is_pure_virtual=True, is_virtual=True) + return + +def register_Ns3UniformVariable_methods(root_module, cls): + ## random-variable.h: ns3::UniformVariable::UniformVariable() [constructor] + cls.add_constructor([], visibility='public') + ## random-variable.h: ns3::UniformVariable::UniformVariable(double s, double l) [constructor] + cls.add_constructor([param('double', 's'), param('double', 'l')], visibility='public') + ## random-variable.h: static double ns3::UniformVariable::GetSingleValue(double s, double l) [member function] + cls.add_method('GetSingleValue', 'double', [param('double', 's'), param('double', 'l')], is_static=True) + return + +def register_Ns3Object_methods(root_module, cls): + ## object.h: static ns3::TypeId ns3::Object::GetTypeId() [member function] + cls.add_method('GetTypeId', 'ns3::TypeId', [], is_static=True) + ## object.h: ns3::Object::Object() [constructor] + cls.add_constructor([], visibility='public') + ## object.h: ns3::TypeId ns3::Object::GetInstanceTypeId() const [member function] + cls.add_method('GetInstanceTypeId', 'ns3::TypeId', [], is_const=True, is_virtual=True) + ## object.h: ns3::Ptr ns3::Object::GetObject(ns3::TypeId tid) const [member function] + cls.add_method('GetObject', 'ns3::Ptr< ns3::Object >', [param('ns3::TypeId', 'tid')], is_const=True, template_parameters=['ns3::Object'], custom_template_method_name='GetObject') + ## object.h: void ns3::Object::Dispose() [member function] + cls.add_method('Dispose', 'void', []) + ## object.h: void ns3::Object::AggregateObject(ns3::Ptr other) [member function] + cls.add_method('AggregateObject', 'void', [param('ns3::Ptr< ns3::Object >', 'other')]) + ## object.h: ns3::Object::AggregateIterator ns3::Object::GetAggregateIterator() const [member function] + cls.add_method('GetAggregateIterator', 'ns3::Object::AggregateIterator', [], is_const=True) + ## object.h: void ns3::Object::DoDispose() [member function] + cls.add_method('DoDispose', 'void', [], visibility='protected', is_virtual=True) + ## object.h: ns3::Object::Object(ns3::Object const & o) [copy constructor] + cls.add_constructor([param('ns3::Object&', 'o', is_const=True)], visibility='protected') + return + +def register_Ns3ObjectAggregateIterator_methods(root_module, cls): + ## object.h: ns3::Object::AggregateIterator::AggregateIterator() [constructor] + cls.add_constructor([], visibility='public') + ## object.h: bool ns3::Object::AggregateIterator::HasNext() const [member function] + cls.add_method('HasNext', 'bool', [], is_const=True) + ## object.h: ns3::Ptr ns3::Object::AggregateIterator::Next() [member function] + cls.add_method('Next', 'ns3::Ptr< ns3::Object const >', []) + return + +def register_Ns3SequentialVariable_methods(root_module, cls): + ## random-variable.h: ns3::SequentialVariable::SequentialVariable(double f, double l, double i=1, uint32_t c=1) [constructor] + cls.add_constructor([param('double', 'f'), param('double', 'l'), param('double', 'i', default_value='1'), param('uint32_t', 'c', default_value='1')], visibility='public') + ## random-variable.h: ns3::SequentialVariable::SequentialVariable(double f, double l, ns3::RandomVariable const & i, uint32_t c=1) [constructor] + cls.add_constructor([param('double', 'f'), param('double', 'l'), param('ns3::RandomVariable&', 'i', is_const=True), param('uint32_t', 'c', default_value='1')], visibility='public') + return + +def register_Ns3ObjectVectorChecker_methods(root_module, cls): + ## object-vector.h: ns3::TypeId ns3::ObjectVectorChecker::GetItemTypeId() const [member function] + cls.add_method('GetItemTypeId', 'ns3::TypeId', [], is_pure_virtual=True, is_const=True, is_virtual=True) + cls.add_constructor([]) + return + +def register_Ns3StringChecker_methods(root_module, cls): + cls.add_constructor([]) + return + +def register_Ns3ObjectVectorValue_methods(root_module, cls): + ## object-vector.h: ns3::ObjectVectorValue::ObjectVectorValue() [constructor] + cls.add_constructor([], visibility='public') + ## object-vector.h: __gnu_cxx::__normal_iterator*,std::vector, std::allocator > > > ns3::ObjectVectorValue::Begin() const [member function] + cls.add_method('Begin', '__gnu_cxx::__normal_iterator< const ns3::Ptr< ns3::Object >, std::vector< ns3::Ptr< ns3::Object >, std::allocator< ns3::Ptr< ns3::Object > > > >', [], is_const=True) + ## object-vector.h: __gnu_cxx::__normal_iterator*,std::vector, std::allocator > > > ns3::ObjectVectorValue::End() const [member function] + cls.add_method('End', '__gnu_cxx::__normal_iterator< const ns3::Ptr< ns3::Object >, std::vector< ns3::Ptr< ns3::Object >, std::allocator< ns3::Ptr< ns3::Object > > > >', [], is_const=True) + ## object-vector.h: uint32_t ns3::ObjectVectorValue::GetN() const [member function] + cls.add_method('GetN', 'uint32_t', [], is_const=True) + ## object-vector.h: ns3::Ptr ns3::ObjectVectorValue::Get(uint32_t i) const [member function] + cls.add_method('Get', 'ns3::Ptr< ns3::Object >', [param('uint32_t', 'i')], is_const=True) + ## object-vector.h: ns3::Ptr ns3::ObjectVectorValue::Copy() const [member function] + cls.add_method('Copy', 'ns3::Ptr< ns3::AttributeValue >', [], is_const=True, is_virtual=True) + ## object-vector.h: std::string ns3::ObjectVectorValue::SerializeToString(ns3::Ptr checker) const [member function] + cls.add_method('SerializeToString', 'std::string', [param('ns3::Ptr< ns3::AttributeChecker const >', 'checker')], is_const=True, is_virtual=True) + ## object-vector.h: bool ns3::ObjectVectorValue::DeserializeFromString(std::string value, ns3::Ptr checker) [member function] + cls.add_method('DeserializeFromString', 'bool', [param('std::string', 'value'), param('ns3::Ptr< ns3::AttributeChecker const >', 'checker')], is_virtual=True) + return + +def register_Ns3BooleanChecker_methods(root_module, cls): + cls.add_constructor([]) + return + +def register_Ns3UintegerValue_methods(root_module, cls): + ## uinteger.h: ns3::UintegerValue::UintegerValue() [constructor] + cls.add_constructor([], visibility='public') + ## uinteger.h: ns3::UintegerValue::UintegerValue(uint64_t const & value) [constructor] + cls.add_constructor([param('uint64_t&', 'value', is_const=True)], visibility='public') + ## uinteger.h: void ns3::UintegerValue::Set(uint64_t const & value) [member function] + cls.add_method('Set', 'void', [param('uint64_t&', 'value', is_const=True)]) + ## uinteger.h: uint64_t ns3::UintegerValue::Get() const [member function] + cls.add_method('Get', 'uint64_t', [], is_const=True) + ## uinteger.h: ns3::Ptr ns3::UintegerValue::Copy() const [member function] + cls.add_method('Copy', 'ns3::Ptr< ns3::AttributeValue >', [], is_const=True, is_virtual=True) + ## uinteger.h: std::string ns3::UintegerValue::SerializeToString(ns3::Ptr checker) const [member function] + cls.add_method('SerializeToString', 'std::string', [param('ns3::Ptr< ns3::AttributeChecker const >', 'checker')], is_const=True, is_virtual=True) + ## uinteger.h: bool ns3::UintegerValue::DeserializeFromString(std::string value, ns3::Ptr checker) [member function] + cls.add_method('DeserializeFromString', 'bool', [param('std::string', 'value'), param('ns3::Ptr< ns3::AttributeChecker const >', 'checker')], is_virtual=True) + return + +def register_Ns3ObjectVectorAccessor_methods(root_module, cls): + ## object-vector.h: bool ns3::ObjectVectorAccessor::Set(ns3::ObjectBase * object, ns3::AttributeValue const & value) const [member function] + cls.add_method('Set', 'bool', [param('ns3::ObjectBase *', 'object'), param('ns3::AttributeValue&', 'value', is_const=True)], is_const=True, is_virtual=True) + ## object-vector.h: bool ns3::ObjectVectorAccessor::Get(ns3::ObjectBase const * object, ns3::AttributeValue & value) const [member function] + cls.add_method('Get', 'bool', [param('ns3::ObjectBase *', 'object', transfer_ownership=False, is_const=True), param('ns3::AttributeValue&', 'value')], is_const=True, is_virtual=True) + ## object-vector.h: bool ns3::ObjectVectorAccessor::HasGetter() const [member function] + cls.add_method('HasGetter', 'bool', [], is_const=True, is_virtual=True) + ## object-vector.h: bool ns3::ObjectVectorAccessor::HasSetter() const [member function] + cls.add_method('HasSetter', 'bool', [], is_const=True, is_virtual=True) + ## object-vector.h: bool ns3::ObjectVectorAccessor::DoGetN(ns3::ObjectBase const * object, uint32_t * n) const [member function] + cls.add_method('DoGetN', 'bool', [param('ns3::ObjectBase *', 'object', transfer_ownership=False, is_const=True), param('uint32_t *', 'n')], is_pure_virtual=True, is_const=True, visibility='private', is_virtual=True) + ## object-vector.h: ns3::Ptr ns3::ObjectVectorAccessor::DoGet(ns3::ObjectBase const * object, uint32_t i) const [member function] + cls.add_method('DoGet', 'ns3::Ptr< ns3::Object >', [param('ns3::ObjectBase *', 'object', transfer_ownership=False, is_const=True), param('uint32_t', 'i')], is_pure_virtual=True, is_const=True, visibility='private', is_virtual=True) + cls.add_constructor([]) + return + +def register_Ns3PointerValue_methods(root_module, cls): + ## pointer.h: ns3::PointerValue::PointerValue(ns3::PointerValue const & arg0) [copy constructor] + cls.add_constructor([param('ns3::PointerValue&', 'arg0', is_const=True)], visibility='public') + ## pointer.h: ns3::PointerValue::PointerValue() [constructor] + cls.add_constructor([], visibility='public') + ## pointer.h: ns3::PointerValue::PointerValue(ns3::Ptr object) [constructor] + cls.add_constructor([param('ns3::Ptr< ns3::Object >', 'object')], visibility='public') + ## pointer.h: void ns3::PointerValue::SetObject(ns3::Ptr object) [member function] + cls.add_method('SetObject', 'void', [param('ns3::Ptr< ns3::Object >', 'object')]) + ## pointer.h: ns3::Ptr ns3::PointerValue::GetObject() const [member function] + cls.add_method('GetObject', 'ns3::Ptr< ns3::Object >', [], is_const=True) + ## pointer.h: ns3::Ptr ns3::PointerValue::Copy() const [member function] + cls.add_method('Copy', 'ns3::Ptr< ns3::AttributeValue >', [], is_const=True, is_virtual=True) + ## pointer.h: std::string ns3::PointerValue::SerializeToString(ns3::Ptr checker) const [member function] + cls.add_method('SerializeToString', 'std::string', [param('ns3::Ptr< ns3::AttributeChecker const >', 'checker')], is_const=True, is_virtual=True) + ## pointer.h: bool ns3::PointerValue::DeserializeFromString(std::string value, ns3::Ptr checker) [member function] + cls.add_method('DeserializeFromString', 'bool', [param('std::string', 'value'), param('ns3::Ptr< ns3::AttributeChecker const >', 'checker')], is_virtual=True) + return + +def register_Ns3ObjectFactoryChecker_methods(root_module, cls): + cls.add_constructor([]) + return + +def register_Ns3TypeIdChecker_methods(root_module, cls): + cls.add_constructor([]) + return + +def register_Ns3DoubleValue_methods(root_module, cls): + ## double.h: ns3::DoubleValue::DoubleValue() [constructor] + cls.add_constructor([], visibility='public') + ## double.h: ns3::DoubleValue::DoubleValue(double const & value) [constructor] + cls.add_constructor([param('double&', 'value', is_const=True)], visibility='public') + ## double.h: void ns3::DoubleValue::Set(double const & value) [member function] + cls.add_method('Set', 'void', [param('double&', 'value', is_const=True)]) + ## double.h: double ns3::DoubleValue::Get() const [member function] + cls.add_method('Get', 'double', [], is_const=True) + ## double.h: ns3::Ptr ns3::DoubleValue::Copy() const [member function] + cls.add_method('Copy', 'ns3::Ptr< ns3::AttributeValue >', [], is_const=True, is_virtual=True) + ## double.h: std::string ns3::DoubleValue::SerializeToString(ns3::Ptr checker) const [member function] + cls.add_method('SerializeToString', 'std::string', [param('ns3::Ptr< ns3::AttributeChecker const >', 'checker')], is_const=True, is_virtual=True) + ## double.h: bool ns3::DoubleValue::DeserializeFromString(std::string value, ns3::Ptr checker) [member function] + cls.add_method('DeserializeFromString', 'bool', [param('std::string', 'value'), param('ns3::Ptr< ns3::AttributeChecker const >', 'checker')], is_virtual=True) + return + +def register_Ns3StringValue_methods(root_module, cls): + ## string.h: ns3::StringValue::StringValue() [constructor] + cls.add_constructor([], visibility='public') + ## string.h: ns3::StringValue::StringValue(std::string const & value) [constructor] + cls.add_constructor([param('std::string&', 'value', is_const=True)], visibility='public') + ## string.h: void ns3::StringValue::Set(std::string const & value) [member function] + cls.add_method('Set', 'void', [param('std::string&', 'value', is_const=True)]) + ## string.h: std::string ns3::StringValue::Get() const [member function] + cls.add_method('Get', 'std::string', [], is_const=True) + ## string.h: ns3::Ptr ns3::StringValue::Copy() const [member function] + cls.add_method('Copy', 'ns3::Ptr< ns3::AttributeValue >', [], is_const=True, is_virtual=True) + ## string.h: std::string ns3::StringValue::SerializeToString(ns3::Ptr checker) const [member function] + cls.add_method('SerializeToString', 'std::string', [param('ns3::Ptr< ns3::AttributeChecker const >', 'checker')], is_const=True, is_virtual=True) + ## string.h: bool ns3::StringValue::DeserializeFromString(std::string value, ns3::Ptr checker) [member function] + cls.add_method('DeserializeFromString', 'bool', [param('std::string', 'value'), param('ns3::Ptr< ns3::AttributeChecker const >', 'checker')], is_virtual=True) + return + +def register_Ns3TypeIdValue_methods(root_module, cls): + ## type-id.h: ns3::TypeIdValue::TypeIdValue() [constructor] + cls.add_constructor([], visibility='public') + ## type-id.h: ns3::TypeIdValue::TypeIdValue(ns3::TypeId const & value) [constructor] + cls.add_constructor([param('ns3::TypeId&', 'value', is_const=True)], visibility='public') + ## type-id.h: void ns3::TypeIdValue::Set(ns3::TypeId const & value) [member function] + cls.add_method('Set', 'void', [param('ns3::TypeId&', 'value', is_const=True)]) + ## type-id.h: ns3::TypeId ns3::TypeIdValue::Get() const [member function] + cls.add_method('Get', 'ns3::TypeId', [], is_const=True) + ## type-id.h: ns3::Ptr ns3::TypeIdValue::Copy() const [member function] + cls.add_method('Copy', 'ns3::Ptr< ns3::AttributeValue >', [], is_const=True, is_virtual=True) + ## type-id.h: std::string ns3::TypeIdValue::SerializeToString(ns3::Ptr checker) const [member function] + cls.add_method('SerializeToString', 'std::string', [param('ns3::Ptr< ns3::AttributeChecker const >', 'checker')], is_const=True, is_virtual=True) + ## type-id.h: bool ns3::TypeIdValue::DeserializeFromString(std::string value, ns3::Ptr checker) [member function] + cls.add_method('DeserializeFromString', 'bool', [param('std::string', 'value'), param('ns3::Ptr< ns3::AttributeChecker const >', 'checker')], is_virtual=True) + return + +def register_Ns3EnumValue_methods(root_module, cls): + ## enum.h: ns3::EnumValue::EnumValue() [constructor] + cls.add_constructor([], visibility='public') + ## enum.h: ns3::EnumValue::EnumValue(int v) [constructor] + cls.add_constructor([param('int', 'v')], visibility='public') + ## enum.h: void ns3::EnumValue::Set(int v) [member function] + cls.add_method('Set', 'void', [param('int', 'v')]) + ## enum.h: int ns3::EnumValue::Get() const [member function] + cls.add_method('Get', 'int', [], is_const=True) + ## enum.h: ns3::Ptr ns3::EnumValue::Copy() const [member function] + cls.add_method('Copy', 'ns3::Ptr< ns3::AttributeValue >', [], is_const=True, is_virtual=True) + ## enum.h: std::string ns3::EnumValue::SerializeToString(ns3::Ptr checker) const [member function] + cls.add_method('SerializeToString', 'std::string', [param('ns3::Ptr< ns3::AttributeChecker const >', 'checker')], is_const=True, is_virtual=True) + ## enum.h: bool ns3::EnumValue::DeserializeFromString(std::string value, ns3::Ptr checker) [member function] + cls.add_method('DeserializeFromString', 'bool', [param('std::string', 'value'), param('ns3::Ptr< ns3::AttributeChecker const >', 'checker')], is_virtual=True) + return + +def register_Ns3RandomVariableValue_methods(root_module, cls): + ## random-variable.h: ns3::RandomVariableValue::RandomVariableValue() [constructor] + cls.add_constructor([], visibility='public') + ## random-variable.h: ns3::RandomVariableValue::RandomVariableValue(ns3::RandomVariable const & value) [constructor] + cls.add_constructor([param('ns3::RandomVariable&', 'value', is_const=True)], visibility='public') + ## random-variable.h: void ns3::RandomVariableValue::Set(ns3::RandomVariable const & value) [member function] + cls.add_method('Set', 'void', [param('ns3::RandomVariable&', 'value', is_const=True)]) + ## random-variable.h: ns3::RandomVariable ns3::RandomVariableValue::Get() const [member function] + cls.add_method('Get', 'ns3::RandomVariable', [], is_const=True) + ## random-variable.h: ns3::Ptr ns3::RandomVariableValue::Copy() const [member function] + cls.add_method('Copy', 'ns3::Ptr< ns3::AttributeValue >', [], is_const=True, is_virtual=True) + ## random-variable.h: std::string ns3::RandomVariableValue::SerializeToString(ns3::Ptr checker) const [member function] + cls.add_method('SerializeToString', 'std::string', [param('ns3::Ptr< ns3::AttributeChecker const >', 'checker')], is_const=True, is_virtual=True) + ## random-variable.h: bool ns3::RandomVariableValue::DeserializeFromString(std::string value, ns3::Ptr checker) [member function] + cls.add_method('DeserializeFromString', 'bool', [param('std::string', 'value'), param('ns3::Ptr< ns3::AttributeChecker const >', 'checker')], is_virtual=True) + return + +def register_Ns3ObjectFactoryValue_methods(root_module, cls): + ## object-factory.h: ns3::ObjectFactoryValue::ObjectFactoryValue() [constructor] + cls.add_constructor([], visibility='public') + ## object-factory.h: ns3::ObjectFactoryValue::ObjectFactoryValue(ns3::ObjectFactory const & value) [constructor] + cls.add_constructor([param('ns3::ObjectFactory&', 'value', is_const=True)], visibility='public') + ## object-factory.h: void ns3::ObjectFactoryValue::Set(ns3::ObjectFactory const & value) [member function] + cls.add_method('Set', 'void', [param('ns3::ObjectFactory&', 'value', is_const=True)]) + ## object-factory.h: ns3::ObjectFactory ns3::ObjectFactoryValue::Get() const [member function] + cls.add_method('Get', 'ns3::ObjectFactory', [], is_const=True) + ## object-factory.h: ns3::Ptr ns3::ObjectFactoryValue::Copy() const [member function] + cls.add_method('Copy', 'ns3::Ptr< ns3::AttributeValue >', [], is_const=True, is_virtual=True) + ## object-factory.h: std::string ns3::ObjectFactoryValue::SerializeToString(ns3::Ptr checker) const [member function] + cls.add_method('SerializeToString', 'std::string', [param('ns3::Ptr< ns3::AttributeChecker const >', 'checker')], is_const=True, is_virtual=True) + ## object-factory.h: bool ns3::ObjectFactoryValue::DeserializeFromString(std::string value, ns3::Ptr checker) [member function] + cls.add_method('DeserializeFromString', 'bool', [param('std::string', 'value'), param('ns3::Ptr< ns3::AttributeChecker const >', 'checker')], is_virtual=True) + return + +def register_Ns3IntegerValue_methods(root_module, cls): + ## integer.h: ns3::IntegerValue::IntegerValue() [constructor] + cls.add_constructor([], visibility='public') + ## integer.h: ns3::IntegerValue::IntegerValue(int64_t const & value) [constructor] + cls.add_constructor([param('int64_t&', 'value', is_const=True)], visibility='public') + ## integer.h: void ns3::IntegerValue::Set(int64_t const & value) [member function] + cls.add_method('Set', 'void', [param('int64_t&', 'value', is_const=True)]) + ## integer.h: int64_t ns3::IntegerValue::Get() const [member function] + cls.add_method('Get', 'int64_t', [], is_const=True) + ## integer.h: ns3::Ptr ns3::IntegerValue::Copy() const [member function] + cls.add_method('Copy', 'ns3::Ptr< ns3::AttributeValue >', [], is_const=True, is_virtual=True) + ## integer.h: std::string ns3::IntegerValue::SerializeToString(ns3::Ptr checker) const [member function] + cls.add_method('SerializeToString', 'std::string', [param('ns3::Ptr< ns3::AttributeChecker const >', 'checker')], is_const=True, is_virtual=True) + ## integer.h: bool ns3::IntegerValue::DeserializeFromString(std::string value, ns3::Ptr checker) [member function] + cls.add_method('DeserializeFromString', 'bool', [param('std::string', 'value'), param('ns3::Ptr< ns3::AttributeChecker const >', 'checker')], is_virtual=True) + return + +def register_Ns3EmptyAttributeValue_methods(root_module, cls): + ## attribute.h: ns3::EmptyAttributeValue::EmptyAttributeValue(ns3::EmptyAttributeValue const & arg0) [copy constructor] + cls.add_constructor([param('ns3::EmptyAttributeValue&', 'arg0', is_const=True)], visibility='public') + ## attribute.h: ns3::EmptyAttributeValue::EmptyAttributeValue() [constructor] + cls.add_constructor([], visibility='public') + ## attribute.h: ns3::Ptr ns3::EmptyAttributeValue::Copy() const [member function] + cls.add_method('Copy', 'ns3::Ptr< ns3::AttributeValue >', [], is_const=True, visibility='private', is_virtual=True) + ## attribute.h: std::string ns3::EmptyAttributeValue::SerializeToString(ns3::Ptr checker) const [member function] + cls.add_method('SerializeToString', 'std::string', [param('ns3::Ptr< ns3::AttributeChecker const >', 'checker')], is_const=True, visibility='private', is_virtual=True) + ## attribute.h: bool ns3::EmptyAttributeValue::DeserializeFromString(std::string value, ns3::Ptr checker) [member function] + cls.add_method('DeserializeFromString', 'bool', [param('std::string', 'value'), param('ns3::Ptr< ns3::AttributeChecker const >', 'checker')], visibility='private', is_virtual=True) + return + +def register_Ns3BooleanValue_methods(root_module, cls): + ## boolean.h: ns3::BooleanValue::BooleanValue(ns3::BooleanValue const & arg0) [copy constructor] + cls.add_constructor([param('ns3::BooleanValue&', 'arg0', is_const=True)], visibility='public') + ## boolean.h: ns3::BooleanValue::BooleanValue() [constructor] + cls.add_constructor([], visibility='public') + ## boolean.h: ns3::BooleanValue::BooleanValue(bool value) [constructor] + cls.add_constructor([param('bool', 'value')], visibility='public') + ## boolean.h: ns3::Ptr ns3::BooleanValue::Copy() const [member function] + cls.add_method('Copy', 'ns3::Ptr< ns3::AttributeValue >', [], is_const=True, is_virtual=True) + ## boolean.h: bool ns3::BooleanValue::DeserializeFromString(std::string value, ns3::Ptr checker) [member function] + cls.add_method('DeserializeFromString', 'bool', [param('std::string', 'value'), param('ns3::Ptr< ns3::AttributeChecker const >', 'checker')], is_virtual=True) + ## boolean.h: bool ns3::BooleanValue::Get() const [member function] + cls.add_method('Get', 'bool', [], is_const=True) + ## boolean.h: std::string ns3::BooleanValue::SerializeToString(ns3::Ptr checker) const [member function] + cls.add_method('SerializeToString', 'std::string', [param('ns3::Ptr< ns3::AttributeChecker const >', 'checker')], is_const=True, is_virtual=True) + ## boolean.h: void ns3::BooleanValue::Set(bool value) [member function] + cls.add_method('Set', 'void', [param('bool', 'value')]) + cls.add_output_stream_operator() + return + +def register_Ns3TracedValue__Unsigned_int_methods(root_module, cls): + ## traced-value.h: ns3::TracedValue::TracedValue() [constructor] + cls.add_constructor([], visibility='public') + ## traced-value.h: ns3::TracedValue::TracedValue(ns3::TracedValue const & o) [copy constructor] + cls.add_constructor([param('ns3::TracedValue< unsigned int >&', 'o', is_const=True)], visibility='public') + ## traced-value.h: ns3::TracedValue::TracedValue(unsigned int const & v) [constructor] + cls.add_constructor([param('unsigned int&', 'v', is_const=True)], visibility='public') + ## traced-value.h: ns3::TracedValue::TracedValue(ns3::IntegerValue const & value) [constructor] + cls.add_constructor([param('ns3::IntegerValue&', 'value', is_const=True)], visibility='public') + ## traced-value.h: ns3::TracedValue::TracedValue(ns3::UintegerValue const & value) [constructor] + cls.add_constructor([param('ns3::UintegerValue&', 'value', is_const=True)], visibility='public') + ## traced-value.h: ns3::TracedValue::TracedValue(ns3::BooleanValue const & value) [constructor] + cls.add_constructor([param('ns3::BooleanValue&', 'value', is_const=True)], visibility='public') + ## traced-value.h: ns3::TracedValue::TracedValue(ns3::EnumValue const & value) [constructor] + cls.add_constructor([param('ns3::EnumValue&', 'value', is_const=True)], visibility='public') + ## traced-value.h: void ns3::TracedValue::ConnectWithoutContext(ns3::CallbackBase const & cb) [member function] + cls.add_method('ConnectWithoutContext', 'void', [param('ns3::CallbackBase&', 'cb', is_const=True)]) + ## traced-value.h: void ns3::TracedValue::Connect(ns3::CallbackBase const & cb, std::string path) [member function] + cls.add_method('Connect', 'void', [param('ns3::CallbackBase&', 'cb', is_const=True), param('std::string', 'path')]) + ## traced-value.h: void ns3::TracedValue::DisconnectWithoutContext(ns3::CallbackBase const & cb) [member function] + cls.add_method('DisconnectWithoutContext', 'void', [param('ns3::CallbackBase&', 'cb', is_const=True)]) + ## traced-value.h: void ns3::TracedValue::Disconnect(ns3::CallbackBase const & cb, std::string path) [member function] + cls.add_method('Disconnect', 'void', [param('ns3::CallbackBase&', 'cb', is_const=True), param('std::string', 'path')]) + ## traced-value.h: void ns3::TracedValue::Set(unsigned int const & v) [member function] + cls.add_method('Set', 'void', [param('unsigned int&', 'v', is_const=True)]) + ## traced-value.h: unsigned int ns3::TracedValue::Get() const [member function] + cls.add_method('Get', 'unsigned int', [], is_const=True) + return + +def register_functions(root_module): + module = root_module + ## boolean.h: extern ns3::Ptr ns3::MakeBooleanChecker() [free function] + module.add_function('MakeBooleanChecker', 'ns3::Ptr< ns3::AttributeChecker const >', []) + ## type-name.h: extern std::string ns3::TypeNameGet() [free function] + module.add_function('TypeNameGet', 'std::string', [], template_parameters=['double']) + ## type-name.h: extern std::string ns3::TypeNameGet() [free function] + module.add_function('TypeNameGet', 'std::string', [], template_parameters=['float']) + ## type-name.h: extern std::string ns3::TypeNameGet() [free function] + module.add_function('TypeNameGet', 'std::string', [], template_parameters=['long']) + ## type-name.h: extern std::string ns3::TypeNameGet() [free function] + module.add_function('TypeNameGet', 'std::string', [], template_parameters=['int']) + ## type-name.h: extern std::string ns3::TypeNameGet() [free function] + module.add_function('TypeNameGet', 'std::string', [], template_parameters=['short']) + ## type-name.h: extern std::string ns3::TypeNameGet() [free function] + module.add_function('TypeNameGet', 'std::string', [], template_parameters=['signed char']) + ## type-name.h: extern std::string ns3::TypeNameGet() [free function] + module.add_function('TypeNameGet', 'std::string', [], template_parameters=['unsigned long']) + ## type-name.h: extern std::string ns3::TypeNameGet() [free function] + module.add_function('TypeNameGet', 'std::string', [], template_parameters=['unsigned int']) + ## type-name.h: extern std::string ns3::TypeNameGet() [free function] + module.add_function('TypeNameGet', 'std::string', [], template_parameters=['unsigned short']) + ## type-name.h: extern std::string ns3::TypeNameGet() [free function] + module.add_function('TypeNameGet', 'std::string', [], template_parameters=['unsigned char']) + ## string.h: extern ns3::Ptr ns3::MakeStringChecker() [free function] + module.add_function('MakeStringChecker', 'ns3::Ptr< ns3::AttributeChecker const >', []) + ## enum.h: extern ns3::Ptr ns3::MakeEnumChecker(int v1, std::string n1, int v2=0, std::string n2="", int v3=0, std::string n3="", int v4=0, std::string n4="", int v5=0, std::string n5="", int v6=0, std::string n6="", int v7=0, std::string n7="", int v8=0, std::string n8="", int v9=0, std::string n9="", int v10=0, std::string n10="", int v11=0, std::string n11="", int v12=0, std::string n12="") [free function] + module.add_function('MakeEnumChecker', 'ns3::Ptr< ns3::AttributeChecker const >', [param('int', 'v1'), param('std::string', 'n1'), param('int', 'v2', default_value='0'), param('std::string', 'n2', default_value='""'), param('int', 'v3', default_value='0'), param('std::string', 'n3', default_value='""'), param('int', 'v4', default_value='0'), param('std::string', 'n4', default_value='""'), param('int', 'v5', default_value='0'), param('std::string', 'n5', default_value='""'), param('int', 'v6', default_value='0'), param('std::string', 'n6', default_value='""'), param('int', 'v7', default_value='0'), param('std::string', 'n7', default_value='""'), param('int', 'v8', default_value='0'), param('std::string', 'n8', default_value='""'), param('int', 'v9', default_value='0'), param('std::string', 'n9', default_value='""'), param('int', 'v10', default_value='0'), param('std::string', 'n10', default_value='""'), param('int', 'v11', default_value='0'), param('std::string', 'n11', default_value='""'), param('int', 'v12', default_value='0'), param('std::string', 'n12', default_value='""')]) + ## type-id.h: extern ns3::Ptr ns3::MakeTypeIdChecker() [free function] + module.add_function('MakeTypeIdChecker', 'ns3::Ptr< ns3::AttributeChecker const >', []) + ## ptr.h: extern ns3::Ptr ns3::Create() [free function] + module.add_function('Create', 'ns3::Ptr< ns3::PointerValue >', [], template_parameters=['ns3::PointerValue']) + ## ptr.h: extern ns3::Ptr ns3::Create() [free function] + module.add_function('Create', 'ns3::Ptr< ns3::ObjectVectorValue >', [], template_parameters=['ns3::ObjectVectorValue']) + ## object-factory.h: extern ns3::Ptr ns3::MakeObjectFactoryChecker() [free function] + module.add_function('MakeObjectFactoryChecker', 'ns3::Ptr< ns3::AttributeChecker const >', []) + ## breakpoint.h: extern void ns3::BreakpointFallback() [free function] + module.add_function('BreakpointFallback', 'void', []) + ## random-variable.h: extern ns3::Ptr ns3::MakeRandomVariableChecker() [free function] + module.add_function('MakeRandomVariableChecker', 'ns3::Ptr< ns3::AttributeChecker const >', []) + register_functions_ns3_internal(module.get_submodule('internal'), root_module) + register_functions_ns3_TimeStepPrecision(module.get_submodule('TimeStepPrecision'), root_module) + register_functions_ns3_Config(module.get_submodule('Config'), root_module) + register_functions_ns3_olsr(module.get_submodule('olsr'), root_module) + return + +def register_functions_ns3_internal(module, root_module): + ## uinteger.h: extern ns3::Ptr ns3::internal::MakeUintegerChecker(uint64_t min, uint64_t max, std::string name) [free function] + module.add_function('MakeUintegerChecker', 'ns3::Ptr< ns3::AttributeChecker const >', [param('uint64_t', 'min'), param('uint64_t', 'max'), param('std::string', 'name')]) + ## integer.h: extern ns3::Ptr ns3::internal::MakeIntegerChecker(int64_t min, int64_t max, std::string name) [free function] + module.add_function('MakeIntegerChecker', 'ns3::Ptr< ns3::AttributeChecker const >', [param('int64_t', 'min'), param('int64_t', 'max'), param('std::string', 'name')]) + ## double.h: extern ns3::Ptr ns3::internal::MakeDoubleChecker(double min, double max, std::string name) [free function] + module.add_function('MakeDoubleChecker', 'ns3::Ptr< ns3::AttributeChecker const >', [param('double', 'min'), param('double', 'max'), param('std::string', 'name')]) + return + +def register_functions_ns3_TimeStepPrecision(module, root_module): + return + +def register_functions_ns3_Config(module, root_module): + ## config.h: extern bool ns3::Config::SetDefaultFailSafe(std::string name, ns3::AttributeValue const & value) [free function] + module.add_function('SetDefaultFailSafe', 'bool', [param('std::string', 'name'), param('ns3::AttributeValue&', 'value', is_const=True)]) + ## config.h: extern void ns3::Config::DisconnectWithoutContext(std::string path, ns3::CallbackBase const & cb) [free function] + module.add_function('DisconnectWithoutContext', 'void', [param('std::string', 'path'), param('ns3::CallbackBase&', 'cb', is_const=True)]) + ## config.h: extern void ns3::Config::SetDefault(std::string name, ns3::AttributeValue const & value) [free function] + module.add_function('SetDefault', 'void', [param('std::string', 'name'), param('ns3::AttributeValue&', 'value', is_const=True)]) + ## config.h: extern void ns3::Config::Connect(std::string path, ns3::CallbackBase const & cb) [free function] + module.add_function('Connect', 'void', [param('std::string', 'path'), param('ns3::CallbackBase&', 'cb', is_const=True)]) + ## config.h: extern ns3::Ptr ns3::Config::GetRootNamespaceObject(uint32_t i) [free function] + module.add_function('GetRootNamespaceObject', 'ns3::Ptr< ns3::Object >', [param('uint32_t', 'i')]) + ## config.h: extern void ns3::Config::ConnectWithoutContext(std::string path, ns3::CallbackBase const & cb) [free function] + module.add_function('ConnectWithoutContext', 'void', [param('std::string', 'path'), param('ns3::CallbackBase&', 'cb', is_const=True)]) + ## config.h: extern void ns3::Config::UnregisterRootNamespaceObject(ns3::Ptr obj) [free function] + module.add_function('UnregisterRootNamespaceObject', 'void', [param('ns3::Ptr< ns3::Object >', 'obj')]) + ## config.h: extern bool ns3::Config::SetGlobalFailSafe(std::string name, ns3::AttributeValue const & value) [free function] + module.add_function('SetGlobalFailSafe', 'bool', [param('std::string', 'name'), param('ns3::AttributeValue&', 'value', is_const=True)]) + ## config.h: extern uint32_t ns3::Config::GetRootNamespaceObjectN() [free function] + module.add_function('GetRootNamespaceObjectN', 'uint32_t', []) + ## config.h: extern void ns3::Config::Set(std::string path, ns3::AttributeValue const & value) [free function] + module.add_function('Set', 'void', [param('std::string', 'path'), param('ns3::AttributeValue&', 'value', is_const=True)]) + ## config.h: extern void ns3::Config::SetGlobal(std::string name, ns3::AttributeValue const & value) [free function] + module.add_function('SetGlobal', 'void', [param('std::string', 'name'), param('ns3::AttributeValue&', 'value', is_const=True)]) + ## config.h: extern void ns3::Config::RegisterRootNamespaceObject(ns3::Ptr obj) [free function] + module.add_function('RegisterRootNamespaceObject', 'void', [param('ns3::Ptr< ns3::Object >', 'obj')]) + ## config.h: extern void ns3::Config::Disconnect(std::string path, ns3::CallbackBase const & cb) [free function] + module.add_function('Disconnect', 'void', [param('std::string', 'path'), param('ns3::CallbackBase&', 'cb', is_const=True)]) + return + +def register_functions_ns3_olsr(module, root_module): + return + diff --git a/bindings/python/ns3_module_csma.py b/bindings/python/ns3_module_csma.py new file mode 100644 index 000000000..ee4152eac --- /dev/null +++ b/bindings/python/ns3_module_csma.py @@ -0,0 +1,245 @@ +from pybindgen import Module, FileCodeSink, write_preamble, param, retval + +def register_types(module): + root_module = module.get_root() + + ## csma-channel.h: ns3::WireState [enumeration] + module.add_enum('WireState', ['IDLE', 'TRANSMITTING', 'PROPAGATING']) + ## csma-channel.h: ns3::CsmaDeviceRec [class] + module.add_class('CsmaDeviceRec') + ## backoff.h: ns3::Backoff [class] + module.add_class('Backoff') + ## csma-channel.h: ns3::CsmaChannel [class] + module.add_class('CsmaChannel', allow_subclassing=True, parent=root_module['ns3::Channel']) + ## csma-net-device.h: ns3::CsmaNetDevice [class] + module.add_class('CsmaNetDevice', allow_subclassing=True, parent=root_module['ns3::NetDevice']) + ## csma-net-device.h: ns3::CsmaNetDevice::CsmaEncapsulationMode [enumeration] + module.add_enum('CsmaEncapsulationMode', ['ETHERNET_V1', 'IP_ARP', 'RAW', 'LLC'], outer_class=root_module['ns3::CsmaNetDevice']) + + ## Register a nested module for the namespace internal + + nested_module = module.add_cpp_namespace('internal') + register_types_ns3_internal(nested_module) + + + ## Register a nested module for the namespace TimeStepPrecision + + nested_module = module.add_cpp_namespace('TimeStepPrecision') + register_types_ns3_TimeStepPrecision(nested_module) + + + ## Register a nested module for the namespace Config + + nested_module = module.add_cpp_namespace('Config') + register_types_ns3_Config(nested_module) + + + ## Register a nested module for the namespace olsr + + nested_module = module.add_cpp_namespace('olsr') + register_types_ns3_olsr(nested_module) + + +def register_types_ns3_internal(module): + root_module = module.get_root() + + +def register_types_ns3_TimeStepPrecision(module): + root_module = module.get_root() + + +def register_types_ns3_Config(module): + root_module = module.get_root() + + +def register_types_ns3_olsr(module): + root_module = module.get_root() + + +def register_methods(root_module): + register_Ns3CsmaDeviceRec_methods(root_module, root_module['ns3::CsmaDeviceRec']) + register_Ns3Backoff_methods(root_module, root_module['ns3::Backoff']) + register_Ns3CsmaChannel_methods(root_module, root_module['ns3::CsmaChannel']) + register_Ns3CsmaNetDevice_methods(root_module, root_module['ns3::CsmaNetDevice']) + return + +def register_Ns3CsmaDeviceRec_methods(root_module, cls): + ## csma-channel.h: ns3::CsmaDeviceRec::devicePtr [variable] + cls.add_instance_attribute('devicePtr', 'ns3::Ptr< ns3::CsmaNetDevice >', is_const=False) + ## csma-channel.h: ns3::CsmaDeviceRec::active [variable] + cls.add_instance_attribute('active', 'bool', is_const=False) + ## csma-channel.h: ns3::CsmaDeviceRec::CsmaDeviceRec() [constructor] + cls.add_constructor([], visibility='public') + ## csma-channel.h: ns3::CsmaDeviceRec::CsmaDeviceRec(ns3::Ptr device) [constructor] + cls.add_constructor([param('ns3::Ptr< ns3::CsmaNetDevice >', 'device')], visibility='public') + ## csma-channel.h: bool ns3::CsmaDeviceRec::IsActive() [member function] + cls.add_method('IsActive', 'bool', []) + return + +def register_Ns3Backoff_methods(root_module, cls): + ## backoff.h: ns3::Backoff::m_minSlots [variable] + cls.add_instance_attribute('m_minSlots', 'uint32_t', is_const=False) + ## backoff.h: ns3::Backoff::m_maxSlots [variable] + cls.add_instance_attribute('m_maxSlots', 'uint32_t', is_const=False) + ## backoff.h: ns3::Backoff::m_ceiling [variable] + cls.add_instance_attribute('m_ceiling', 'uint32_t', is_const=False) + ## backoff.h: ns3::Backoff::m_maxRetries [variable] + cls.add_instance_attribute('m_maxRetries', 'uint32_t', is_const=False) + ## backoff.h: ns3::Backoff::m_slotTime [variable] + cls.add_instance_attribute('m_slotTime', 'ns3::Time', is_const=False) + ## backoff.h: ns3::Backoff::Backoff() [constructor] + cls.add_constructor([], visibility='public') + ## backoff.h: ns3::Backoff::Backoff(ns3::Time slotTime, uint32_t minSlots, uint32_t maxSlots, uint32_t ceiling, uint32_t maxRetries) [constructor] + cls.add_constructor([param('ns3::Time', 'slotTime'), param('uint32_t', 'minSlots'), param('uint32_t', 'maxSlots'), param('uint32_t', 'ceiling'), param('uint32_t', 'maxRetries')], visibility='public') + ## backoff.h: ns3::Time ns3::Backoff::GetBackoffTime() [member function] + cls.add_method('GetBackoffTime', 'ns3::Time', []) + ## backoff.h: void ns3::Backoff::ResetBackoffTime() [member function] + cls.add_method('ResetBackoffTime', 'void', []) + ## backoff.h: bool ns3::Backoff::MaxRetriesReached() [member function] + cls.add_method('MaxRetriesReached', 'bool', []) + ## backoff.h: void ns3::Backoff::IncrNumRetries() [member function] + cls.add_method('IncrNumRetries', 'void', []) + return + +def register_Ns3CsmaChannel_methods(root_module, cls): + ## csma-channel.h: static ns3::TypeId ns3::CsmaChannel::GetTypeId() [member function] + cls.add_method('GetTypeId', 'ns3::TypeId', [], is_static=True) + ## csma-channel.h: ns3::CsmaChannel::CsmaChannel() [constructor] + cls.add_constructor([], visibility='public') + ## csma-channel.h: int32_t ns3::CsmaChannel::Attach(ns3::Ptr device) [member function] + cls.add_method('Attach', 'int32_t', [param('ns3::Ptr< ns3::CsmaNetDevice >', 'device')]) + ## csma-channel.h: bool ns3::CsmaChannel::Detach(ns3::Ptr device) [member function] + cls.add_method('Detach', 'bool', [param('ns3::Ptr< ns3::CsmaNetDevice >', 'device')]) + ## csma-channel.h: bool ns3::CsmaChannel::Detach(uint32_t deviceId) [member function] + cls.add_method('Detach', 'bool', [param('uint32_t', 'deviceId')]) + ## csma-channel.h: bool ns3::CsmaChannel::Reattach(uint32_t deviceId) [member function] + cls.add_method('Reattach', 'bool', [param('uint32_t', 'deviceId')]) + ## csma-channel.h: bool ns3::CsmaChannel::Reattach(ns3::Ptr device) [member function] + cls.add_method('Reattach', 'bool', [param('ns3::Ptr< ns3::CsmaNetDevice >', 'device')]) + ## csma-channel.h: bool ns3::CsmaChannel::TransmitStart(ns3::Ptr p, uint32_t srcId) [member function] + cls.add_method('TransmitStart', 'bool', [param('ns3::Ptr< ns3::Packet >', 'p'), param('uint32_t', 'srcId')]) + ## csma-channel.h: bool ns3::CsmaChannel::TransmitEnd() [member function] + cls.add_method('TransmitEnd', 'bool', []) + ## csma-channel.h: void ns3::CsmaChannel::PropagationCompleteEvent() [member function] + cls.add_method('PropagationCompleteEvent', 'void', []) + ## csma-channel.h: int32_t ns3::CsmaChannel::GetDeviceNum(ns3::Ptr device) [member function] + cls.add_method('GetDeviceNum', 'int32_t', [param('ns3::Ptr< ns3::CsmaNetDevice >', 'device')]) + ## csma-channel.h: ns3::WireState ns3::CsmaChannel::GetState() [member function] + cls.add_method('GetState', 'ns3::WireState', []) + ## csma-channel.h: bool ns3::CsmaChannel::IsBusy() [member function] + cls.add_method('IsBusy', 'bool', []) + ## csma-channel.h: bool ns3::CsmaChannel::IsActive(uint32_t deviceId) [member function] + cls.add_method('IsActive', 'bool', [param('uint32_t', 'deviceId')]) + ## csma-channel.h: uint32_t ns3::CsmaChannel::GetNumActDevices() [member function] + cls.add_method('GetNumActDevices', 'uint32_t', []) + ## csma-channel.h: uint32_t ns3::CsmaChannel::GetNDevices() const [member function] + cls.add_method('GetNDevices', 'uint32_t', [], is_const=True, is_virtual=True) + ## csma-channel.h: ns3::Ptr ns3::CsmaChannel::GetDevice(uint32_t i) const [member function] + cls.add_method('GetDevice', 'ns3::Ptr< ns3::NetDevice >', [param('uint32_t', 'i')], is_const=True, is_virtual=True) + ## csma-channel.h: ns3::Ptr ns3::CsmaChannel::GetCsmaDevice(uint32_t i) const [member function] + cls.add_method('GetCsmaDevice', 'ns3::Ptr< ns3::CsmaNetDevice >', [param('uint32_t', 'i')], is_const=True) + ## csma-channel.h: ns3::DataRate ns3::CsmaChannel::GetDataRate() [member function] + cls.add_method('GetDataRate', 'ns3::DataRate', [], is_virtual=True) + ## csma-channel.h: ns3::Time ns3::CsmaChannel::GetDelay() [member function] + cls.add_method('GetDelay', 'ns3::Time', [], is_virtual=True) + return + +def register_Ns3CsmaNetDevice_methods(root_module, cls): + ## csma-net-device.h: static ns3::TypeId ns3::CsmaNetDevice::GetTypeId() [member function] + cls.add_method('GetTypeId', 'ns3::TypeId', [], is_static=True) + ## csma-net-device.h: ns3::CsmaNetDevice::CsmaNetDevice() [constructor] + cls.add_constructor([], visibility='public') + ## csma-net-device.h: void ns3::CsmaNetDevice::SetInterframeGap(ns3::Time t) [member function] + cls.add_method('SetInterframeGap', 'void', [param('ns3::Time', 't')]) + ## csma-net-device.h: void ns3::CsmaNetDevice::SetBackoffParams(ns3::Time slotTime, uint32_t minSlots, uint32_t maxSlots, uint32_t maxRetries, uint32_t ceiling) [member function] + cls.add_method('SetBackoffParams', 'void', [param('ns3::Time', 'slotTime'), param('uint32_t', 'minSlots'), param('uint32_t', 'maxSlots'), param('uint32_t', 'maxRetries'), param('uint32_t', 'ceiling')]) + ## csma-net-device.h: bool ns3::CsmaNetDevice::Attach(ns3::Ptr ch) [member function] + cls.add_method('Attach', 'bool', [param('ns3::Ptr< ns3::CsmaChannel >', 'ch')]) + ## csma-net-device.h: void ns3::CsmaNetDevice::SetQueue(ns3::Ptr queue) [member function] + cls.add_method('SetQueue', 'void', [param('ns3::Ptr< ns3::Queue >', 'queue')]) + ## csma-net-device.h: void ns3::CsmaNetDevice::SetReceiveErrorModel(ns3::Ptr em) [member function] + cls.add_method('SetReceiveErrorModel', 'void', [param('ns3::Ptr< ns3::ErrorModel >', 'em')]) + ## csma-net-device.h: void ns3::CsmaNetDevice::Receive(ns3::Ptr p) [member function] + cls.add_method('Receive', 'void', [param('ns3::Ptr< ns3::Packet >', 'p')]) + ## csma-net-device.h: bool ns3::CsmaNetDevice::IsSendEnabled() [member function] + cls.add_method('IsSendEnabled', 'bool', []) + ## csma-net-device.h: void ns3::CsmaNetDevice::SetSendEnable(bool enable) [member function] + cls.add_method('SetSendEnable', 'void', [param('bool', 'enable')]) + ## csma-net-device.h: bool ns3::CsmaNetDevice::IsReceiveEnabled() [member function] + cls.add_method('IsReceiveEnabled', 'bool', []) + ## csma-net-device.h: void ns3::CsmaNetDevice::SetReceiveEnable(bool enable) [member function] + cls.add_method('SetReceiveEnable', 'void', [param('bool', 'enable')]) + ## csma-net-device.h: void ns3::CsmaNetDevice::SetAddress(ns3::Mac48Address addr) [member function] + cls.add_method('SetAddress', 'void', [param('ns3::Mac48Address', 'addr')]) + ## csma-net-device.h: void ns3::CsmaNetDevice::SetName(std::string const name) [member function] + cls.add_method('SetName', 'void', [param('std::string', 'name', is_const=True)], is_virtual=True) + ## csma-net-device.h: std::string ns3::CsmaNetDevice::GetName() const [member function] + cls.add_method('GetName', 'std::string', [], is_const=True, is_virtual=True) + ## csma-net-device.h: void ns3::CsmaNetDevice::SetIfIndex(uint32_t const index) [member function] + cls.add_method('SetIfIndex', 'void', [param('uint32_t', 'index', is_const=True)], is_virtual=True) + ## csma-net-device.h: uint32_t ns3::CsmaNetDevice::GetIfIndex() const [member function] + cls.add_method('GetIfIndex', 'uint32_t', [], is_const=True, is_virtual=True) + ## csma-net-device.h: ns3::Ptr ns3::CsmaNetDevice::GetChannel() const [member function] + cls.add_method('GetChannel', 'ns3::Ptr< ns3::Channel >', [], is_const=True, is_virtual=True) + ## csma-net-device.h: ns3::Address ns3::CsmaNetDevice::GetAddress() const [member function] + cls.add_method('GetAddress', 'ns3::Address', [], is_const=True, is_virtual=True) + ## csma-net-device.h: bool ns3::CsmaNetDevice::SetMtu(uint16_t const mtu) [member function] + cls.add_method('SetMtu', 'bool', [param('uint16_t', 'mtu', is_const=True)], is_virtual=True) + ## csma-net-device.h: uint16_t ns3::CsmaNetDevice::GetMtu() const [member function] + cls.add_method('GetMtu', 'uint16_t', [], is_const=True, is_virtual=True) + ## csma-net-device.h: bool ns3::CsmaNetDevice::IsLinkUp() const [member function] + cls.add_method('IsLinkUp', 'bool', [], is_const=True, is_virtual=True) + ## csma-net-device.h: void ns3::CsmaNetDevice::SetLinkChangeCallback(ns3::Callback callback) [member function] + cls.add_method('SetLinkChangeCallback', 'void', [param('ns3::Callback< void, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty >', 'callback')], is_virtual=True) + ## csma-net-device.h: bool ns3::CsmaNetDevice::IsBroadcast() const [member function] + cls.add_method('IsBroadcast', 'bool', [], is_const=True, is_virtual=True) + ## csma-net-device.h: ns3::Address ns3::CsmaNetDevice::GetBroadcast() const [member function] + cls.add_method('GetBroadcast', 'ns3::Address', [], is_const=True, is_virtual=True) + ## csma-net-device.h: bool ns3::CsmaNetDevice::IsMulticast() const [member function] + cls.add_method('IsMulticast', 'bool', [], is_const=True, is_virtual=True) + ## csma-net-device.h: ns3::Address ns3::CsmaNetDevice::GetMulticast() const [member function] + cls.add_method('GetMulticast', 'ns3::Address', [], is_const=True, is_virtual=True) + ## csma-net-device.h: ns3::Address ns3::CsmaNetDevice::MakeMulticastAddress(ns3::Ipv4Address multicastGroup) const [member function] + cls.add_method('MakeMulticastAddress', 'ns3::Address', [param('ns3::Ipv4Address', 'multicastGroup')], is_const=True, is_virtual=True) + ## csma-net-device.h: bool ns3::CsmaNetDevice::IsPointToPoint() const [member function] + cls.add_method('IsPointToPoint', 'bool', [], is_const=True, is_virtual=True) + ## csma-net-device.h: bool ns3::CsmaNetDevice::Send(ns3::Ptr packet, ns3::Address const & dest, uint16_t protocolNumber) [member function] + cls.add_method('Send', 'bool', [param('ns3::Ptr< ns3::Packet >', 'packet'), param('ns3::Address&', 'dest', is_const=True), param('uint16_t', 'protocolNumber')], is_virtual=True) + ## csma-net-device.h: ns3::Ptr ns3::CsmaNetDevice::GetNode() const [member function] + cls.add_method('GetNode', 'ns3::Ptr< ns3::Node >', [], is_const=True, is_virtual=True) + ## csma-net-device.h: void ns3::CsmaNetDevice::SetNode(ns3::Ptr node) [member function] + cls.add_method('SetNode', 'void', [param('ns3::Ptr< ns3::Node >', 'node')], is_virtual=True) + ## csma-net-device.h: bool ns3::CsmaNetDevice::NeedsArp() const [member function] + cls.add_method('NeedsArp', 'bool', [], is_const=True, is_virtual=True) + ## csma-net-device.h: void ns3::CsmaNetDevice::SetReceiveCallback(ns3::Callback, ns3::Ptr, unsigned short, ns3::Address const&, ns3::empty, ns3::empty> cb) [member function] + cls.add_method('SetReceiveCallback', 'void', [param('ns3::Callback< bool, ns3::Ptr< ns3::NetDevice >, ns3::Ptr< ns3::Packet >, unsigned short, ns3::Address const&, ns3::empty, ns3::empty >', 'cb')], is_virtual=True) + ## csma-net-device.h: void ns3::CsmaNetDevice::DoDispose() [member function] + cls.add_method('DoDispose', 'void', [], visibility='protected', is_virtual=True) + ## csma-net-device.h: ns3::Ptr ns3::CsmaNetDevice::GetQueue() const [member function] + cls.add_method('GetQueue', 'ns3::Ptr< ns3::Queue >', [], is_const=True, visibility='protected') + ## csma-net-device.h: void ns3::CsmaNetDevice::AddHeader(ns3::Ptr p, ns3::Mac48Address dest, uint16_t protocolNumber) [member function] + cls.add_method('AddHeader', 'void', [param('ns3::Ptr< ns3::Packet >', 'p'), param('ns3::Mac48Address', 'dest'), param('uint16_t', 'protocolNumber')], visibility='protected') + ## csma-net-device.h: bool ns3::CsmaNetDevice::ProcessHeader(ns3::Ptr p, uint16_t & param) [member function] + cls.add_method('ProcessHeader', 'bool', [param('ns3::Ptr< ns3::Packet >', 'p'), param('uint16_t&', 'param')], visibility='protected') + return + +def register_functions(root_module): + module = root_module + register_functions_ns3_internal(module.get_submodule('internal'), root_module) + register_functions_ns3_TimeStepPrecision(module.get_submodule('TimeStepPrecision'), root_module) + register_functions_ns3_Config(module.get_submodule('Config'), root_module) + register_functions_ns3_olsr(module.get_submodule('olsr'), root_module) + return + +def register_functions_ns3_internal(module, root_module): + return + +def register_functions_ns3_TimeStepPrecision(module, root_module): + return + +def register_functions_ns3_Config(module, root_module): + return + +def register_functions_ns3_olsr(module, root_module): + return + diff --git a/bindings/python/ns3_module_global_routing.py b/bindings/python/ns3_module_global_routing.py new file mode 100644 index 000000000..026ea0ac0 --- /dev/null +++ b/bindings/python/ns3_module_global_routing.py @@ -0,0 +1,184 @@ +from pybindgen import Module, FileCodeSink, write_preamble, param, retval + +def register_types(module): + root_module = module.get_root() + + ## global-route-manager.h: ns3::GlobalRouteManager [class] + module.add_class('GlobalRouteManager') + ## global-router-interface.h: ns3::GlobalRoutingLSA [class] + module.add_class('GlobalRoutingLSA') + ## global-router-interface.h: ns3::GlobalRoutingLSA::LSType [enumeration] + module.add_enum('LSType', ['Unknown', 'RouterLSA', 'NetworkLSA', 'SummaryLSA', 'SummaryLSA_ASBR', 'ASExternalLSAs'], outer_class=root_module['ns3::GlobalRoutingLSA']) + ## global-router-interface.h: ns3::GlobalRoutingLSA::SPFStatus [enumeration] + module.add_enum('SPFStatus', ['LSA_SPF_NOT_EXPLORED', 'LSA_SPF_CANDIDATE', 'LSA_SPF_IN_SPFTREE'], outer_class=root_module['ns3::GlobalRoutingLSA']) + ## global-router-interface.h: ns3::GlobalRoutingLinkRecord [class] + module.add_class('GlobalRoutingLinkRecord') + ## global-router-interface.h: ns3::GlobalRoutingLinkRecord::LinkType [enumeration] + module.add_enum('LinkType', ['Unknown', 'PointToPoint', 'TransitNetwork', 'StubNetwork', 'VirtualLink'], outer_class=root_module['ns3::GlobalRoutingLinkRecord']) + ## global-router-interface.h: ns3::GlobalRouter [class] + module.add_class('GlobalRouter', allow_subclassing=True, is_singleton=True, parent=root_module['ns3::Object']) + + ## Register a nested module for the namespace internal + + nested_module = module.add_cpp_namespace('internal') + register_types_ns3_internal(nested_module) + + + ## Register a nested module for the namespace TimeStepPrecision + + nested_module = module.add_cpp_namespace('TimeStepPrecision') + register_types_ns3_TimeStepPrecision(nested_module) + + + ## Register a nested module for the namespace Config + + nested_module = module.add_cpp_namespace('Config') + register_types_ns3_Config(nested_module) + + + ## Register a nested module for the namespace olsr + + nested_module = module.add_cpp_namespace('olsr') + register_types_ns3_olsr(nested_module) + + +def register_types_ns3_internal(module): + root_module = module.get_root() + + +def register_types_ns3_TimeStepPrecision(module): + root_module = module.get_root() + + +def register_types_ns3_Config(module): + root_module = module.get_root() + + +def register_types_ns3_olsr(module): + root_module = module.get_root() + + +def register_methods(root_module): + register_Ns3GlobalRouteManager_methods(root_module, root_module['ns3::GlobalRouteManager']) + register_Ns3GlobalRoutingLSA_methods(root_module, root_module['ns3::GlobalRoutingLSA']) + register_Ns3GlobalRoutingLinkRecord_methods(root_module, root_module['ns3::GlobalRoutingLinkRecord']) + register_Ns3GlobalRouter_methods(root_module, root_module['ns3::GlobalRouter']) + return + +def register_Ns3GlobalRouteManager_methods(root_module, cls): + ## global-route-manager.h: static void ns3::GlobalRouteManager::PopulateRoutingTables() [member function] + cls.add_method('PopulateRoutingTables', 'void', [], is_static=True) + ## global-route-manager.h: static uint32_t ns3::GlobalRouteManager::AllocateRouterId() [member function] + cls.add_method('AllocateRouterId', 'uint32_t', [], is_static=True) + return + +def register_Ns3GlobalRoutingLSA_methods(root_module, cls): + ## global-router-interface.h: ns3::GlobalRoutingLSA::GlobalRoutingLSA() [constructor] + cls.add_constructor([], visibility='public') + ## global-router-interface.h: ns3::GlobalRoutingLSA::GlobalRoutingLSA(ns3::GlobalRoutingLSA::SPFStatus status, ns3::Ipv4Address linkStateId, ns3::Ipv4Address advertisingRtr) [constructor] + cls.add_constructor([param('ns3::GlobalRoutingLSA::SPFStatus', 'status'), param('ns3::Ipv4Address', 'linkStateId'), param('ns3::Ipv4Address', 'advertisingRtr')], visibility='public') + ## global-router-interface.h: ns3::GlobalRoutingLSA::GlobalRoutingLSA(ns3::GlobalRoutingLSA & lsa) [constructor] + cls.add_constructor([param('ns3::GlobalRoutingLSA&', 'lsa')], visibility='public') + ## global-router-interface.h: uint32_t ns3::GlobalRoutingLSA::AddAttachedRouter(ns3::Ipv4Address addr) [member function] + cls.add_method('AddAttachedRouter', 'uint32_t', [param('ns3::Ipv4Address', 'addr')]) + ## global-router-interface.h: uint32_t ns3::GlobalRoutingLSA::AddLinkRecord(ns3::GlobalRoutingLinkRecord * lr) [member function] + cls.add_method('AddLinkRecord', 'uint32_t', [param('ns3::GlobalRoutingLinkRecord *', 'lr')]) + ## global-router-interface.h: void ns3::GlobalRoutingLSA::ClearLinkRecords() [member function] + cls.add_method('ClearLinkRecords', 'void', []) + ## global-router-interface.h: void ns3::GlobalRoutingLSA::CopyLinkRecords(ns3::GlobalRoutingLSA const & lsa) [member function] + cls.add_method('CopyLinkRecords', 'void', [param('ns3::GlobalRoutingLSA&', 'lsa', is_const=True)]) + ## global-router-interface.h: ns3::Ipv4Address ns3::GlobalRoutingLSA::GetAdvertisingRouter() const [member function] + cls.add_method('GetAdvertisingRouter', 'ns3::Ipv4Address', [], is_const=True) + ## global-router-interface.h: ns3::Ipv4Address ns3::GlobalRoutingLSA::GetAttachedRouter(uint32_t n) const [member function] + cls.add_method('GetAttachedRouter', 'ns3::Ipv4Address', [param('uint32_t', 'n')], is_const=True) + ## global-router-interface.h: ns3::GlobalRoutingLSA::LSType ns3::GlobalRoutingLSA::GetLSType() const [member function] + cls.add_method('GetLSType', 'ns3::GlobalRoutingLSA::LSType', [], is_const=True) + ## global-router-interface.h: ns3::GlobalRoutingLinkRecord * ns3::GlobalRoutingLSA::GetLinkRecord(uint32_t n) const [member function] + cls.add_method('GetLinkRecord', 'ns3::GlobalRoutingLinkRecord *', [param('uint32_t', 'n')], is_const=True) + ## global-router-interface.h: ns3::Ipv4Address ns3::GlobalRoutingLSA::GetLinkStateId() const [member function] + cls.add_method('GetLinkStateId', 'ns3::Ipv4Address', [], is_const=True) + ## global-router-interface.h: uint32_t ns3::GlobalRoutingLSA::GetNAttachedRouters() const [member function] + cls.add_method('GetNAttachedRouters', 'uint32_t', [], is_const=True) + ## global-router-interface.h: uint32_t ns3::GlobalRoutingLSA::GetNLinkRecords() const [member function] + cls.add_method('GetNLinkRecords', 'uint32_t', [], is_const=True) + ## global-router-interface.h: ns3::Ipv4Mask ns3::GlobalRoutingLSA::GetNetworkLSANetworkMask() const [member function] + cls.add_method('GetNetworkLSANetworkMask', 'ns3::Ipv4Mask', [], is_const=True) + ## global-router-interface.h: ns3::GlobalRoutingLSA::SPFStatus ns3::GlobalRoutingLSA::GetStatus() const [member function] + cls.add_method('GetStatus', 'ns3::GlobalRoutingLSA::SPFStatus', [], is_const=True) + ## global-router-interface.h: bool ns3::GlobalRoutingLSA::IsEmpty() const [member function] + cls.add_method('IsEmpty', 'bool', [], is_const=True) + ## global-router-interface.h: void ns3::GlobalRoutingLSA::Print(std::ostream & os) const [member function] + cls.add_method('Print', 'void', [param('std::ostream&', 'os')], is_const=True) + ## global-router-interface.h: void ns3::GlobalRoutingLSA::SetAdvertisingRouter(ns3::Ipv4Address rtr) [member function] + cls.add_method('SetAdvertisingRouter', 'void', [param('ns3::Ipv4Address', 'rtr')]) + ## global-router-interface.h: void ns3::GlobalRoutingLSA::SetLSType(ns3::GlobalRoutingLSA::LSType typ) [member function] + cls.add_method('SetLSType', 'void', [param('ns3::GlobalRoutingLSA::LSType', 'typ')]) + ## global-router-interface.h: void ns3::GlobalRoutingLSA::SetLinkStateId(ns3::Ipv4Address addr) [member function] + cls.add_method('SetLinkStateId', 'void', [param('ns3::Ipv4Address', 'addr')]) + ## global-router-interface.h: void ns3::GlobalRoutingLSA::SetNetworkLSANetworkMask(ns3::Ipv4Mask mask) [member function] + cls.add_method('SetNetworkLSANetworkMask', 'void', [param('ns3::Ipv4Mask', 'mask')]) + ## global-router-interface.h: void ns3::GlobalRoutingLSA::SetStatus(ns3::GlobalRoutingLSA::SPFStatus status) [member function] + cls.add_method('SetStatus', 'void', [param('ns3::GlobalRoutingLSA::SPFStatus', 'status')]) + cls.add_output_stream_operator() + return + +def register_Ns3GlobalRoutingLinkRecord_methods(root_module, cls): + ## global-router-interface.h: ns3::GlobalRoutingLinkRecord::GlobalRoutingLinkRecord() [constructor] + cls.add_constructor([], visibility='public') + ## global-router-interface.h: ns3::GlobalRoutingLinkRecord::GlobalRoutingLinkRecord(ns3::GlobalRoutingLinkRecord::LinkType linkType, ns3::Ipv4Address linkId, ns3::Ipv4Address linkData, uint16_t metric) [constructor] + cls.add_constructor([param('ns3::GlobalRoutingLinkRecord::LinkType', 'linkType'), param('ns3::Ipv4Address', 'linkId'), param('ns3::Ipv4Address', 'linkData'), param('uint16_t', 'metric')], visibility='public') + ## global-router-interface.h: ns3::Ipv4Address ns3::GlobalRoutingLinkRecord::GetLinkId() const [member function] + cls.add_method('GetLinkId', 'ns3::Ipv4Address', [], is_const=True) + ## global-router-interface.h: void ns3::GlobalRoutingLinkRecord::SetLinkId(ns3::Ipv4Address addr) [member function] + cls.add_method('SetLinkId', 'void', [param('ns3::Ipv4Address', 'addr')]) + ## global-router-interface.h: ns3::Ipv4Address ns3::GlobalRoutingLinkRecord::GetLinkData() const [member function] + cls.add_method('GetLinkData', 'ns3::Ipv4Address', [], is_const=True) + ## global-router-interface.h: void ns3::GlobalRoutingLinkRecord::SetLinkData(ns3::Ipv4Address addr) [member function] + cls.add_method('SetLinkData', 'void', [param('ns3::Ipv4Address', 'addr')]) + ## global-router-interface.h: ns3::GlobalRoutingLinkRecord::LinkType ns3::GlobalRoutingLinkRecord::GetLinkType() const [member function] + cls.add_method('GetLinkType', 'ns3::GlobalRoutingLinkRecord::LinkType', [], is_const=True) + ## global-router-interface.h: void ns3::GlobalRoutingLinkRecord::SetLinkType(ns3::GlobalRoutingLinkRecord::LinkType linkType) [member function] + cls.add_method('SetLinkType', 'void', [param('ns3::GlobalRoutingLinkRecord::LinkType', 'linkType')]) + ## global-router-interface.h: uint16_t ns3::GlobalRoutingLinkRecord::GetMetric() const [member function] + cls.add_method('GetMetric', 'uint16_t', [], is_const=True) + ## global-router-interface.h: void ns3::GlobalRoutingLinkRecord::SetMetric(uint16_t metric) [member function] + cls.add_method('SetMetric', 'void', [param('uint16_t', 'metric')]) + return + +def register_Ns3GlobalRouter_methods(root_module, cls): + ## global-router-interface.h: static ns3::TypeId ns3::GlobalRouter::GetTypeId() [member function] + cls.add_method('GetTypeId', 'ns3::TypeId', [], is_static=True) + ## global-router-interface.h: ns3::GlobalRouter::GlobalRouter() [constructor] + cls.add_constructor([], visibility='public') + ## global-router-interface.h: ns3::Ipv4Address ns3::GlobalRouter::GetRouterId() const [member function] + cls.add_method('GetRouterId', 'ns3::Ipv4Address', [], is_const=True) + ## global-router-interface.h: uint32_t ns3::GlobalRouter::DiscoverLSAs() [member function] + cls.add_method('DiscoverLSAs', 'uint32_t', []) + ## global-router-interface.h: uint32_t ns3::GlobalRouter::GetNumLSAs() const [member function] + cls.add_method('GetNumLSAs', 'uint32_t', [], is_const=True) + ## global-router-interface.h: bool ns3::GlobalRouter::GetLSA(uint32_t n, ns3::GlobalRoutingLSA & lsa) const [member function] + cls.add_method('GetLSA', 'bool', [param('uint32_t', 'n'), param('ns3::GlobalRoutingLSA&', 'lsa')], is_const=True) + ## global-router-interface.h: void ns3::GlobalRouter::DoDispose() [member function] + cls.add_method('DoDispose', 'void', [], visibility='private', is_virtual=True) + return + +def register_functions(root_module): + module = root_module + register_functions_ns3_internal(module.get_submodule('internal'), root_module) + register_functions_ns3_TimeStepPrecision(module.get_submodule('TimeStepPrecision'), root_module) + register_functions_ns3_Config(module.get_submodule('Config'), root_module) + register_functions_ns3_olsr(module.get_submodule('olsr'), root_module) + return + +def register_functions_ns3_internal(module, root_module): + return + +def register_functions_ns3_TimeStepPrecision(module, root_module): + return + +def register_functions_ns3_Config(module, root_module): + return + +def register_functions_ns3_olsr(module, root_module): + return + diff --git a/bindings/python/ns3_module_helper.py b/bindings/python/ns3_module_helper.py new file mode 100644 index 000000000..ca1ce24f0 --- /dev/null +++ b/bindings/python/ns3_module_helper.py @@ -0,0 +1,409 @@ +from pybindgen import Module, FileCodeSink, write_preamble, param, retval + +def register_types(module): + root_module = module.get_root() + + ## mobility-helper.h: ns3::MobilityHelper [class] + module.add_class('MobilityHelper', allow_subclassing=False) + ## internet-stack-helper.h: ns3::InternetStackHelper [class] + module.add_class('InternetStackHelper', allow_subclassing=False) + ## node-container.h: ns3::NodeContainer [class] + module.add_class('NodeContainer') + ## point-to-point-helper.h: ns3::PointToPointHelper [class] + module.add_class('PointToPointHelper', allow_subclassing=False) + ## net-device-container.h: ns3::NetDeviceContainer [class] + module.add_class('NetDeviceContainer') + ## csma-helper.h: ns3::CsmaHelper [class] + module.add_class('CsmaHelper', allow_subclassing=False) + ## udp-echo-helper.h: ns3::UdpEchoServerHelper [class] + module.add_class('UdpEchoServerHelper', allow_subclassing=False) + ## olsr-helper.h: ns3::OlsrHelper [class] + module.add_class('OlsrHelper', allow_subclassing=False) + ## packet-socket-helper.h: ns3::PacketSocketHelper [class] + module.add_class('PacketSocketHelper', allow_subclassing=False) + ## on-off-helper.h: ns3::OnOffHelper [class] + module.add_class('OnOffHelper', allow_subclassing=False) + ## udp-echo-helper.h: ns3::UdpEchoClientHelper [class] + module.add_class('UdpEchoClientHelper', allow_subclassing=False) + ## static-multicast-route-helper.h: ns3::StaticMulticastRouteHelper [class] + module.add_class('StaticMulticastRouteHelper', allow_subclassing=False) + ## ipv4-interface-container.h: ns3::Ipv4InterfaceContainer [class] + module.add_class('Ipv4InterfaceContainer') + ## application-container.h: ns3::ApplicationContainer [class] + module.add_class('ApplicationContainer') + ## wifi-helper.h: ns3::WifiHelper [class] + module.add_class('WifiHelper', allow_subclassing=False) + ## ipv4-address-helper.h: ns3::Ipv4AddressHelper [class] + module.add_class('Ipv4AddressHelper', allow_subclassing=False) + ## packet-sink-helper.h: ns3::PacketSinkHelper [class] + module.add_class('PacketSinkHelper', allow_subclassing=False) + ## ns2-mobility-helper.h: ns3::Ns2MobilityHelper [class] + module.add_class('Ns2MobilityHelper', allow_subclassing=False) + + ## Register a nested module for the namespace internal + + nested_module = module.add_cpp_namespace('internal') + register_types_ns3_internal(nested_module) + + + ## Register a nested module for the namespace TimeStepPrecision + + nested_module = module.add_cpp_namespace('TimeStepPrecision') + register_types_ns3_TimeStepPrecision(nested_module) + + + ## Register a nested module for the namespace Config + + nested_module = module.add_cpp_namespace('Config') + register_types_ns3_Config(nested_module) + + + ## Register a nested module for the namespace olsr + + nested_module = module.add_cpp_namespace('olsr') + register_types_ns3_olsr(nested_module) + + +def register_types_ns3_internal(module): + root_module = module.get_root() + + +def register_types_ns3_TimeStepPrecision(module): + root_module = module.get_root() + + +def register_types_ns3_Config(module): + root_module = module.get_root() + + +def register_types_ns3_olsr(module): + root_module = module.get_root() + + +def register_methods(root_module): + register_Ns3MobilityHelper_methods(root_module, root_module['ns3::MobilityHelper']) + register_Ns3InternetStackHelper_methods(root_module, root_module['ns3::InternetStackHelper']) + register_Ns3NodeContainer_methods(root_module, root_module['ns3::NodeContainer']) + register_Ns3PointToPointHelper_methods(root_module, root_module['ns3::PointToPointHelper']) + register_Ns3NetDeviceContainer_methods(root_module, root_module['ns3::NetDeviceContainer']) + register_Ns3CsmaHelper_methods(root_module, root_module['ns3::CsmaHelper']) + register_Ns3UdpEchoServerHelper_methods(root_module, root_module['ns3::UdpEchoServerHelper']) + register_Ns3OlsrHelper_methods(root_module, root_module['ns3::OlsrHelper']) + register_Ns3PacketSocketHelper_methods(root_module, root_module['ns3::PacketSocketHelper']) + register_Ns3OnOffHelper_methods(root_module, root_module['ns3::OnOffHelper']) + register_Ns3UdpEchoClientHelper_methods(root_module, root_module['ns3::UdpEchoClientHelper']) + register_Ns3StaticMulticastRouteHelper_methods(root_module, root_module['ns3::StaticMulticastRouteHelper']) + register_Ns3Ipv4InterfaceContainer_methods(root_module, root_module['ns3::Ipv4InterfaceContainer']) + register_Ns3ApplicationContainer_methods(root_module, root_module['ns3::ApplicationContainer']) + register_Ns3WifiHelper_methods(root_module, root_module['ns3::WifiHelper']) + register_Ns3Ipv4AddressHelper_methods(root_module, root_module['ns3::Ipv4AddressHelper']) + register_Ns3PacketSinkHelper_methods(root_module, root_module['ns3::PacketSinkHelper']) + register_Ns3Ns2MobilityHelper_methods(root_module, root_module['ns3::Ns2MobilityHelper']) + return + +def register_Ns3MobilityHelper_methods(root_module, cls): + ## mobility-helper.h: ns3::MobilityHelper::MobilityHelper() [constructor] + cls.add_constructor([], visibility='public') + ## mobility-helper.h: void ns3::MobilityHelper::SetPositionAllocator(ns3::Ptr allocator) [member function] + cls.add_method('SetPositionAllocator', 'void', [param('ns3::Ptr< ns3::PositionAllocator >', 'allocator')]) + ## mobility-helper.h: void ns3::MobilityHelper::SetPositionAllocator(std::string type, std::string n1="", ns3::AttributeValue const & v1=ns3::EmptyAttributeValue(), std::string n2="", ns3::AttributeValue const & v2=ns3::EmptyAttributeValue(), std::string n3="", ns3::AttributeValue const & v3=ns3::EmptyAttributeValue(), std::string n4="", ns3::AttributeValue const & v4=ns3::EmptyAttributeValue(), std::string n5="", ns3::AttributeValue const & v5=ns3::EmptyAttributeValue(), std::string n6="", ns3::AttributeValue const & v6=ns3::EmptyAttributeValue(), std::string n7="", ns3::AttributeValue const & v7=ns3::EmptyAttributeValue(), std::string n8="", ns3::AttributeValue const & v8=ns3::EmptyAttributeValue(), std::string n9="", ns3::AttributeValue const & v9=ns3::EmptyAttributeValue()) [member function] + cls.add_method('SetPositionAllocator', 'void', [param('std::string', 'type'), param('std::string', 'n1', default_value='""'), param('ns3::AttributeValue&', 'v1', default_value='ns3::EmptyAttributeValue()', is_const=True), param('std::string', 'n2', default_value='""'), param('ns3::AttributeValue&', 'v2', default_value='ns3::EmptyAttributeValue()', is_const=True), param('std::string', 'n3', default_value='""'), param('ns3::AttributeValue&', 'v3', default_value='ns3::EmptyAttributeValue()', is_const=True), param('std::string', 'n4', default_value='""'), param('ns3::AttributeValue&', 'v4', default_value='ns3::EmptyAttributeValue()', is_const=True), param('std::string', 'n5', default_value='""'), param('ns3::AttributeValue&', 'v5', default_value='ns3::EmptyAttributeValue()', is_const=True), param('std::string', 'n6', default_value='""'), param('ns3::AttributeValue&', 'v6', default_value='ns3::EmptyAttributeValue()', is_const=True), param('std::string', 'n7', default_value='""'), param('ns3::AttributeValue&', 'v7', default_value='ns3::EmptyAttributeValue()', is_const=True), param('std::string', 'n8', default_value='""'), param('ns3::AttributeValue&', 'v8', default_value='ns3::EmptyAttributeValue()', is_const=True), param('std::string', 'n9', default_value='""'), param('ns3::AttributeValue&', 'v9', default_value='ns3::EmptyAttributeValue()', is_const=True)]) + ## mobility-helper.h: void ns3::MobilityHelper::SetMobilityModel(std::string type, std::string n1="", ns3::AttributeValue const & v1=ns3::EmptyAttributeValue(), std::string n2="", ns3::AttributeValue const & v2=ns3::EmptyAttributeValue(), std::string n3="", ns3::AttributeValue const & v3=ns3::EmptyAttributeValue(), std::string n4="", ns3::AttributeValue const & v4=ns3::EmptyAttributeValue(), std::string n5="", ns3::AttributeValue const & v5=ns3::EmptyAttributeValue(), std::string n6="", ns3::AttributeValue const & v6=ns3::EmptyAttributeValue(), std::string n7="", ns3::AttributeValue const & v7=ns3::EmptyAttributeValue(), std::string n8="", ns3::AttributeValue const & v8=ns3::EmptyAttributeValue(), std::string n9="", ns3::AttributeValue const & v9=ns3::EmptyAttributeValue()) [member function] + cls.add_method('SetMobilityModel', 'void', [param('std::string', 'type'), param('std::string', 'n1', default_value='""'), param('ns3::AttributeValue&', 'v1', default_value='ns3::EmptyAttributeValue()', is_const=True), param('std::string', 'n2', default_value='""'), param('ns3::AttributeValue&', 'v2', default_value='ns3::EmptyAttributeValue()', is_const=True), param('std::string', 'n3', default_value='""'), param('ns3::AttributeValue&', 'v3', default_value='ns3::EmptyAttributeValue()', is_const=True), param('std::string', 'n4', default_value='""'), param('ns3::AttributeValue&', 'v4', default_value='ns3::EmptyAttributeValue()', is_const=True), param('std::string', 'n5', default_value='""'), param('ns3::AttributeValue&', 'v5', default_value='ns3::EmptyAttributeValue()', is_const=True), param('std::string', 'n6', default_value='""'), param('ns3::AttributeValue&', 'v6', default_value='ns3::EmptyAttributeValue()', is_const=True), param('std::string', 'n7', default_value='""'), param('ns3::AttributeValue&', 'v7', default_value='ns3::EmptyAttributeValue()', is_const=True), param('std::string', 'n8', default_value='""'), param('ns3::AttributeValue&', 'v8', default_value='ns3::EmptyAttributeValue()', is_const=True), param('std::string', 'n9', default_value='""'), param('ns3::AttributeValue&', 'v9', default_value='ns3::EmptyAttributeValue()', is_const=True)]) + ## mobility-helper.h: void ns3::MobilityHelper::PushReferenceMobilityModel(ns3::Ptr reference) [member function] + cls.add_method('PushReferenceMobilityModel', 'void', [param('ns3::Ptr< ns3::Object >', 'reference')]) + ## mobility-helper.h: void ns3::MobilityHelper::PopReferenceMobilityModel() [member function] + cls.add_method('PopReferenceMobilityModel', 'void', []) + ## mobility-helper.h: std::string ns3::MobilityHelper::GetMobilityModelType() const [member function] + cls.add_method('GetMobilityModelType', 'std::string', [], is_const=True) + ## mobility-helper.h: void ns3::MobilityHelper::Install(ns3::NodeContainer container) [member function] + cls.add_method('Install', 'void', [param('ns3::NodeContainer', 'container')]) + ## mobility-helper.h: void ns3::MobilityHelper::InstallAll() [member function] + cls.add_method('InstallAll', 'void', []) + return + +def register_Ns3InternetStackHelper_methods(root_module, cls): + ## internet-stack-helper.h: void ns3::InternetStackHelper::Install(ns3::NodeContainer c) [member function] + cls.add_method('Install', 'void', [param('ns3::NodeContainer', 'c')]) + ## internet-stack-helper.h: static void ns3::InternetStackHelper::EnablePcapAll(std::string filename) [member function] + cls.add_method('EnablePcapAll', 'void', [param('std::string', 'filename')], is_static=True) + cls.add_constructor([]) + return + +def register_Ns3NodeContainer_methods(root_module, cls): + ## node-container.h: ns3::NodeContainer::NodeContainer() [constructor] + cls.add_constructor([], visibility='public') + ## node-container.h: ns3::NodeContainer::NodeContainer(ns3::Ptr node) [constructor] + cls.add_constructor([param('ns3::Ptr< ns3::Node >', 'node')], visibility='public') + ## node-container.h: ns3::NodeContainer::NodeContainer(ns3::NodeContainer const & a, ns3::NodeContainer const & b) [constructor] + cls.add_constructor([param('ns3::NodeContainer&', 'a', is_const=True), param('ns3::NodeContainer&', 'b', is_const=True)], visibility='public') + ## node-container.h: ns3::NodeContainer::NodeContainer(ns3::NodeContainer const & a, ns3::NodeContainer const & b, ns3::NodeContainer const & c) [constructor] + cls.add_constructor([param('ns3::NodeContainer&', 'a', is_const=True), param('ns3::NodeContainer&', 'b', is_const=True), param('ns3::NodeContainer&', 'c', is_const=True)], visibility='public') + ## node-container.h: ns3::NodeContainer::NodeContainer(ns3::NodeContainer const & a, ns3::NodeContainer const & b, ns3::NodeContainer const & c, ns3::NodeContainer const & d) [constructor] + cls.add_constructor([param('ns3::NodeContainer&', 'a', is_const=True), param('ns3::NodeContainer&', 'b', is_const=True), param('ns3::NodeContainer&', 'c', is_const=True), param('ns3::NodeContainer&', 'd', is_const=True)], visibility='public') + ## node-container.h: __gnu_cxx::__normal_iterator*,std::vector, std::allocator > > > ns3::NodeContainer::Begin() const [member function] + cls.add_method('Begin', '__gnu_cxx::__normal_iterator< const ns3::Ptr< ns3::Node >, std::vector< ns3::Ptr< ns3::Node >, std::allocator< ns3::Ptr< ns3::Node > > > >', [], is_const=True) + ## node-container.h: __gnu_cxx::__normal_iterator*,std::vector, std::allocator > > > ns3::NodeContainer::End() const [member function] + cls.add_method('End', '__gnu_cxx::__normal_iterator< const ns3::Ptr< ns3::Node >, std::vector< ns3::Ptr< ns3::Node >, std::allocator< ns3::Ptr< ns3::Node > > > >', [], is_const=True) + ## node-container.h: uint32_t ns3::NodeContainer::GetN() const [member function] + cls.add_method('GetN', 'uint32_t', [], is_const=True) + ## node-container.h: ns3::Ptr ns3::NodeContainer::Get(uint32_t i) const [member function] + cls.add_method('Get', 'ns3::Ptr< ns3::Node >', [param('uint32_t', 'i')], is_const=True) + ## node-container.h: void ns3::NodeContainer::Create(uint32_t n) [member function] + cls.add_method('Create', 'void', [param('uint32_t', 'n')]) + ## node-container.h: void ns3::NodeContainer::Add(ns3::NodeContainer other) [member function] + cls.add_method('Add', 'void', [param('ns3::NodeContainer', 'other')]) + ## node-container.h: void ns3::NodeContainer::Add(ns3::Ptr node) [member function] + cls.add_method('Add', 'void', [param('ns3::Ptr< ns3::Node >', 'node')]) + ## node-container.h: static ns3::NodeContainer ns3::NodeContainer::GetGlobal() [member function] + cls.add_method('GetGlobal', 'ns3::NodeContainer', [], is_static=True) + return + +def register_Ns3PointToPointHelper_methods(root_module, cls): + ## point-to-point-helper.h: ns3::PointToPointHelper::PointToPointHelper() [constructor] + cls.add_constructor([], visibility='public') + ## point-to-point-helper.h: void ns3::PointToPointHelper::SetQueue(std::string type, std::string n1="", ns3::AttributeValue const & v1=ns3::EmptyAttributeValue(), std::string n2="", ns3::AttributeValue const & v2=ns3::EmptyAttributeValue(), std::string n3="", ns3::AttributeValue const & v3=ns3::EmptyAttributeValue(), std::string n4="", ns3::AttributeValue const & v4=ns3::EmptyAttributeValue()) [member function] + cls.add_method('SetQueue', 'void', [param('std::string', 'type'), param('std::string', 'n1', default_value='""'), param('ns3::AttributeValue&', 'v1', default_value='ns3::EmptyAttributeValue()', is_const=True), param('std::string', 'n2', default_value='""'), param('ns3::AttributeValue&', 'v2', default_value='ns3::EmptyAttributeValue()', is_const=True), param('std::string', 'n3', default_value='""'), param('ns3::AttributeValue&', 'v3', default_value='ns3::EmptyAttributeValue()', is_const=True), param('std::string', 'n4', default_value='""'), param('ns3::AttributeValue&', 'v4', default_value='ns3::EmptyAttributeValue()', is_const=True)]) + ## point-to-point-helper.h: void ns3::PointToPointHelper::SetDeviceAttribute(std::string name, ns3::AttributeValue const & value) [member function] + cls.add_method('SetDeviceAttribute', 'void', [param('std::string', 'name'), param('ns3::AttributeValue&', 'value', is_const=True)]) + ## point-to-point-helper.h: void ns3::PointToPointHelper::SetChannelAttribute(std::string name, ns3::AttributeValue const & value) [member function] + cls.add_method('SetChannelAttribute', 'void', [param('std::string', 'name'), param('ns3::AttributeValue&', 'value', is_const=True)]) + ## point-to-point-helper.h: static void ns3::PointToPointHelper::EnablePcap(std::string filename, uint32_t nodeid, uint32_t deviceid) [member function] + cls.add_method('EnablePcap', 'void', [param('std::string', 'filename'), param('uint32_t', 'nodeid'), param('uint32_t', 'deviceid')], is_static=True) + ## point-to-point-helper.h: static void ns3::PointToPointHelper::EnablePcap(std::string filename, ns3::NetDeviceContainer d) [member function] + cls.add_method('EnablePcap', 'void', [param('std::string', 'filename'), param('ns3::NetDeviceContainer', 'd')], is_static=True) + ## point-to-point-helper.h: static void ns3::PointToPointHelper::EnablePcap(std::string filename, ns3::NodeContainer n) [member function] + cls.add_method('EnablePcap', 'void', [param('std::string', 'filename'), param('ns3::NodeContainer', 'n')], is_static=True) + ## point-to-point-helper.h: static void ns3::PointToPointHelper::EnablePcapAll(std::string filename) [member function] + cls.add_method('EnablePcapAll', 'void', [param('std::string', 'filename')], is_static=True) + ## point-to-point-helper.h: static void ns3::PointToPointHelper::EnableAscii(std::ostream & os, uint32_t nodeid, uint32_t deviceid) [member function] + cls.add_method('EnableAscii', 'void', [param('std::ostream&', 'os'), param('uint32_t', 'nodeid'), param('uint32_t', 'deviceid')], is_static=True) + ## point-to-point-helper.h: static void ns3::PointToPointHelper::EnableAscii(std::ostream & os, ns3::NetDeviceContainer d) [member function] + cls.add_method('EnableAscii', 'void', [param('std::ostream&', 'os'), param('ns3::NetDeviceContainer', 'd')], is_static=True) + ## point-to-point-helper.h: static void ns3::PointToPointHelper::EnableAscii(std::ostream & os, ns3::NodeContainer n) [member function] + cls.add_method('EnableAscii', 'void', [param('std::ostream&', 'os'), param('ns3::NodeContainer', 'n')], is_static=True) + ## point-to-point-helper.h: static void ns3::PointToPointHelper::EnableAsciiAll(std::ostream & os) [member function] + cls.add_method('EnableAsciiAll', 'void', [param('std::ostream&', 'os')], is_static=True) + ## point-to-point-helper.h: ns3::NetDeviceContainer ns3::PointToPointHelper::Install(ns3::NodeContainer c) [member function] + cls.add_method('Install', 'ns3::NetDeviceContainer', [param('ns3::NodeContainer', 'c')]) + ## point-to-point-helper.h: ns3::NetDeviceContainer ns3::PointToPointHelper::Install(ns3::Ptr a, ns3::Ptr b) [member function] + cls.add_method('Install', 'ns3::NetDeviceContainer', [param('ns3::Ptr< ns3::Node >', 'a'), param('ns3::Ptr< ns3::Node >', 'b')]) + return + +def register_Ns3NetDeviceContainer_methods(root_module, cls): + ## net-device-container.h: __gnu_cxx::__normal_iterator*,std::vector, std::allocator > > > ns3::NetDeviceContainer::Begin() const [member function] + cls.add_method('Begin', '__gnu_cxx::__normal_iterator< const ns3::Ptr< ns3::NetDevice >, std::vector< ns3::Ptr< ns3::NetDevice >, std::allocator< ns3::Ptr< ns3::NetDevice > > > >', [], is_const=True) + ## net-device-container.h: __gnu_cxx::__normal_iterator*,std::vector, std::allocator > > > ns3::NetDeviceContainer::End() const [member function] + cls.add_method('End', '__gnu_cxx::__normal_iterator< const ns3::Ptr< ns3::NetDevice >, std::vector< ns3::Ptr< ns3::NetDevice >, std::allocator< ns3::Ptr< ns3::NetDevice > > > >', [], is_const=True) + ## net-device-container.h: uint32_t ns3::NetDeviceContainer::GetN() const [member function] + cls.add_method('GetN', 'uint32_t', [], is_const=True) + ## net-device-container.h: ns3::Ptr ns3::NetDeviceContainer::Get(uint32_t i) const [member function] + cls.add_method('Get', 'ns3::Ptr< ns3::NetDevice >', [param('uint32_t', 'i')], is_const=True) + ## net-device-container.h: void ns3::NetDeviceContainer::Add(ns3::NetDeviceContainer other) [member function] + cls.add_method('Add', 'void', [param('ns3::NetDeviceContainer', 'other')]) + ## net-device-container.h: void ns3::NetDeviceContainer::Add(ns3::Ptr device) [member function] + cls.add_method('Add', 'void', [param('ns3::Ptr< ns3::NetDevice >', 'device')]) + cls.add_constructor([]) + return + +def register_Ns3CsmaHelper_methods(root_module, cls): + ## csma-helper.h: ns3::CsmaHelper::CsmaHelper() [constructor] + cls.add_constructor([], visibility='public') + ## csma-helper.h: void ns3::CsmaHelper::SetQueue(std::string type, std::string n1="", ns3::AttributeValue const & v1=ns3::EmptyAttributeValue(), std::string n2="", ns3::AttributeValue const & v2=ns3::EmptyAttributeValue(), std::string n3="", ns3::AttributeValue const & v3=ns3::EmptyAttributeValue(), std::string n4="", ns3::AttributeValue const & v4=ns3::EmptyAttributeValue()) [member function] + cls.add_method('SetQueue', 'void', [param('std::string', 'type'), param('std::string', 'n1', default_value='""'), param('ns3::AttributeValue&', 'v1', default_value='ns3::EmptyAttributeValue()', is_const=True), param('std::string', 'n2', default_value='""'), param('ns3::AttributeValue&', 'v2', default_value='ns3::EmptyAttributeValue()', is_const=True), param('std::string', 'n3', default_value='""'), param('ns3::AttributeValue&', 'v3', default_value='ns3::EmptyAttributeValue()', is_const=True), param('std::string', 'n4', default_value='""'), param('ns3::AttributeValue&', 'v4', default_value='ns3::EmptyAttributeValue()', is_const=True)]) + ## csma-helper.h: void ns3::CsmaHelper::SetDeviceAttribute(std::string n1, ns3::AttributeValue const & v1) [member function] + cls.add_method('SetDeviceAttribute', 'void', [param('std::string', 'n1'), param('ns3::AttributeValue&', 'v1', is_const=True)]) + ## csma-helper.h: void ns3::CsmaHelper::SetChannelAttribute(std::string n1, ns3::AttributeValue const & v1) [member function] + cls.add_method('SetChannelAttribute', 'void', [param('std::string', 'n1'), param('ns3::AttributeValue&', 'v1', is_const=True)]) + ## csma-helper.h: static void ns3::CsmaHelper::EnablePcap(std::string filename, uint32_t nodeid, uint32_t deviceid) [member function] + cls.add_method('EnablePcap', 'void', [param('std::string', 'filename'), param('uint32_t', 'nodeid'), param('uint32_t', 'deviceid')], is_static=True) + ## csma-helper.h: static void ns3::CsmaHelper::EnablePcap(std::string filename, ns3::NetDeviceContainer d) [member function] + cls.add_method('EnablePcap', 'void', [param('std::string', 'filename'), param('ns3::NetDeviceContainer', 'd')], is_static=True) + ## csma-helper.h: static void ns3::CsmaHelper::EnablePcap(std::string filename, ns3::NodeContainer n) [member function] + cls.add_method('EnablePcap', 'void', [param('std::string', 'filename'), param('ns3::NodeContainer', 'n')], is_static=True) + ## csma-helper.h: static void ns3::CsmaHelper::EnablePcapAll(std::string filename) [member function] + cls.add_method('EnablePcapAll', 'void', [param('std::string', 'filename')], is_static=True) + ## csma-helper.h: static void ns3::CsmaHelper::EnableAscii(std::ostream & os, uint32_t nodeid, uint32_t deviceid) [member function] + cls.add_method('EnableAscii', 'void', [param('std::ostream&', 'os'), param('uint32_t', 'nodeid'), param('uint32_t', 'deviceid')], is_static=True) + ## csma-helper.h: static void ns3::CsmaHelper::EnableAscii(std::ostream & os, ns3::NetDeviceContainer d) [member function] + cls.add_method('EnableAscii', 'void', [param('std::ostream&', 'os'), param('ns3::NetDeviceContainer', 'd')], is_static=True) + ## csma-helper.h: static void ns3::CsmaHelper::EnableAscii(std::ostream & os, ns3::NodeContainer n) [member function] + cls.add_method('EnableAscii', 'void', [param('std::ostream&', 'os'), param('ns3::NodeContainer', 'n')], is_static=True) + ## csma-helper.h: static void ns3::CsmaHelper::EnableAsciiAll(std::ostream & os) [member function] + cls.add_method('EnableAsciiAll', 'void', [param('std::ostream&', 'os')], is_static=True) + ## csma-helper.h: ns3::NetDeviceContainer ns3::CsmaHelper::Install(ns3::NodeContainer const & c) [member function] + cls.add_method('Install', 'ns3::NetDeviceContainer', [param('ns3::NodeContainer&', 'c', is_const=True)]) + ## csma-helper.h: ns3::NetDeviceContainer ns3::CsmaHelper::Install(ns3::NodeContainer const & c, ns3::Ptr channel) [member function] + cls.add_method('Install', 'ns3::NetDeviceContainer', [param('ns3::NodeContainer&', 'c', is_const=True), param('ns3::Ptr< ns3::CsmaChannel >', 'channel')]) + return + +def register_Ns3UdpEchoServerHelper_methods(root_module, cls): + ## udp-echo-helper.h: ns3::UdpEchoServerHelper::UdpEchoServerHelper(uint16_t port) [constructor] + cls.add_constructor([param('uint16_t', 'port')], visibility='public') + ## udp-echo-helper.h: void ns3::UdpEchoServerHelper::SetAttribute(std::string name, ns3::AttributeValue const & value) [member function] + cls.add_method('SetAttribute', 'void', [param('std::string', 'name'), param('ns3::AttributeValue&', 'value', is_const=True)]) + ## udp-echo-helper.h: ns3::ApplicationContainer ns3::UdpEchoServerHelper::Install(ns3::NodeContainer c) [member function] + cls.add_method('Install', 'ns3::ApplicationContainer', [param('ns3::NodeContainer', 'c')]) + return + +def register_Ns3OlsrHelper_methods(root_module, cls): + ## olsr-helper.h: ns3::OlsrHelper::OlsrHelper() [constructor] + cls.add_constructor([], visibility='public') + ## olsr-helper.h: void ns3::OlsrHelper::SetAgent(std::string tid, std::string n0="", ns3::AttributeValue const & v0=ns3::EmptyAttributeValue(), std::string n1="", ns3::AttributeValue const & v1=ns3::EmptyAttributeValue(), std::string n2="", ns3::AttributeValue const & v2=ns3::EmptyAttributeValue(), std::string n3="", ns3::AttributeValue const & v3=ns3::EmptyAttributeValue(), std::string n4="", ns3::AttributeValue const & v4=ns3::EmptyAttributeValue(), std::string n5="", ns3::AttributeValue const & v5=ns3::EmptyAttributeValue(), std::string n6="", ns3::AttributeValue const & v6=ns3::EmptyAttributeValue(), std::string n7="", ns3::AttributeValue const & v7=ns3::EmptyAttributeValue()) [member function] + cls.add_method('SetAgent', 'void', [param('std::string', 'tid'), param('std::string', 'n0', default_value='""'), param('ns3::AttributeValue&', 'v0', default_value='ns3::EmptyAttributeValue()', is_const=True), param('std::string', 'n1', default_value='""'), param('ns3::AttributeValue&', 'v1', default_value='ns3::EmptyAttributeValue()', is_const=True), param('std::string', 'n2', default_value='""'), param('ns3::AttributeValue&', 'v2', default_value='ns3::EmptyAttributeValue()', is_const=True), param('std::string', 'n3', default_value='""'), param('ns3::AttributeValue&', 'v3', default_value='ns3::EmptyAttributeValue()', is_const=True), param('std::string', 'n4', default_value='""'), param('ns3::AttributeValue&', 'v4', default_value='ns3::EmptyAttributeValue()', is_const=True), param('std::string', 'n5', default_value='""'), param('ns3::AttributeValue&', 'v5', default_value='ns3::EmptyAttributeValue()', is_const=True), param('std::string', 'n6', default_value='""'), param('ns3::AttributeValue&', 'v6', default_value='ns3::EmptyAttributeValue()', is_const=True), param('std::string', 'n7', default_value='""'), param('ns3::AttributeValue&', 'v7', default_value='ns3::EmptyAttributeValue()', is_const=True)]) + ## olsr-helper.h: void ns3::OlsrHelper::Install(ns3::NodeContainer container) [member function] + cls.add_method('Install', 'void', [param('ns3::NodeContainer', 'container')]) + ## olsr-helper.h: void ns3::OlsrHelper::Install(ns3::Ptr node) [member function] + cls.add_method('Install', 'void', [param('ns3::Ptr< ns3::Node >', 'node')]) + ## olsr-helper.h: void ns3::OlsrHelper::InstallAll() [member function] + cls.add_method('InstallAll', 'void', []) + return + +def register_Ns3PacketSocketHelper_methods(root_module, cls): + ## packet-socket-helper.h: void ns3::PacketSocketHelper::Install(ns3::NodeContainer c) [member function] + cls.add_method('Install', 'void', [param('ns3::NodeContainer', 'c')]) + cls.add_constructor([]) + return + +def register_Ns3OnOffHelper_methods(root_module, cls): + ## on-off-helper.h: ns3::OnOffHelper::OnOffHelper(std::string protocol, ns3::Address address) [constructor] + cls.add_constructor([param('std::string', 'protocol'), param('ns3::Address', 'address')], visibility='public') + ## on-off-helper.h: void ns3::OnOffHelper::SetAttribute(std::string name, ns3::AttributeValue const & value) [member function] + cls.add_method('SetAttribute', 'void', [param('std::string', 'name'), param('ns3::AttributeValue&', 'value', is_const=True)]) + ## on-off-helper.h: ns3::ApplicationContainer ns3::OnOffHelper::Install(ns3::NodeContainer c) [member function] + cls.add_method('Install', 'ns3::ApplicationContainer', [param('ns3::NodeContainer', 'c')]) + return + +def register_Ns3UdpEchoClientHelper_methods(root_module, cls): + ## udp-echo-helper.h: ns3::UdpEchoClientHelper::UdpEchoClientHelper(ns3::Ipv4Address ip, uint16_t port) [constructor] + cls.add_constructor([param('ns3::Ipv4Address', 'ip'), param('uint16_t', 'port')], visibility='public') + ## udp-echo-helper.h: void ns3::UdpEchoClientHelper::SetAttribute(std::string name, ns3::AttributeValue const & value) [member function] + cls.add_method('SetAttribute', 'void', [param('std::string', 'name'), param('ns3::AttributeValue&', 'value', is_const=True)]) + ## udp-echo-helper.h: ns3::ApplicationContainer ns3::UdpEchoClientHelper::Install(ns3::NodeContainer c) [member function] + cls.add_method('Install', 'ns3::ApplicationContainer', [param('ns3::NodeContainer', 'c')]) + return + +def register_Ns3StaticMulticastRouteHelper_methods(root_module, cls): + ## static-multicast-route-helper.h: ns3::StaticMulticastRouteHelper::StaticMulticastRouteHelper() [constructor] + cls.add_constructor([], visibility='public') + ## static-multicast-route-helper.h: void ns3::StaticMulticastRouteHelper::AddMulticastRoute(ns3::Ptr arg0, ns3::Ipv4Address source, ns3::Ipv4Address group, ns3::Ptr input, ns3::NetDeviceContainer output) [member function] + cls.add_method('AddMulticastRoute', 'void', [param('ns3::Ptr< ns3::Node >', 'arg0'), param('ns3::Ipv4Address', 'source'), param('ns3::Ipv4Address', 'group'), param('ns3::Ptr< ns3::NetDevice >', 'input'), param('ns3::NetDeviceContainer', 'output')]) + ## static-multicast-route-helper.h: void ns3::StaticMulticastRouteHelper::SetDefaultMulticastRoute(ns3::Ptr n, ns3::Ptr nd) [member function] + cls.add_method('SetDefaultMulticastRoute', 'void', [param('ns3::Ptr< ns3::Node >', 'n'), param('ns3::Ptr< ns3::NetDevice >', 'nd')]) + ## static-multicast-route-helper.h: void ns3::StaticMulticastRouteHelper::JoinMulticastGroup(ns3::Ptr n, ns3::Ipv4Address source, ns3::Ipv4Address group) [member function] + cls.add_method('JoinMulticastGroup', 'void', [param('ns3::Ptr< ns3::Node >', 'n'), param('ns3::Ipv4Address', 'source'), param('ns3::Ipv4Address', 'group')]) + return + +def register_Ns3Ipv4InterfaceContainer_methods(root_module, cls): + ## ipv4-interface-container.h: ns3::Ipv4InterfaceContainer::Ipv4InterfaceContainer() [constructor] + cls.add_constructor([], visibility='public') + ## ipv4-interface-container.h: uint32_t ns3::Ipv4InterfaceContainer::GetN() const [member function] + cls.add_method('GetN', 'uint32_t', [], is_const=True) + ## ipv4-interface-container.h: ns3::Ipv4Address ns3::Ipv4InterfaceContainer::GetAddress(uint32_t i) const [member function] + cls.add_method('GetAddress', 'ns3::Ipv4Address', [param('uint32_t', 'i')], is_const=True) + ## ipv4-interface-container.h: void ns3::Ipv4InterfaceContainer::SetMetric(uint32_t i, uint16_t metric) [member function] + cls.add_method('SetMetric', 'void', [param('uint32_t', 'i'), param('uint16_t', 'metric')]) + ## ipv4-interface-container.h: void ns3::Ipv4InterfaceContainer::Add(ns3::Ptr ipv4, uint32_t interface) [member function] + cls.add_method('Add', 'void', [param('ns3::Ptr< ns3::Ipv4 >', 'ipv4'), param('uint32_t', 'interface')]) + return + +def register_Ns3ApplicationContainer_methods(root_module, cls): + ## application-container.h: __gnu_cxx::__normal_iterator*,std::vector, std::allocator > > > ns3::ApplicationContainer::Begin() const [member function] + cls.add_method('Begin', '__gnu_cxx::__normal_iterator< const ns3::Ptr< ns3::Application >, std::vector< ns3::Ptr< ns3::Application >, std::allocator< ns3::Ptr< ns3::Application > > > >', [], is_const=True) + ## application-container.h: __gnu_cxx::__normal_iterator*,std::vector, std::allocator > > > ns3::ApplicationContainer::End() const [member function] + cls.add_method('End', '__gnu_cxx::__normal_iterator< const ns3::Ptr< ns3::Application >, std::vector< ns3::Ptr< ns3::Application >, std::allocator< ns3::Ptr< ns3::Application > > > >', [], is_const=True) + ## application-container.h: uint32_t ns3::ApplicationContainer::GetN() const [member function] + cls.add_method('GetN', 'uint32_t', [], is_const=True) + ## application-container.h: ns3::Ptr ns3::ApplicationContainer::Get(uint32_t i) const [member function] + cls.add_method('Get', 'ns3::Ptr< ns3::Application >', [param('uint32_t', 'i')], is_const=True) + ## application-container.h: void ns3::ApplicationContainer::Add(ns3::ApplicationContainer other) [member function] + cls.add_method('Add', 'void', [param('ns3::ApplicationContainer', 'other')]) + ## application-container.h: void ns3::ApplicationContainer::Add(ns3::Ptr application) [member function] + cls.add_method('Add', 'void', [param('ns3::Ptr< ns3::Application >', 'application')]) + ## application-container.h: void ns3::ApplicationContainer::Start(ns3::Time start) [member function] + cls.add_method('Start', 'void', [param('ns3::Time', 'start')]) + ## application-container.h: void ns3::ApplicationContainer::Stop(ns3::Time stop) [member function] + cls.add_method('Stop', 'void', [param('ns3::Time', 'stop')]) + cls.add_constructor([]) + return + +def register_Ns3WifiHelper_methods(root_module, cls): + ## wifi-helper.h: ns3::WifiHelper::WifiHelper() [constructor] + cls.add_constructor([], visibility='public') + ## wifi-helper.h: void ns3::WifiHelper::SetRemoteStationManager(std::string type, std::string n0="", ns3::AttributeValue const & v0=ns3::EmptyAttributeValue(), std::string n1="", ns3::AttributeValue const & v1=ns3::EmptyAttributeValue(), std::string n2="", ns3::AttributeValue const & v2=ns3::EmptyAttributeValue(), std::string n3="", ns3::AttributeValue const & v3=ns3::EmptyAttributeValue(), std::string n4="", ns3::AttributeValue const & v4=ns3::EmptyAttributeValue(), std::string n5="", ns3::AttributeValue const & v5=ns3::EmptyAttributeValue(), std::string n6="", ns3::AttributeValue const & v6=ns3::EmptyAttributeValue(), std::string n7="", ns3::AttributeValue const & v7=ns3::EmptyAttributeValue()) [member function] + cls.add_method('SetRemoteStationManager', 'void', [param('std::string', 'type'), param('std::string', 'n0', default_value='""'), param('ns3::AttributeValue&', 'v0', default_value='ns3::EmptyAttributeValue()', is_const=True), param('std::string', 'n1', default_value='""'), param('ns3::AttributeValue&', 'v1', default_value='ns3::EmptyAttributeValue()', is_const=True), param('std::string', 'n2', default_value='""'), param('ns3::AttributeValue&', 'v2', default_value='ns3::EmptyAttributeValue()', is_const=True), param('std::string', 'n3', default_value='""'), param('ns3::AttributeValue&', 'v3', default_value='ns3::EmptyAttributeValue()', is_const=True), param('std::string', 'n4', default_value='""'), param('ns3::AttributeValue&', 'v4', default_value='ns3::EmptyAttributeValue()', is_const=True), param('std::string', 'n5', default_value='""'), param('ns3::AttributeValue&', 'v5', default_value='ns3::EmptyAttributeValue()', is_const=True), param('std::string', 'n6', default_value='""'), param('ns3::AttributeValue&', 'v6', default_value='ns3::EmptyAttributeValue()', is_const=True), param('std::string', 'n7', default_value='""'), param('ns3::AttributeValue&', 'v7', default_value='ns3::EmptyAttributeValue()', is_const=True)]) + ## wifi-helper.h: void ns3::WifiHelper::SetMac(std::string type, std::string n0="", ns3::AttributeValue const & v0=ns3::EmptyAttributeValue(), std::string n1="", ns3::AttributeValue const & v1=ns3::EmptyAttributeValue(), std::string n2="", ns3::AttributeValue const & v2=ns3::EmptyAttributeValue(), std::string n3="", ns3::AttributeValue const & v3=ns3::EmptyAttributeValue(), std::string n4="", ns3::AttributeValue const & v4=ns3::EmptyAttributeValue(), std::string n5="", ns3::AttributeValue const & v5=ns3::EmptyAttributeValue(), std::string n6="", ns3::AttributeValue const & v6=ns3::EmptyAttributeValue(), std::string n7="", ns3::AttributeValue const & v7=ns3::EmptyAttributeValue()) [member function] + cls.add_method('SetMac', 'void', [param('std::string', 'type'), param('std::string', 'n0', default_value='""'), param('ns3::AttributeValue&', 'v0', default_value='ns3::EmptyAttributeValue()', is_const=True), param('std::string', 'n1', default_value='""'), param('ns3::AttributeValue&', 'v1', default_value='ns3::EmptyAttributeValue()', is_const=True), param('std::string', 'n2', default_value='""'), param('ns3::AttributeValue&', 'v2', default_value='ns3::EmptyAttributeValue()', is_const=True), param('std::string', 'n3', default_value='""'), param('ns3::AttributeValue&', 'v3', default_value='ns3::EmptyAttributeValue()', is_const=True), param('std::string', 'n4', default_value='""'), param('ns3::AttributeValue&', 'v4', default_value='ns3::EmptyAttributeValue()', is_const=True), param('std::string', 'n5', default_value='""'), param('ns3::AttributeValue&', 'v5', default_value='ns3::EmptyAttributeValue()', is_const=True), param('std::string', 'n6', default_value='""'), param('ns3::AttributeValue&', 'v6', default_value='ns3::EmptyAttributeValue()', is_const=True), param('std::string', 'n7', default_value='""'), param('ns3::AttributeValue&', 'v7', default_value='ns3::EmptyAttributeValue()', is_const=True)]) + ## wifi-helper.h: void ns3::WifiHelper::SetPhy(std::string phyType, std::string n0="", ns3::AttributeValue const & v0=ns3::EmptyAttributeValue(), std::string n1="", ns3::AttributeValue const & v1=ns3::EmptyAttributeValue(), std::string n2="", ns3::AttributeValue const & v2=ns3::EmptyAttributeValue(), std::string n3="", ns3::AttributeValue const & v3=ns3::EmptyAttributeValue(), std::string n4="", ns3::AttributeValue const & v4=ns3::EmptyAttributeValue(), std::string n5="", ns3::AttributeValue const & v5=ns3::EmptyAttributeValue(), std::string n6="", ns3::AttributeValue const & v6=ns3::EmptyAttributeValue(), std::string n7="", ns3::AttributeValue const & v7=ns3::EmptyAttributeValue()) [member function] + cls.add_method('SetPhy', 'void', [param('std::string', 'phyType'), param('std::string', 'n0', default_value='""'), param('ns3::AttributeValue&', 'v0', default_value='ns3::EmptyAttributeValue()', is_const=True), param('std::string', 'n1', default_value='""'), param('ns3::AttributeValue&', 'v1', default_value='ns3::EmptyAttributeValue()', is_const=True), param('std::string', 'n2', default_value='""'), param('ns3::AttributeValue&', 'v2', default_value='ns3::EmptyAttributeValue()', is_const=True), param('std::string', 'n3', default_value='""'), param('ns3::AttributeValue&', 'v3', default_value='ns3::EmptyAttributeValue()', is_const=True), param('std::string', 'n4', default_value='""'), param('ns3::AttributeValue&', 'v4', default_value='ns3::EmptyAttributeValue()', is_const=True), param('std::string', 'n5', default_value='""'), param('ns3::AttributeValue&', 'v5', default_value='ns3::EmptyAttributeValue()', is_const=True), param('std::string', 'n6', default_value='""'), param('ns3::AttributeValue&', 'v6', default_value='ns3::EmptyAttributeValue()', is_const=True), param('std::string', 'n7', default_value='""'), param('ns3::AttributeValue&', 'v7', default_value='ns3::EmptyAttributeValue()', is_const=True)]) + ## wifi-helper.h: static void ns3::WifiHelper::EnablePcap(std::string filename, uint32_t nodeid, uint32_t deviceid) [member function] + cls.add_method('EnablePcap', 'void', [param('std::string', 'filename'), param('uint32_t', 'nodeid'), param('uint32_t', 'deviceid')], is_static=True) + ## wifi-helper.h: static void ns3::WifiHelper::EnablePcap(std::string filename, ns3::NetDeviceContainer d) [member function] + cls.add_method('EnablePcap', 'void', [param('std::string', 'filename'), param('ns3::NetDeviceContainer', 'd')], is_static=True) + ## wifi-helper.h: static void ns3::WifiHelper::EnablePcap(std::string filename, ns3::NodeContainer n) [member function] + cls.add_method('EnablePcap', 'void', [param('std::string', 'filename'), param('ns3::NodeContainer', 'n')], is_static=True) + ## wifi-helper.h: static void ns3::WifiHelper::EnablePcapAll(std::string filename) [member function] + cls.add_method('EnablePcapAll', 'void', [param('std::string', 'filename')], is_static=True) + ## wifi-helper.h: static void ns3::WifiHelper::EnableAscii(std::ostream & os, uint32_t nodeid, uint32_t deviceid) [member function] + cls.add_method('EnableAscii', 'void', [param('std::ostream&', 'os'), param('uint32_t', 'nodeid'), param('uint32_t', 'deviceid')], is_static=True) + ## wifi-helper.h: static void ns3::WifiHelper::EnableAscii(std::ostream & os, ns3::NetDeviceContainer d) [member function] + cls.add_method('EnableAscii', 'void', [param('std::ostream&', 'os'), param('ns3::NetDeviceContainer', 'd')], is_static=True) + ## wifi-helper.h: static void ns3::WifiHelper::EnableAscii(std::ostream & os, ns3::NodeContainer n) [member function] + cls.add_method('EnableAscii', 'void', [param('std::ostream&', 'os'), param('ns3::NodeContainer', 'n')], is_static=True) + ## wifi-helper.h: static void ns3::WifiHelper::EnableAsciiAll(std::ostream & os) [member function] + cls.add_method('EnableAsciiAll', 'void', [param('std::ostream&', 'os')], is_static=True) + ## wifi-helper.h: ns3::NetDeviceContainer ns3::WifiHelper::Install(ns3::NodeContainer c) const [member function] + cls.add_method('Install', 'ns3::NetDeviceContainer', [param('ns3::NodeContainer', 'c')], is_const=True) + ## wifi-helper.h: ns3::NetDeviceContainer ns3::WifiHelper::Install(ns3::NodeContainer c, ns3::Ptr channel) const [member function] + cls.add_method('Install', 'ns3::NetDeviceContainer', [param('ns3::NodeContainer', 'c'), param('ns3::Ptr< ns3::WifiChannel >', 'channel')], is_const=True) + return + +def register_Ns3Ipv4AddressHelper_methods(root_module, cls): + ## ipv4-address-helper.h: ns3::Ipv4AddressHelper::Ipv4AddressHelper() [constructor] + cls.add_constructor([], visibility='public') + ## ipv4-address-helper.h: void ns3::Ipv4AddressHelper::SetBase(ns3::Ipv4Address network, ns3::Ipv4Mask mask, ns3::Ipv4Address base="0.0.0.1") [member function] + cls.add_method('SetBase', 'void', [param('ns3::Ipv4Address', 'network'), param('ns3::Ipv4Mask', 'mask'), param('ns3::Ipv4Address', 'base', default_value='"0.0.0.1"')]) + ## ipv4-address-helper.h: ns3::Ipv4Address ns3::Ipv4AddressHelper::NewNetwork() [member function] + cls.add_method('NewNetwork', 'ns3::Ipv4Address', []) + ## ipv4-address-helper.h: ns3::Ipv4Address ns3::Ipv4AddressHelper::NewAddress() [member function] + cls.add_method('NewAddress', 'ns3::Ipv4Address', []) + ## ipv4-address-helper.h: ns3::Ipv4InterfaceContainer ns3::Ipv4AddressHelper::Assign(ns3::NetDeviceContainer const & c) [member function] + cls.add_method('Assign', 'ns3::Ipv4InterfaceContainer', [param('ns3::NetDeviceContainer&', 'c', is_const=True)]) + return + +def register_Ns3PacketSinkHelper_methods(root_module, cls): + ## packet-sink-helper.h: ns3::PacketSinkHelper::PacketSinkHelper(std::string protocol, ns3::Address address) [constructor] + cls.add_constructor([param('std::string', 'protocol'), param('ns3::Address', 'address')], visibility='public') + ## packet-sink-helper.h: void ns3::PacketSinkHelper::SetAttribute(std::string name, ns3::AttributeValue const & value) [member function] + cls.add_method('SetAttribute', 'void', [param('std::string', 'name'), param('ns3::AttributeValue&', 'value', is_const=True)]) + ## packet-sink-helper.h: ns3::ApplicationContainer ns3::PacketSinkHelper::Install(ns3::NodeContainer c) [member function] + cls.add_method('Install', 'ns3::ApplicationContainer', [param('ns3::NodeContainer', 'c')]) + return + +def register_Ns3Ns2MobilityHelper_methods(root_module, cls): + ## ns2-mobility-helper.h: ns3::Ns2MobilityHelper::Ns2MobilityHelper(std::string filename) [constructor] + cls.add_constructor([param('std::string', 'filename')], visibility='public') + ## ns2-mobility-helper.h: void ns3::Ns2MobilityHelper::Install() const [member function] + cls.add_method('Install', 'void', [], is_const=True) + return + +def register_functions(root_module): + module = root_module + register_functions_ns3_internal(module.get_submodule('internal'), root_module) + register_functions_ns3_TimeStepPrecision(module.get_submodule('TimeStepPrecision'), root_module) + register_functions_ns3_Config(module.get_submodule('Config'), root_module) + register_functions_ns3_olsr(module.get_submodule('olsr'), root_module) + return + +def register_functions_ns3_internal(module, root_module): + return + +def register_functions_ns3_TimeStepPrecision(module, root_module): + return + +def register_functions_ns3_Config(module, root_module): + return + +def register_functions_ns3_olsr(module, root_module): + return + diff --git a/bindings/python/ns3_module_internet_stack.py b/bindings/python/ns3_module_internet_stack.py new file mode 100644 index 000000000..2f51733a9 --- /dev/null +++ b/bindings/python/ns3_module_internet_stack.py @@ -0,0 +1,355 @@ +from pybindgen import Module, FileCodeSink, write_preamble, param, retval + +def register_types(module): + root_module = module.get_root() + + ## ipv4-interface.h: ns3::Ipv4Interface [class] + module.add_class('Ipv4Interface', allow_subclassing=True, parent=root_module['ns3::Object']) + ## udp-header.h: ns3::UdpHeader [class] + module.add_class('UdpHeader', allow_subclassing=True, parent=root_module['ns3::Header']) + ## tcp-header.h: ns3::TcpHeader [class] + module.add_class('TcpHeader', allow_subclassing=True, parent=root_module['ns3::Header']) + ## tcp-header.h: ns3::TcpHeader::Flags_t [enumeration] + module.add_enum('Flags_t', ['NONE', 'FIN', 'SYN', 'RST', 'PSH', 'ACK', 'URG'], outer_class=root_module['ns3::TcpHeader']) + ## ipv4-static-routing.h: ns3::Ipv4StaticRouting [class] + module.add_class('Ipv4StaticRouting', allow_subclassing=True, parent=root_module['ns3::Ipv4RoutingProtocol']) + ## ipv4-l3-protocol.h: ns3::Ipv4L3Protocol [class] + module.add_class('Ipv4L3Protocol', allow_subclassing=True, parent=root_module['ns3::Object']) + + ## Register a nested module for the namespace internal + + nested_module = module.add_cpp_namespace('internal') + register_types_ns3_internal(nested_module) + + + ## Register a nested module for the namespace TimeStepPrecision + + nested_module = module.add_cpp_namespace('TimeStepPrecision') + register_types_ns3_TimeStepPrecision(nested_module) + + + ## Register a nested module for the namespace Config + + nested_module = module.add_cpp_namespace('Config') + register_types_ns3_Config(nested_module) + + + ## Register a nested module for the namespace olsr + + nested_module = module.add_cpp_namespace('olsr') + register_types_ns3_olsr(nested_module) + + +def register_types_ns3_internal(module): + root_module = module.get_root() + + +def register_types_ns3_TimeStepPrecision(module): + root_module = module.get_root() + + +def register_types_ns3_Config(module): + root_module = module.get_root() + + +def register_types_ns3_olsr(module): + root_module = module.get_root() + + +def register_methods(root_module): + register_Ns3Ipv4Interface_methods(root_module, root_module['ns3::Ipv4Interface']) + register_Ns3UdpHeader_methods(root_module, root_module['ns3::UdpHeader']) + register_Ns3TcpHeader_methods(root_module, root_module['ns3::TcpHeader']) + register_Ns3Ipv4StaticRouting_methods(root_module, root_module['ns3::Ipv4StaticRouting']) + register_Ns3Ipv4L3Protocol_methods(root_module, root_module['ns3::Ipv4L3Protocol']) + return + +def register_Ns3Ipv4Interface_methods(root_module, cls): + ## ipv4-interface.h: static ns3::TypeId ns3::Ipv4Interface::GetTypeId() [member function] + cls.add_method('GetTypeId', 'ns3::TypeId', [], is_static=True) + ## ipv4-interface.h: ns3::Ipv4Interface::Ipv4Interface() [constructor] + cls.add_constructor([], visibility='public') + ## ipv4-interface.h: ns3::Ptr ns3::Ipv4Interface::GetDevice() const [member function] + cls.add_method('GetDevice', 'ns3::Ptr< ns3::NetDevice >', [], is_pure_virtual=True, is_const=True, is_virtual=True) + ## ipv4-interface.h: void ns3::Ipv4Interface::SetAddress(ns3::Ipv4Address a) [member function] + cls.add_method('SetAddress', 'void', [param('ns3::Ipv4Address', 'a')]) + ## ipv4-interface.h: void ns3::Ipv4Interface::SetNetworkMask(ns3::Ipv4Mask mask) [member function] + cls.add_method('SetNetworkMask', 'void', [param('ns3::Ipv4Mask', 'mask')]) + ## ipv4-interface.h: ns3::Ipv4Address ns3::Ipv4Interface::GetBroadcast() const [member function] + cls.add_method('GetBroadcast', 'ns3::Ipv4Address', [], is_const=True) + ## ipv4-interface.h: ns3::Ipv4Mask ns3::Ipv4Interface::GetNetworkMask() const [member function] + cls.add_method('GetNetworkMask', 'ns3::Ipv4Mask', [], is_const=True) + ## ipv4-interface.h: void ns3::Ipv4Interface::SetMetric(uint16_t metric) [member function] + cls.add_method('SetMetric', 'void', [param('uint16_t', 'metric')]) + ## ipv4-interface.h: uint16_t ns3::Ipv4Interface::GetMetric() const [member function] + cls.add_method('GetMetric', 'uint16_t', [], is_const=True) + ## ipv4-interface.h: ns3::Ipv4Address ns3::Ipv4Interface::GetAddress() const [member function] + cls.add_method('GetAddress', 'ns3::Ipv4Address', [], is_const=True) + ## ipv4-interface.h: uint16_t ns3::Ipv4Interface::GetMtu() const [member function] + cls.add_method('GetMtu', 'uint16_t', [], is_const=True) + ## ipv4-interface.h: bool ns3::Ipv4Interface::IsUp() const [member function] + cls.add_method('IsUp', 'bool', [], is_const=True) + ## ipv4-interface.h: bool ns3::Ipv4Interface::IsDown() const [member function] + cls.add_method('IsDown', 'bool', [], is_const=True) + ## ipv4-interface.h: void ns3::Ipv4Interface::SetUp() [member function] + cls.add_method('SetUp', 'void', []) + ## ipv4-interface.h: void ns3::Ipv4Interface::SetDown() [member function] + cls.add_method('SetDown', 'void', []) + ## ipv4-interface.h: void ns3::Ipv4Interface::Send(ns3::Ptr p, ns3::Ipv4Address dest) [member function] + cls.add_method('Send', 'void', [param('ns3::Ptr< ns3::Packet >', 'p'), param('ns3::Ipv4Address', 'dest')]) + ## ipv4-interface.h: void ns3::Ipv4Interface::DoDispose() [member function] + cls.add_method('DoDispose', 'void', [], visibility='protected', is_virtual=True) + ## ipv4-interface.h: void ns3::Ipv4Interface::SendTo(ns3::Ptr p, ns3::Ipv4Address dest) [member function] + cls.add_method('SendTo', 'void', [param('ns3::Ptr< ns3::Packet >', 'p'), param('ns3::Ipv4Address', 'dest')], is_pure_virtual=True, visibility='private', is_virtual=True) + return + +def register_Ns3UdpHeader_methods(root_module, cls): + ## udp-header.h: ns3::UdpHeader::UdpHeader() [constructor] + cls.add_constructor([], visibility='public') + ## udp-header.h: void ns3::UdpHeader::EnableChecksums() [member function] + cls.add_method('EnableChecksums', 'void', []) + ## udp-header.h: void ns3::UdpHeader::SetDestinationPort(uint16_t port) [member function] + cls.add_method('SetDestinationPort', 'void', [param('uint16_t', 'port')]) + ## udp-header.h: void ns3::UdpHeader::SetSourcePort(uint16_t port) [member function] + cls.add_method('SetSourcePort', 'void', [param('uint16_t', 'port')]) + ## udp-header.h: uint16_t ns3::UdpHeader::GetSourcePort() const [member function] + cls.add_method('GetSourcePort', 'uint16_t', [], is_const=True) + ## udp-header.h: uint16_t ns3::UdpHeader::GetDestinationPort() const [member function] + cls.add_method('GetDestinationPort', 'uint16_t', [], is_const=True) + ## udp-header.h: void ns3::UdpHeader::SetPayloadSize(uint16_t size) [member function] + cls.add_method('SetPayloadSize', 'void', [param('uint16_t', 'size')]) + ## udp-header.h: void ns3::UdpHeader::InitializeChecksum(ns3::Ipv4Address source, ns3::Ipv4Address destination, uint8_t protocol) [member function] + cls.add_method('InitializeChecksum', 'void', [param('ns3::Ipv4Address', 'source'), param('ns3::Ipv4Address', 'destination'), param('uint8_t', 'protocol')]) + ## udp-header.h: static ns3::TypeId ns3::UdpHeader::GetTypeId() [member function] + cls.add_method('GetTypeId', 'ns3::TypeId', [], is_static=True) + ## udp-header.h: ns3::TypeId ns3::UdpHeader::GetInstanceTypeId() const [member function] + cls.add_method('GetInstanceTypeId', 'ns3::TypeId', [], is_const=True, is_virtual=True) + ## udp-header.h: void ns3::UdpHeader::Print(std::ostream & os) const [member function] + cls.add_method('Print', 'void', [param('std::ostream&', 'os')], is_const=True, is_virtual=True) + ## udp-header.h: uint32_t ns3::UdpHeader::GetSerializedSize() const [member function] + cls.add_method('GetSerializedSize', 'uint32_t', [], is_const=True, is_virtual=True) + ## udp-header.h: void ns3::UdpHeader::Serialize(ns3::Buffer::Iterator start) const [member function] + cls.add_method('Serialize', 'void', [param('ns3::Buffer::Iterator', 'start')], is_const=True, is_virtual=True) + ## udp-header.h: uint32_t ns3::UdpHeader::Deserialize(ns3::Buffer::Iterator start) [member function] + cls.add_method('Deserialize', 'uint32_t', [param('ns3::Buffer::Iterator', 'start')], is_virtual=True) + ## udp-header.h: bool ns3::UdpHeader::IsChecksumOk() const [member function] + cls.add_method('IsChecksumOk', 'bool', [], is_const=True) + return + +def register_Ns3TcpHeader_methods(root_module, cls): + ## tcp-header.h: ns3::TcpHeader::TcpHeader() [constructor] + cls.add_constructor([], visibility='public') + ## tcp-header.h: void ns3::TcpHeader::EnableChecksums() [member function] + cls.add_method('EnableChecksums', 'void', []) + ## tcp-header.h: void ns3::TcpHeader::SetSourcePort(uint16_t port) [member function] + cls.add_method('SetSourcePort', 'void', [param('uint16_t', 'port')]) + ## tcp-header.h: void ns3::TcpHeader::SetDestinationPort(uint16_t port) [member function] + cls.add_method('SetDestinationPort', 'void', [param('uint16_t', 'port')]) + ## tcp-header.h: void ns3::TcpHeader::SetSequenceNumber(SequenceNumber sequenceNumber) [member function] + cls.add_method('SetSequenceNumber', 'void', [param('SequenceNumber', 'sequenceNumber')]) + ## tcp-header.h: void ns3::TcpHeader::SetAckNumber(SequenceNumber ackNumber) [member function] + cls.add_method('SetAckNumber', 'void', [param('SequenceNumber', 'ackNumber')]) + ## tcp-header.h: void ns3::TcpHeader::SetLength(uint8_t length) [member function] + cls.add_method('SetLength', 'void', [param('uint8_t', 'length')]) + ## tcp-header.h: void ns3::TcpHeader::SetFlags(uint8_t flags) [member function] + cls.add_method('SetFlags', 'void', [param('uint8_t', 'flags')]) + ## tcp-header.h: void ns3::TcpHeader::SetWindowSize(uint16_t windowSize) [member function] + cls.add_method('SetWindowSize', 'void', [param('uint16_t', 'windowSize')]) + ## tcp-header.h: void ns3::TcpHeader::SetChecksum(uint16_t checksum) [member function] + cls.add_method('SetChecksum', 'void', [param('uint16_t', 'checksum')]) + ## tcp-header.h: void ns3::TcpHeader::SetUrgentPointer(uint16_t urgentPointer) [member function] + cls.add_method('SetUrgentPointer', 'void', [param('uint16_t', 'urgentPointer')]) + ## tcp-header.h: uint16_t ns3::TcpHeader::GetSourcePort() const [member function] + cls.add_method('GetSourcePort', 'uint16_t', [], is_const=True) + ## tcp-header.h: uint16_t ns3::TcpHeader::GetDestinationPort() const [member function] + cls.add_method('GetDestinationPort', 'uint16_t', [], is_const=True) + ## tcp-header.h: SequenceNumber ns3::TcpHeader::GetSequenceNumber() const [member function] + cls.add_method('GetSequenceNumber', 'SequenceNumber', [], is_const=True) + ## tcp-header.h: SequenceNumber ns3::TcpHeader::GetAckNumber() const [member function] + cls.add_method('GetAckNumber', 'SequenceNumber', [], is_const=True) + ## tcp-header.h: uint8_t ns3::TcpHeader::GetLength() const [member function] + cls.add_method('GetLength', 'uint8_t', [], is_const=True) + ## tcp-header.h: uint8_t ns3::TcpHeader::GetFlags() const [member function] + cls.add_method('GetFlags', 'uint8_t', [], is_const=True) + ## tcp-header.h: uint16_t ns3::TcpHeader::GetWindowSize() const [member function] + cls.add_method('GetWindowSize', 'uint16_t', [], is_const=True) + ## tcp-header.h: uint16_t ns3::TcpHeader::GetChecksum() const [member function] + cls.add_method('GetChecksum', 'uint16_t', [], is_const=True) + ## tcp-header.h: uint16_t ns3::TcpHeader::GetUrgentPointer() const [member function] + cls.add_method('GetUrgentPointer', 'uint16_t', [], is_const=True) + ## tcp-header.h: void ns3::TcpHeader::InitializeChecksum(ns3::Ipv4Address source, ns3::Ipv4Address destination, uint8_t protocol) [member function] + cls.add_method('InitializeChecksum', 'void', [param('ns3::Ipv4Address', 'source'), param('ns3::Ipv4Address', 'destination'), param('uint8_t', 'protocol')]) + ## tcp-header.h: static ns3::TypeId ns3::TcpHeader::GetTypeId() [member function] + cls.add_method('GetTypeId', 'ns3::TypeId', [], is_static=True) + ## tcp-header.h: ns3::TypeId ns3::TcpHeader::GetInstanceTypeId() const [member function] + cls.add_method('GetInstanceTypeId', 'ns3::TypeId', [], is_const=True, is_virtual=True) + ## tcp-header.h: void ns3::TcpHeader::Print(std::ostream & os) const [member function] + cls.add_method('Print', 'void', [param('std::ostream&', 'os')], is_const=True, is_virtual=True) + ## tcp-header.h: uint32_t ns3::TcpHeader::GetSerializedSize() const [member function] + cls.add_method('GetSerializedSize', 'uint32_t', [], is_const=True, is_virtual=True) + ## tcp-header.h: void ns3::TcpHeader::Serialize(ns3::Buffer::Iterator start) const [member function] + cls.add_method('Serialize', 'void', [param('ns3::Buffer::Iterator', 'start')], is_const=True, is_virtual=True) + ## tcp-header.h: uint32_t ns3::TcpHeader::Deserialize(ns3::Buffer::Iterator start) [member function] + cls.add_method('Deserialize', 'uint32_t', [param('ns3::Buffer::Iterator', 'start')], is_virtual=True) + ## tcp-header.h: void ns3::TcpHeader::SetPayloadSize(uint16_t size) [member function] + cls.add_method('SetPayloadSize', 'void', [param('uint16_t', 'size')]) + ## tcp-header.h: bool ns3::TcpHeader::IsChecksumOk() const [member function] + cls.add_method('IsChecksumOk', 'bool', [], is_const=True) + return + +def register_Ns3Ipv4StaticRouting_methods(root_module, cls): + ## ipv4-static-routing.h: ns3::Ipv4StaticRouting::Ipv4StaticRouting() [constructor] + cls.add_constructor([], visibility='public') + ## ipv4-static-routing.h: bool ns3::Ipv4StaticRouting::RequestRoute(uint32_t ifIndex, ns3::Ipv4Header const & ipHeader, ns3::Ptr packet, ns3::Callback,const ns3::Ipv4Header&,ns3::empty,ns3::empty> routeReply) [member function] + cls.add_method('RequestRoute', 'bool', [param('uint32_t', 'ifIndex'), param('ns3::Ipv4Header&', 'ipHeader', is_const=True), param('ns3::Ptr< ns3::Packet >', 'packet'), param('ns3::Callback< void, bool, const ns3::Ipv4Route&, ns3::Ptr< ns3::Packet >, const ns3::Ipv4Header&, ns3::empty, ns3::empty >', 'routeReply')], is_virtual=True) + ## ipv4-static-routing.h: bool ns3::Ipv4StaticRouting::RequestIfIndex(ns3::Ipv4Address destination, uint32_t & ifIndex) [member function] + cls.add_method('RequestIfIndex', 'bool', [param('ns3::Ipv4Address', 'destination'), param('uint32_t&', 'ifIndex')], is_virtual=True) + ## ipv4-static-routing.h: void ns3::Ipv4StaticRouting::AddHostRouteTo(ns3::Ipv4Address dest, ns3::Ipv4Address nextHop, uint32_t interface) [member function] + cls.add_method('AddHostRouteTo', 'void', [param('ns3::Ipv4Address', 'dest'), param('ns3::Ipv4Address', 'nextHop'), param('uint32_t', 'interface')]) + ## ipv4-static-routing.h: void ns3::Ipv4StaticRouting::AddHostRouteTo(ns3::Ipv4Address dest, uint32_t interface) [member function] + cls.add_method('AddHostRouteTo', 'void', [param('ns3::Ipv4Address', 'dest'), param('uint32_t', 'interface')]) + ## ipv4-static-routing.h: void ns3::Ipv4StaticRouting::AddNetworkRouteTo(ns3::Ipv4Address network, ns3::Ipv4Mask networkMask, ns3::Ipv4Address nextHop, uint32_t interface) [member function] + cls.add_method('AddNetworkRouteTo', 'void', [param('ns3::Ipv4Address', 'network'), param('ns3::Ipv4Mask', 'networkMask'), param('ns3::Ipv4Address', 'nextHop'), param('uint32_t', 'interface')]) + ## ipv4-static-routing.h: void ns3::Ipv4StaticRouting::AddNetworkRouteTo(ns3::Ipv4Address network, ns3::Ipv4Mask networkMask, uint32_t interface) [member function] + cls.add_method('AddNetworkRouteTo', 'void', [param('ns3::Ipv4Address', 'network'), param('ns3::Ipv4Mask', 'networkMask'), param('uint32_t', 'interface')]) + ## ipv4-static-routing.h: void ns3::Ipv4StaticRouting::SetDefaultRoute(ns3::Ipv4Address nextHop, uint32_t interface) [member function] + cls.add_method('SetDefaultRoute', 'void', [param('ns3::Ipv4Address', 'nextHop'), param('uint32_t', 'interface')]) + ## ipv4-static-routing.h: uint32_t ns3::Ipv4StaticRouting::GetNRoutes() [member function] + cls.add_method('GetNRoutes', 'uint32_t', []) + ## ipv4-static-routing.h: ns3::Ipv4Route * ns3::Ipv4StaticRouting::GetDefaultRoute() [member function] + cls.add_method('GetDefaultRoute', 'ns3::Ipv4Route *', []) + ## ipv4-static-routing.h: ns3::Ipv4Route * ns3::Ipv4StaticRouting::GetRoute(uint32_t i) [member function] + cls.add_method('GetRoute', 'ns3::Ipv4Route *', [param('uint32_t', 'i')]) + ## ipv4-static-routing.h: void ns3::Ipv4StaticRouting::RemoveRoute(uint32_t i) [member function] + cls.add_method('RemoveRoute', 'void', [param('uint32_t', 'i')]) + ## ipv4-static-routing.h: void ns3::Ipv4StaticRouting::AddMulticastRoute(ns3::Ipv4Address origin, ns3::Ipv4Address group, uint32_t inputInterface, std::vector > outputInterfaces) [member function] + cls.add_method('AddMulticastRoute', 'void', [param('ns3::Ipv4Address', 'origin'), param('ns3::Ipv4Address', 'group'), param('uint32_t', 'inputInterface'), param('std::vector< unsigned int, std::allocator< unsigned int > >', 'outputInterfaces')]) + ## ipv4-static-routing.h: void ns3::Ipv4StaticRouting::SetDefaultMulticastRoute(uint32_t outputInterface) [member function] + cls.add_method('SetDefaultMulticastRoute', 'void', [param('uint32_t', 'outputInterface')]) + ## ipv4-static-routing.h: uint32_t ns3::Ipv4StaticRouting::GetNMulticastRoutes() const [member function] + cls.add_method('GetNMulticastRoutes', 'uint32_t', [], is_const=True) + ## ipv4-static-routing.h: ns3::Ipv4MulticastRoute * ns3::Ipv4StaticRouting::GetMulticastRoute(uint32_t i) const [member function] + cls.add_method('GetMulticastRoute', 'ns3::Ipv4MulticastRoute *', [param('uint32_t', 'i')], is_const=True) + ## ipv4-static-routing.h: ns3::Ipv4MulticastRoute * ns3::Ipv4StaticRouting::GetDefaultMulticastRoute() const [member function] + cls.add_method('GetDefaultMulticastRoute', 'ns3::Ipv4MulticastRoute *', [], is_const=True) + ## ipv4-static-routing.h: bool ns3::Ipv4StaticRouting::RemoveMulticastRoute(ns3::Ipv4Address origin, ns3::Ipv4Address group, uint32_t inputInterface) [member function] + cls.add_method('RemoveMulticastRoute', 'bool', [param('ns3::Ipv4Address', 'origin'), param('ns3::Ipv4Address', 'group'), param('uint32_t', 'inputInterface')]) + ## ipv4-static-routing.h: void ns3::Ipv4StaticRouting::RemoveMulticastRoute(uint32_t index) [member function] + cls.add_method('RemoveMulticastRoute', 'void', [param('uint32_t', 'index')]) + ## ipv4-static-routing.h: void ns3::Ipv4StaticRouting::DoDispose() [member function] + cls.add_method('DoDispose', 'void', [], visibility='protected', is_virtual=True) + return + +def register_Ns3Ipv4L3Protocol_methods(root_module, cls): + ## ipv4-l3-protocol.h: ns3::Ipv4L3Protocol::PROT_NUMBER [variable] + cls.add_static_attribute('PROT_NUMBER', retval('uint16_t', is_const=True), is_const=True) + ## ipv4-l3-protocol.h: static ns3::TypeId ns3::Ipv4L3Protocol::GetTypeId() [member function] + cls.add_method('GetTypeId', 'ns3::TypeId', [], is_static=True) + ## ipv4-l3-protocol.h: ns3::Ipv4L3Protocol::Ipv4L3Protocol() [constructor] + cls.add_constructor([], visibility='public') + ## ipv4-l3-protocol.h: void ns3::Ipv4L3Protocol::SetNode(ns3::Ptr node) [member function] + cls.add_method('SetNode', 'void', [param('ns3::Ptr< ns3::Node >', 'node')]) + ## ipv4-l3-protocol.h: void ns3::Ipv4L3Protocol::SetDefaultTtl(uint8_t ttl) [member function] + cls.add_method('SetDefaultTtl', 'void', [param('uint8_t', 'ttl')]) + ## ipv4-l3-protocol.h: ns3::Ptr ns3::Ipv4L3Protocol::FindInterfaceForDevice(ns3::Ptr device) [member function] + cls.add_method('FindInterfaceForDevice', 'ns3::Ptr< ns3::Ipv4Interface >', [param('ns3::Ptr< const ns3::NetDevice >', 'device')]) + ## ipv4-l3-protocol.h: void ns3::Ipv4L3Protocol::Receive(ns3::Ptr device, ns3::Ptr p, uint16_t protocol, ns3::Address const & from) [member function] + cls.add_method('Receive', 'void', [param('ns3::Ptr< ns3::NetDevice >', 'device'), param('ns3::Ptr< ns3::Packet >', 'p'), param('uint16_t', 'protocol'), param('ns3::Address&', 'from', is_const=True)]) + ## ipv4-l3-protocol.h: void ns3::Ipv4L3Protocol::Send(ns3::Ptr packet, ns3::Ipv4Address source, ns3::Ipv4Address destination, uint8_t protocol) [member function] + cls.add_method('Send', 'void', [param('ns3::Ptr< ns3::Packet >', 'packet'), param('ns3::Ipv4Address', 'source'), param('ns3::Ipv4Address', 'destination'), param('uint8_t', 'protocol')]) + ## ipv4-l3-protocol.h: void ns3::Ipv4L3Protocol::AddHostRouteTo(ns3::Ipv4Address dest, ns3::Ipv4Address nextHop, uint32_t interface) [member function] + cls.add_method('AddHostRouteTo', 'void', [param('ns3::Ipv4Address', 'dest'), param('ns3::Ipv4Address', 'nextHop'), param('uint32_t', 'interface')]) + ## ipv4-l3-protocol.h: void ns3::Ipv4L3Protocol::AddHostRouteTo(ns3::Ipv4Address dest, uint32_t interface) [member function] + cls.add_method('AddHostRouteTo', 'void', [param('ns3::Ipv4Address', 'dest'), param('uint32_t', 'interface')]) + ## ipv4-l3-protocol.h: void ns3::Ipv4L3Protocol::AddNetworkRouteTo(ns3::Ipv4Address network, ns3::Ipv4Mask networkMask, ns3::Ipv4Address nextHop, uint32_t interface) [member function] + cls.add_method('AddNetworkRouteTo', 'void', [param('ns3::Ipv4Address', 'network'), param('ns3::Ipv4Mask', 'networkMask'), param('ns3::Ipv4Address', 'nextHop'), param('uint32_t', 'interface')]) + ## ipv4-l3-protocol.h: void ns3::Ipv4L3Protocol::AddNetworkRouteTo(ns3::Ipv4Address network, ns3::Ipv4Mask networkMask, uint32_t interface) [member function] + cls.add_method('AddNetworkRouteTo', 'void', [param('ns3::Ipv4Address', 'network'), param('ns3::Ipv4Mask', 'networkMask'), param('uint32_t', 'interface')]) + ## ipv4-l3-protocol.h: void ns3::Ipv4L3Protocol::SetDefaultRoute(ns3::Ipv4Address nextHop, uint32_t interface) [member function] + cls.add_method('SetDefaultRoute', 'void', [param('ns3::Ipv4Address', 'nextHop'), param('uint32_t', 'interface')]) + ## ipv4-l3-protocol.h: void ns3::Ipv4L3Protocol::Lookup(ns3::Ipv4Header const & ipHeader, ns3::Ptr packet, ns3::Callback,const ns3::Ipv4Header&,ns3::empty,ns3::empty> routeReply) [member function] + cls.add_method('Lookup', 'void', [param('ns3::Ipv4Header&', 'ipHeader', is_const=True), param('ns3::Ptr< ns3::Packet >', 'packet'), param('ns3::Callback< void, bool, const ns3::Ipv4Route&, ns3::Ptr< ns3::Packet >, const ns3::Ipv4Header&, ns3::empty, ns3::empty >', 'routeReply')]) + ## ipv4-l3-protocol.h: uint32_t ns3::Ipv4L3Protocol::GetNRoutes() [member function] + cls.add_method('GetNRoutes', 'uint32_t', []) + ## ipv4-l3-protocol.h: ns3::Ipv4Route * ns3::Ipv4L3Protocol::GetRoute(uint32_t i) [member function] + cls.add_method('GetRoute', 'ns3::Ipv4Route *', [param('uint32_t', 'i')]) + ## ipv4-l3-protocol.h: void ns3::Ipv4L3Protocol::RemoveRoute(uint32_t i) [member function] + cls.add_method('RemoveRoute', 'void', [param('uint32_t', 'i')]) + ## ipv4-l3-protocol.h: void ns3::Ipv4L3Protocol::AddMulticastRoute(ns3::Ipv4Address origin, ns3::Ipv4Address group, uint32_t inputInterface, std::vector > outputInterfaces) [member function] + cls.add_method('AddMulticastRoute', 'void', [param('ns3::Ipv4Address', 'origin'), param('ns3::Ipv4Address', 'group'), param('uint32_t', 'inputInterface'), param('std::vector< unsigned int, std::allocator< unsigned int > >', 'outputInterfaces')]) + ## ipv4-l3-protocol.h: void ns3::Ipv4L3Protocol::SetDefaultMulticastRoute(uint32_t onputInterface) [member function] + cls.add_method('SetDefaultMulticastRoute', 'void', [param('uint32_t', 'onputInterface')]) + ## ipv4-l3-protocol.h: uint32_t ns3::Ipv4L3Protocol::GetNMulticastRoutes() const [member function] + cls.add_method('GetNMulticastRoutes', 'uint32_t', [], is_const=True) + ## ipv4-l3-protocol.h: ns3::Ipv4MulticastRoute * ns3::Ipv4L3Protocol::GetMulticastRoute(uint32_t i) const [member function] + cls.add_method('GetMulticastRoute', 'ns3::Ipv4MulticastRoute *', [param('uint32_t', 'i')], is_const=True) + ## ipv4-l3-protocol.h: void ns3::Ipv4L3Protocol::RemoveMulticastRoute(ns3::Ipv4Address origin, ns3::Ipv4Address group, uint32_t inputInterface) [member function] + cls.add_method('RemoveMulticastRoute', 'void', [param('ns3::Ipv4Address', 'origin'), param('ns3::Ipv4Address', 'group'), param('uint32_t', 'inputInterface')]) + ## ipv4-l3-protocol.h: void ns3::Ipv4L3Protocol::RemoveMulticastRoute(uint32_t i) [member function] + cls.add_method('RemoveMulticastRoute', 'void', [param('uint32_t', 'i')]) + ## ipv4-l3-protocol.h: uint32_t ns3::Ipv4L3Protocol::AddInterface(ns3::Ptr device) [member function] + cls.add_method('AddInterface', 'uint32_t', [param('ns3::Ptr< ns3::NetDevice >', 'device')]) + ## ipv4-l3-protocol.h: ns3::Ptr ns3::Ipv4L3Protocol::GetInterface(uint32_t i) const [member function] + cls.add_method('GetInterface', 'ns3::Ptr< ns3::Ipv4Interface >', [param('uint32_t', 'i')], is_const=True) + ## ipv4-l3-protocol.h: uint32_t ns3::Ipv4L3Protocol::GetNInterfaces() const [member function] + cls.add_method('GetNInterfaces', 'uint32_t', [], is_const=True) + ## ipv4-l3-protocol.h: uint32_t ns3::Ipv4L3Protocol::FindInterfaceForAddr(ns3::Ipv4Address addr) const [member function] + cls.add_method('FindInterfaceForAddr', 'uint32_t', [param('ns3::Ipv4Address', 'addr')], is_const=True) + ## ipv4-l3-protocol.h: uint32_t ns3::Ipv4L3Protocol::FindInterfaceForAddr(ns3::Ipv4Address addr, ns3::Ipv4Mask mask) const [member function] + cls.add_method('FindInterfaceForAddr', 'uint32_t', [param('ns3::Ipv4Address', 'addr'), param('ns3::Ipv4Mask', 'mask')], is_const=True) + ## ipv4-l3-protocol.h: int32_t ns3::Ipv4L3Protocol::FindInterfaceIndexForDevice(ns3::Ptr device) const [member function] + cls.add_method('FindInterfaceIndexForDevice', 'int32_t', [param('ns3::Ptr< ns3::NetDevice >', 'device')], is_const=True) + ## ipv4-l3-protocol.h: void ns3::Ipv4L3Protocol::JoinMulticastGroup(ns3::Ipv4Address origin, ns3::Ipv4Address group) [member function] + cls.add_method('JoinMulticastGroup', 'void', [param('ns3::Ipv4Address', 'origin'), param('ns3::Ipv4Address', 'group')]) + ## ipv4-l3-protocol.h: void ns3::Ipv4L3Protocol::LeaveMulticastGroup(ns3::Ipv4Address origin, ns3::Ipv4Address group) [member function] + cls.add_method('LeaveMulticastGroup', 'void', [param('ns3::Ipv4Address', 'origin'), param('ns3::Ipv4Address', 'group')]) + ## ipv4-l3-protocol.h: void ns3::Ipv4L3Protocol::SetAddress(uint32_t i, ns3::Ipv4Address address) [member function] + cls.add_method('SetAddress', 'void', [param('uint32_t', 'i'), param('ns3::Ipv4Address', 'address')]) + ## ipv4-l3-protocol.h: void ns3::Ipv4L3Protocol::SetNetworkMask(uint32_t i, ns3::Ipv4Mask mask) [member function] + cls.add_method('SetNetworkMask', 'void', [param('uint32_t', 'i'), param('ns3::Ipv4Mask', 'mask')]) + ## ipv4-l3-protocol.h: ns3::Ipv4Mask ns3::Ipv4L3Protocol::GetNetworkMask(uint32_t t) const [member function] + cls.add_method('GetNetworkMask', 'ns3::Ipv4Mask', [param('uint32_t', 't')], is_const=True) + ## ipv4-l3-protocol.h: ns3::Ipv4Address ns3::Ipv4L3Protocol::GetAddress(uint32_t i) const [member function] + cls.add_method('GetAddress', 'ns3::Ipv4Address', [param('uint32_t', 'i')], is_const=True) + ## ipv4-l3-protocol.h: void ns3::Ipv4L3Protocol::SetMetric(uint32_t i, uint16_t metric) [member function] + cls.add_method('SetMetric', 'void', [param('uint32_t', 'i'), param('uint16_t', 'metric')]) + ## ipv4-l3-protocol.h: uint16_t ns3::Ipv4L3Protocol::GetMetric(uint32_t i) const [member function] + cls.add_method('GetMetric', 'uint16_t', [param('uint32_t', 'i')], is_const=True) + ## ipv4-l3-protocol.h: bool ns3::Ipv4L3Protocol::GetIfIndexForDestination(ns3::Ipv4Address destination, uint32_t & ifIndex) const [member function] + cls.add_method('GetIfIndexForDestination', 'bool', [param('ns3::Ipv4Address', 'destination'), param('uint32_t&', 'ifIndex')], is_const=True) + ## ipv4-l3-protocol.h: uint16_t ns3::Ipv4L3Protocol::GetMtu(uint32_t i) const [member function] + cls.add_method('GetMtu', 'uint16_t', [param('uint32_t', 'i')], is_const=True) + ## ipv4-l3-protocol.h: bool ns3::Ipv4L3Protocol::IsUp(uint32_t i) const [member function] + cls.add_method('IsUp', 'bool', [param('uint32_t', 'i')], is_const=True) + ## ipv4-l3-protocol.h: void ns3::Ipv4L3Protocol::SetUp(uint32_t i) [member function] + cls.add_method('SetUp', 'void', [param('uint32_t', 'i')]) + ## ipv4-l3-protocol.h: void ns3::Ipv4L3Protocol::SetDown(uint32_t i) [member function] + cls.add_method('SetDown', 'void', [param('uint32_t', 'i')]) + ## ipv4-l3-protocol.h: void ns3::Ipv4L3Protocol::AddRoutingProtocol(ns3::Ptr routingProtocol, int priority) [member function] + cls.add_method('AddRoutingProtocol', 'void', [param('ns3::Ptr< ns3::Ipv4RoutingProtocol >', 'routingProtocol'), param('int', 'priority')]) + ## ipv4-l3-protocol.h: void ns3::Ipv4L3Protocol::DoDispose() [member function] + cls.add_method('DoDispose', 'void', [], visibility='protected', is_virtual=True) + return + +def register_functions(root_module): + module = root_module + ## internet-stack.h: extern void ns3::AddInternetStack(ns3::Ptr node) [free function] + module.add_function('AddInternetStack', 'void', [param('ns3::Ptr< ns3::Node >', 'node')]) + register_functions_ns3_internal(module.get_submodule('internal'), root_module) + register_functions_ns3_TimeStepPrecision(module.get_submodule('TimeStepPrecision'), root_module) + register_functions_ns3_Config(module.get_submodule('Config'), root_module) + register_functions_ns3_olsr(module.get_submodule('olsr'), root_module) + return + +def register_functions_ns3_internal(module, root_module): + return + +def register_functions_ns3_TimeStepPrecision(module, root_module): + return + +def register_functions_ns3_Config(module, root_module): + return + +def register_functions_ns3_olsr(module, root_module): + return + diff --git a/bindings/python/ns3_module_mobility.py b/bindings/python/ns3_module_mobility.py new file mode 100644 index 000000000..2f5cedefe --- /dev/null +++ b/bindings/python/ns3_module_mobility.py @@ -0,0 +1,439 @@ +from pybindgen import Module, FileCodeSink, write_preamble, param, retval + +def register_types(module): + root_module = module.get_root() + + ## static-speed-helper.h: ns3::StaticSpeedHelper [class] + module.add_class('StaticSpeedHelper', allow_subclassing=False) + ## vector.h: ns3::Vector [class] + module.add_class('Vector') + ## vector.h: ns3::VectorChecker [class] + module.add_class('VectorChecker', parent=root_module['ns3::AttributeChecker']) + ## rectangle.h: ns3::RectangleChecker [class] + module.add_class('RectangleChecker', parent=root_module['ns3::AttributeChecker']) + ## rectangle.h: ns3::Rectangle [class] + module.add_class('Rectangle') + ## rectangle.h: ns3::Rectangle::Side [enumeration] + module.add_enum('Side', ['RIGHT', 'LEFT', 'TOP', 'BOTTOM'], outer_class=root_module['ns3::Rectangle']) + ## position-allocator.h: ns3::PositionAllocator [class] + module.add_class('PositionAllocator', allow_subclassing=True, parent=root_module['ns3::Object']) + ## position-allocator.h: ns3::ListPositionAllocator [class] + module.add_class('ListPositionAllocator', allow_subclassing=True, parent=root_module['ns3::PositionAllocator']) + ## rectangle.h: ns3::RectangleValue [class] + module.add_class('RectangleValue', allow_subclassing=True, parent=root_module['ns3::AttributeValue']) + ## position-allocator.h: ns3::RandomRectanglePositionAllocator [class] + module.add_class('RandomRectanglePositionAllocator', allow_subclassing=True, parent=root_module['ns3::PositionAllocator']) + ## vector.h: ns3::VectorValue [class] + module.add_class('VectorValue', allow_subclassing=True, parent=root_module['ns3::AttributeValue']) + ## position-allocator.h: ns3::RandomDiscPositionAllocator [class] + module.add_class('RandomDiscPositionAllocator', allow_subclassing=True, parent=root_module['ns3::PositionAllocator']) + ## mobility-model.h: ns3::MobilityModel [class] + module.add_class('MobilityModel', allow_subclassing=True, parent=root_module['ns3::Object']) + ## random-direction-2d-mobility-model.h: ns3::RandomDirection2dMobilityModel [class] + module.add_class('RandomDirection2dMobilityModel', allow_subclassing=True, parent=root_module['ns3::MobilityModel']) + ## position-allocator.h: ns3::GridPositionAllocator [class] + module.add_class('GridPositionAllocator', allow_subclassing=True, parent=root_module['ns3::PositionAllocator']) + ## position-allocator.h: ns3::GridPositionAllocator::LayoutType [enumeration] + module.add_enum('LayoutType', ['ROW_FIRST', 'COLUMN_FIRST'], outer_class=root_module['ns3::GridPositionAllocator']) + ## random-waypoint-mobility-model.h: ns3::RandomWaypointMobilityModel [class] + module.add_class('RandomWaypointMobilityModel', allow_subclassing=True, parent=root_module['ns3::MobilityModel']) + ## random-walk-2d-mobility-model.h: ns3::RandomWalk2dMobilityModel [class] + module.add_class('RandomWalk2dMobilityModel', allow_subclassing=True, parent=root_module['ns3::MobilityModel']) + ## random-walk-2d-mobility-model.h: ns3::RandomWalk2dMobilityModel::Mode [enumeration] + module.add_enum('Mode', ['MODE_DISTANCE', 'MODE_TIME'], outer_class=root_module['ns3::RandomWalk2dMobilityModel']) + ## static-speed-mobility-model.h: ns3::StaticSpeedMobilityModel [class] + module.add_class('StaticSpeedMobilityModel', allow_subclassing=True, parent=root_module['ns3::MobilityModel']) + ## hierarchical-mobility-model.h: ns3::HierarchicalMobilityModel [class] + module.add_class('HierarchicalMobilityModel', allow_subclassing=True, parent=root_module['ns3::MobilityModel']) + ## static-mobility-model.h: ns3::StaticMobilityModel [class] + module.add_class('StaticMobilityModel', allow_subclassing=True, parent=root_module['ns3::MobilityModel']) + + ## Register a nested module for the namespace internal + + nested_module = module.add_cpp_namespace('internal') + register_types_ns3_internal(nested_module) + + + ## Register a nested module for the namespace TimeStepPrecision + + nested_module = module.add_cpp_namespace('TimeStepPrecision') + register_types_ns3_TimeStepPrecision(nested_module) + + + ## Register a nested module for the namespace Config + + nested_module = module.add_cpp_namespace('Config') + register_types_ns3_Config(nested_module) + + + ## Register a nested module for the namespace olsr + + nested_module = module.add_cpp_namespace('olsr') + register_types_ns3_olsr(nested_module) + + +def register_types_ns3_internal(module): + root_module = module.get_root() + + +def register_types_ns3_TimeStepPrecision(module): + root_module = module.get_root() + + +def register_types_ns3_Config(module): + root_module = module.get_root() + + +def register_types_ns3_olsr(module): + root_module = module.get_root() + + +def register_methods(root_module): + register_Ns3StaticSpeedHelper_methods(root_module, root_module['ns3::StaticSpeedHelper']) + register_Ns3Vector_methods(root_module, root_module['ns3::Vector']) + register_Ns3VectorChecker_methods(root_module, root_module['ns3::VectorChecker']) + register_Ns3RectangleChecker_methods(root_module, root_module['ns3::RectangleChecker']) + register_Ns3Rectangle_methods(root_module, root_module['ns3::Rectangle']) + register_Ns3PositionAllocator_methods(root_module, root_module['ns3::PositionAllocator']) + register_Ns3ListPositionAllocator_methods(root_module, root_module['ns3::ListPositionAllocator']) + register_Ns3RectangleValue_methods(root_module, root_module['ns3::RectangleValue']) + register_Ns3RandomRectanglePositionAllocator_methods(root_module, root_module['ns3::RandomRectanglePositionAllocator']) + register_Ns3VectorValue_methods(root_module, root_module['ns3::VectorValue']) + register_Ns3RandomDiscPositionAllocator_methods(root_module, root_module['ns3::RandomDiscPositionAllocator']) + register_Ns3MobilityModel_methods(root_module, root_module['ns3::MobilityModel']) + register_Ns3RandomDirection2dMobilityModel_methods(root_module, root_module['ns3::RandomDirection2dMobilityModel']) + register_Ns3GridPositionAllocator_methods(root_module, root_module['ns3::GridPositionAllocator']) + register_Ns3RandomWaypointMobilityModel_methods(root_module, root_module['ns3::RandomWaypointMobilityModel']) + register_Ns3RandomWalk2dMobilityModel_methods(root_module, root_module['ns3::RandomWalk2dMobilityModel']) + register_Ns3StaticSpeedMobilityModel_methods(root_module, root_module['ns3::StaticSpeedMobilityModel']) + register_Ns3HierarchicalMobilityModel_methods(root_module, root_module['ns3::HierarchicalMobilityModel']) + register_Ns3StaticMobilityModel_methods(root_module, root_module['ns3::StaticMobilityModel']) + return + +def register_Ns3StaticSpeedHelper_methods(root_module, cls): + ## static-speed-helper.h: ns3::StaticSpeedHelper::StaticSpeedHelper() [constructor] + cls.add_constructor([], visibility='public') + ## static-speed-helper.h: ns3::StaticSpeedHelper::StaticSpeedHelper(ns3::Vector const & position) [constructor] + cls.add_constructor([param('ns3::Vector&', 'position', is_const=True)], visibility='public') + ## static-speed-helper.h: ns3::StaticSpeedHelper::StaticSpeedHelper(ns3::Vector const & position, ns3::Vector const & speed) [constructor] + cls.add_constructor([param('ns3::Vector&', 'position', is_const=True), param('ns3::Vector&', 'speed', is_const=True)], visibility='public') + ## static-speed-helper.h: void ns3::StaticSpeedHelper::InitializePosition(ns3::Vector const & position) [member function] + cls.add_method('InitializePosition', 'void', [param('ns3::Vector&', 'position', is_const=True)]) + ## static-speed-helper.h: void ns3::StaticSpeedHelper::Reset(ns3::Vector const & speed) [member function] + cls.add_method('Reset', 'void', [param('ns3::Vector&', 'speed', is_const=True)]) + ## static-speed-helper.h: ns3::Vector ns3::StaticSpeedHelper::GetCurrentPosition(ns3::Rectangle const & bounds) const [member function] + cls.add_method('GetCurrentPosition', 'ns3::Vector', [param('ns3::Rectangle&', 'bounds', is_const=True)], is_const=True) + ## static-speed-helper.h: ns3::Vector ns3::StaticSpeedHelper::GetCurrentPosition() const [member function] + cls.add_method('GetCurrentPosition', 'ns3::Vector', [], is_const=True) + ## static-speed-helper.h: ns3::Vector ns3::StaticSpeedHelper::GetVelocity() const [member function] + cls.add_method('GetVelocity', 'ns3::Vector', [], is_const=True) + ## static-speed-helper.h: void ns3::StaticSpeedHelper::SetSpeed(ns3::Vector const & speed) [member function] + cls.add_method('SetSpeed', 'void', [param('ns3::Vector&', 'speed', is_const=True)]) + ## static-speed-helper.h: void ns3::StaticSpeedHelper::Pause() [member function] + cls.add_method('Pause', 'void', []) + ## static-speed-helper.h: void ns3::StaticSpeedHelper::Unpause() [member function] + cls.add_method('Unpause', 'void', []) + return + +def register_Ns3Vector_methods(root_module, cls): + ## vector.h: ns3::Vector::Vector(ns3::Vector const & arg0) [copy constructor] + cls.add_constructor([param('ns3::Vector&', 'arg0', is_const=True)], visibility='public') + ## vector.h: ns3::Vector::Vector(double _x, double _y, double _z) [constructor] + cls.add_constructor([param('double', '_x'), param('double', '_y'), param('double', '_z')], visibility='public') + ## vector.h: ns3::Vector::Vector() [constructor] + cls.add_constructor([], visibility='public') + ## vector.h: ns3::Vector::x [variable] + cls.add_instance_attribute('x', 'double', is_const=False) + ## vector.h: ns3::Vector::y [variable] + cls.add_instance_attribute('y', 'double', is_const=False) + ## vector.h: ns3::Vector::z [variable] + cls.add_instance_attribute('z', 'double', is_const=False) + cls.add_output_stream_operator() + return + +def register_Ns3VectorChecker_methods(root_module, cls): + cls.add_constructor([]) + return + +def register_Ns3RectangleChecker_methods(root_module, cls): + cls.add_constructor([]) + return + +def register_Ns3Rectangle_methods(root_module, cls): + ## rectangle.h: ns3::Rectangle::Rectangle(ns3::Rectangle const & arg0) [copy constructor] + cls.add_constructor([param('ns3::Rectangle&', 'arg0', is_const=True)], visibility='public') + ## rectangle.h: ns3::Rectangle::Rectangle(double _xMin, double _xMax, double _yMin, double _yMax) [constructor] + cls.add_constructor([param('double', '_xMin'), param('double', '_xMax'), param('double', '_yMin'), param('double', '_yMax')], visibility='public') + ## rectangle.h: ns3::Rectangle::Rectangle() [constructor] + cls.add_constructor([], visibility='public') + ## rectangle.h: ns3::Vector ns3::Rectangle::CalculateIntersection(ns3::Vector const & current, ns3::Vector const & speed) const [member function] + cls.add_method('CalculateIntersection', 'ns3::Vector', [param('ns3::Vector&', 'current', is_const=True), param('ns3::Vector&', 'speed', is_const=True)], is_const=True) + ## rectangle.h: ns3::Rectangle::Side ns3::Rectangle::GetClosestSide(ns3::Vector const & position) const [member function] + cls.add_method('GetClosestSide', 'ns3::Rectangle::Side', [param('ns3::Vector&', 'position', is_const=True)], is_const=True) + ## rectangle.h: bool ns3::Rectangle::IsInside(ns3::Vector const & position) const [member function] + cls.add_method('IsInside', 'bool', [param('ns3::Vector&', 'position', is_const=True)], is_const=True) + ## rectangle.h: ns3::Rectangle::xMax [variable] + cls.add_instance_attribute('xMax', 'double', is_const=False) + ## rectangle.h: ns3::Rectangle::xMin [variable] + cls.add_instance_attribute('xMin', 'double', is_const=False) + ## rectangle.h: ns3::Rectangle::yMax [variable] + cls.add_instance_attribute('yMax', 'double', is_const=False) + ## rectangle.h: ns3::Rectangle::yMin [variable] + cls.add_instance_attribute('yMin', 'double', is_const=False) + cls.add_output_stream_operator() + return + +def register_Ns3PositionAllocator_methods(root_module, cls): + ## position-allocator.h: static ns3::TypeId ns3::PositionAllocator::GetTypeId() [member function] + cls.add_method('GetTypeId', 'ns3::TypeId', [], is_static=True) + ## position-allocator.h: ns3::PositionAllocator::PositionAllocator() [constructor] + cls.add_constructor([], visibility='public') + ## position-allocator.h: ns3::Vector ns3::PositionAllocator::GetNext() const [member function] + cls.add_method('GetNext', 'ns3::Vector', [], is_pure_virtual=True, is_const=True, is_virtual=True) + return + +def register_Ns3ListPositionAllocator_methods(root_module, cls): + ## position-allocator.h: static ns3::TypeId ns3::ListPositionAllocator::GetTypeId() [member function] + cls.add_method('GetTypeId', 'ns3::TypeId', [], is_static=True) + ## position-allocator.h: ns3::ListPositionAllocator::ListPositionAllocator() [constructor] + cls.add_constructor([], visibility='public') + ## position-allocator.h: void ns3::ListPositionAllocator::Add(ns3::Vector v) [member function] + cls.add_method('Add', 'void', [param('ns3::Vector', 'v')]) + ## position-allocator.h: ns3::Vector ns3::ListPositionAllocator::GetNext() const [member function] + cls.add_method('GetNext', 'ns3::Vector', [], is_const=True, is_virtual=True) + return + +def register_Ns3RectangleValue_methods(root_module, cls): + ## rectangle.h: ns3::RectangleValue::RectangleValue() [constructor] + cls.add_constructor([], visibility='public') + ## rectangle.h: ns3::RectangleValue::RectangleValue(ns3::Rectangle const & value) [constructor] + cls.add_constructor([param('ns3::Rectangle&', 'value', is_const=True)], visibility='public') + ## rectangle.h: void ns3::RectangleValue::Set(ns3::Rectangle const & value) [member function] + cls.add_method('Set', 'void', [param('ns3::Rectangle&', 'value', is_const=True)]) + ## rectangle.h: ns3::Rectangle ns3::RectangleValue::Get() const [member function] + cls.add_method('Get', 'ns3::Rectangle', [], is_const=True) + ## rectangle.h: ns3::Ptr ns3::RectangleValue::Copy() const [member function] + cls.add_method('Copy', 'ns3::Ptr< ns3::AttributeValue >', [], is_const=True, is_virtual=True) + ## rectangle.h: std::string ns3::RectangleValue::SerializeToString(ns3::Ptr checker) const [member function] + cls.add_method('SerializeToString', 'std::string', [param('ns3::Ptr< ns3::AttributeChecker const >', 'checker')], is_const=True, is_virtual=True) + ## rectangle.h: bool ns3::RectangleValue::DeserializeFromString(std::string value, ns3::Ptr checker) [member function] + cls.add_method('DeserializeFromString', 'bool', [param('std::string', 'value'), param('ns3::Ptr< ns3::AttributeChecker const >', 'checker')], is_virtual=True) + return + +def register_Ns3RandomRectanglePositionAllocator_methods(root_module, cls): + ## position-allocator.h: static ns3::TypeId ns3::RandomRectanglePositionAllocator::GetTypeId() [member function] + cls.add_method('GetTypeId', 'ns3::TypeId', [], is_static=True) + ## position-allocator.h: ns3::RandomRectanglePositionAllocator::RandomRectanglePositionAllocator() [constructor] + cls.add_constructor([], visibility='public') + ## position-allocator.h: void ns3::RandomRectanglePositionAllocator::SetX(ns3::RandomVariable x) [member function] + cls.add_method('SetX', 'void', [param('ns3::RandomVariable', 'x')]) + ## position-allocator.h: void ns3::RandomRectanglePositionAllocator::SetY(ns3::RandomVariable y) [member function] + cls.add_method('SetY', 'void', [param('ns3::RandomVariable', 'y')]) + ## position-allocator.h: ns3::Vector ns3::RandomRectanglePositionAllocator::GetNext() const [member function] + cls.add_method('GetNext', 'ns3::Vector', [], is_const=True, is_virtual=True) + return + +def register_Ns3VectorValue_methods(root_module, cls): + ## vector.h: ns3::VectorValue::VectorValue() [constructor] + cls.add_constructor([], visibility='public') + ## vector.h: ns3::VectorValue::VectorValue(ns3::Vector const & value) [constructor] + cls.add_constructor([param('ns3::Vector&', 'value', is_const=True)], visibility='public') + ## vector.h: void ns3::VectorValue::Set(ns3::Vector const & value) [member function] + cls.add_method('Set', 'void', [param('ns3::Vector&', 'value', is_const=True)]) + ## vector.h: ns3::Vector ns3::VectorValue::Get() const [member function] + cls.add_method('Get', 'ns3::Vector', [], is_const=True) + ## vector.h: ns3::Ptr ns3::VectorValue::Copy() const [member function] + cls.add_method('Copy', 'ns3::Ptr< ns3::AttributeValue >', [], is_const=True, is_virtual=True) + ## vector.h: std::string ns3::VectorValue::SerializeToString(ns3::Ptr checker) const [member function] + cls.add_method('SerializeToString', 'std::string', [param('ns3::Ptr< ns3::AttributeChecker const >', 'checker')], is_const=True, is_virtual=True) + ## vector.h: bool ns3::VectorValue::DeserializeFromString(std::string value, ns3::Ptr checker) [member function] + cls.add_method('DeserializeFromString', 'bool', [param('std::string', 'value'), param('ns3::Ptr< ns3::AttributeChecker const >', 'checker')], is_virtual=True) + return + +def register_Ns3RandomDiscPositionAllocator_methods(root_module, cls): + ## position-allocator.h: static ns3::TypeId ns3::RandomDiscPositionAllocator::GetTypeId() [member function] + cls.add_method('GetTypeId', 'ns3::TypeId', [], is_static=True) + ## position-allocator.h: ns3::RandomDiscPositionAllocator::RandomDiscPositionAllocator() [constructor] + cls.add_constructor([], visibility='public') + ## position-allocator.h: void ns3::RandomDiscPositionAllocator::SetTheta(ns3::RandomVariable theta) [member function] + cls.add_method('SetTheta', 'void', [param('ns3::RandomVariable', 'theta')]) + ## position-allocator.h: void ns3::RandomDiscPositionAllocator::SetRho(ns3::RandomVariable rho) [member function] + cls.add_method('SetRho', 'void', [param('ns3::RandomVariable', 'rho')]) + ## position-allocator.h: void ns3::RandomDiscPositionAllocator::SetX(double x) [member function] + cls.add_method('SetX', 'void', [param('double', 'x')]) + ## position-allocator.h: void ns3::RandomDiscPositionAllocator::SetY(double y) [member function] + cls.add_method('SetY', 'void', [param('double', 'y')]) + ## position-allocator.h: ns3::Vector ns3::RandomDiscPositionAllocator::GetNext() const [member function] + cls.add_method('GetNext', 'ns3::Vector', [], is_const=True, is_virtual=True) + return + +def register_Ns3MobilityModel_methods(root_module, cls): + ## mobility-model.h: static ns3::TypeId ns3::MobilityModel::GetTypeId() [member function] + cls.add_method('GetTypeId', 'ns3::TypeId', [], is_static=True) + ## mobility-model.h: ns3::MobilityModel::MobilityModel() [constructor] + cls.add_constructor([], visibility='public') + ## mobility-model.h: ns3::Vector ns3::MobilityModel::GetPosition() const [member function] + cls.add_method('GetPosition', 'ns3::Vector', [], is_const=True) + ## mobility-model.h: void ns3::MobilityModel::SetPosition(ns3::Vector const & position) [member function] + cls.add_method('SetPosition', 'void', [param('ns3::Vector&', 'position', is_const=True)]) + ## mobility-model.h: ns3::Vector ns3::MobilityModel::GetVelocity() const [member function] + cls.add_method('GetVelocity', 'ns3::Vector', [], is_const=True) + ## mobility-model.h: double ns3::MobilityModel::GetDistanceFrom(ns3::Ptr position) const [member function] + cls.add_method('GetDistanceFrom', 'double', [param('ns3::Ptr< const ns3::MobilityModel >', 'position')], is_const=True) + ## mobility-model.h: void ns3::MobilityModel::NotifyCourseChange() const [member function] + cls.add_method('NotifyCourseChange', 'void', [], is_const=True, visibility='protected') + ## mobility-model.h: ns3::Vector ns3::MobilityModel::DoGetPosition() const [member function] + cls.add_method('DoGetPosition', 'ns3::Vector', [], is_pure_virtual=True, is_const=True, visibility='private', is_virtual=True) + ## mobility-model.h: void ns3::MobilityModel::DoSetPosition(ns3::Vector const & position) [member function] + cls.add_method('DoSetPosition', 'void', [param('ns3::Vector&', 'position', is_const=True)], is_pure_virtual=True, visibility='private', is_virtual=True) + ## mobility-model.h: ns3::Vector ns3::MobilityModel::DoGetVelocity() const [member function] + cls.add_method('DoGetVelocity', 'ns3::Vector', [], is_pure_virtual=True, is_const=True, visibility='private', is_virtual=True) + return + +def register_Ns3RandomDirection2dMobilityModel_methods(root_module, cls): + ## random-direction-2d-mobility-model.h: static ns3::TypeId ns3::RandomDirection2dMobilityModel::GetTypeId() [member function] + cls.add_method('GetTypeId', 'ns3::TypeId', [], is_static=True) + ## random-direction-2d-mobility-model.h: ns3::RandomDirection2dMobilityModel::RandomDirection2dMobilityModel() [constructor] + cls.add_constructor([], visibility='public') + ## random-direction-2d-mobility-model.h: void ns3::RandomDirection2dMobilityModel::DoDispose() [member function] + cls.add_method('DoDispose', 'void', [], visibility='private', is_virtual=True) + ## random-direction-2d-mobility-model.h: ns3::Vector ns3::RandomDirection2dMobilityModel::DoGetPosition() const [member function] + cls.add_method('DoGetPosition', 'ns3::Vector', [], is_const=True, visibility='private', is_virtual=True) + ## random-direction-2d-mobility-model.h: void ns3::RandomDirection2dMobilityModel::DoSetPosition(ns3::Vector const & position) [member function] + cls.add_method('DoSetPosition', 'void', [param('ns3::Vector&', 'position', is_const=True)], visibility='private', is_virtual=True) + ## random-direction-2d-mobility-model.h: ns3::Vector ns3::RandomDirection2dMobilityModel::DoGetVelocity() const [member function] + cls.add_method('DoGetVelocity', 'ns3::Vector', [], is_const=True, visibility='private', is_virtual=True) + return + +def register_Ns3GridPositionAllocator_methods(root_module, cls): + ## position-allocator.h: static ns3::TypeId ns3::GridPositionAllocator::GetTypeId() [member function] + cls.add_method('GetTypeId', 'ns3::TypeId', [], is_static=True) + ## position-allocator.h: ns3::GridPositionAllocator::GridPositionAllocator() [constructor] + cls.add_constructor([], visibility='public') + ## position-allocator.h: void ns3::GridPositionAllocator::SetMinX(double xMin) [member function] + cls.add_method('SetMinX', 'void', [param('double', 'xMin')]) + ## position-allocator.h: void ns3::GridPositionAllocator::SetMinY(double yMin) [member function] + cls.add_method('SetMinY', 'void', [param('double', 'yMin')]) + ## position-allocator.h: void ns3::GridPositionAllocator::SetDeltaX(double deltaX) [member function] + cls.add_method('SetDeltaX', 'void', [param('double', 'deltaX')]) + ## position-allocator.h: void ns3::GridPositionAllocator::SetDeltaY(double deltaY) [member function] + cls.add_method('SetDeltaY', 'void', [param('double', 'deltaY')]) + ## position-allocator.h: void ns3::GridPositionAllocator::SetN(uint32_t n) [member function] + cls.add_method('SetN', 'void', [param('uint32_t', 'n')]) + ## position-allocator.h: void ns3::GridPositionAllocator::SetLayoutType(ns3::GridPositionAllocator::LayoutType layoutType) [member function] + cls.add_method('SetLayoutType', 'void', [param('ns3::GridPositionAllocator::LayoutType', 'layoutType')]) + ## position-allocator.h: double ns3::GridPositionAllocator::GetMinX() const [member function] + cls.add_method('GetMinX', 'double', [], is_const=True) + ## position-allocator.h: double ns3::GridPositionAllocator::GetMinY() const [member function] + cls.add_method('GetMinY', 'double', [], is_const=True) + ## position-allocator.h: double ns3::GridPositionAllocator::GetDeltaX() const [member function] + cls.add_method('GetDeltaX', 'double', [], is_const=True) + ## position-allocator.h: double ns3::GridPositionAllocator::GetDeltaY() const [member function] + cls.add_method('GetDeltaY', 'double', [], is_const=True) + ## position-allocator.h: uint32_t ns3::GridPositionAllocator::GetN() const [member function] + cls.add_method('GetN', 'uint32_t', [], is_const=True) + ## position-allocator.h: ns3::GridPositionAllocator::LayoutType ns3::GridPositionAllocator::GetLayoutType() const [member function] + cls.add_method('GetLayoutType', 'ns3::GridPositionAllocator::LayoutType', [], is_const=True) + ## position-allocator.h: ns3::Vector ns3::GridPositionAllocator::GetNext() const [member function] + cls.add_method('GetNext', 'ns3::Vector', [], is_const=True, is_virtual=True) + return + +def register_Ns3RandomWaypointMobilityModel_methods(root_module, cls): + ## random-waypoint-mobility-model.h: static ns3::TypeId ns3::RandomWaypointMobilityModel::GetTypeId() [member function] + cls.add_method('GetTypeId', 'ns3::TypeId', [], is_static=True) + ## random-waypoint-mobility-model.h: ns3::RandomWaypointMobilityModel::RandomWaypointMobilityModel() [constructor] + cls.add_constructor([], visibility='public') + ## random-waypoint-mobility-model.h: ns3::Vector ns3::RandomWaypointMobilityModel::DoGetPosition() const [member function] + cls.add_method('DoGetPosition', 'ns3::Vector', [], is_const=True, visibility='private', is_virtual=True) + ## random-waypoint-mobility-model.h: void ns3::RandomWaypointMobilityModel::DoSetPosition(ns3::Vector const & position) [member function] + cls.add_method('DoSetPosition', 'void', [param('ns3::Vector&', 'position', is_const=True)], visibility='private', is_virtual=True) + ## random-waypoint-mobility-model.h: ns3::Vector ns3::RandomWaypointMobilityModel::DoGetVelocity() const [member function] + cls.add_method('DoGetVelocity', 'ns3::Vector', [], is_const=True, visibility='private', is_virtual=True) + return + +def register_Ns3RandomWalk2dMobilityModel_methods(root_module, cls): + ## random-walk-2d-mobility-model.h: static ns3::TypeId ns3::RandomWalk2dMobilityModel::GetTypeId() [member function] + cls.add_method('GetTypeId', 'ns3::TypeId', [], is_static=True) + ## random-walk-2d-mobility-model.h: ns3::RandomWalk2dMobilityModel::RandomWalk2dMobilityModel() [constructor] + cls.add_constructor([], visibility='public') + ## random-walk-2d-mobility-model.h: void ns3::RandomWalk2dMobilityModel::DoDispose() [member function] + cls.add_method('DoDispose', 'void', [], visibility='private', is_virtual=True) + ## random-walk-2d-mobility-model.h: ns3::Vector ns3::RandomWalk2dMobilityModel::DoGetPosition() const [member function] + cls.add_method('DoGetPosition', 'ns3::Vector', [], is_const=True, visibility='private', is_virtual=True) + ## random-walk-2d-mobility-model.h: void ns3::RandomWalk2dMobilityModel::DoSetPosition(ns3::Vector const & position) [member function] + cls.add_method('DoSetPosition', 'void', [param('ns3::Vector&', 'position', is_const=True)], visibility='private', is_virtual=True) + ## random-walk-2d-mobility-model.h: ns3::Vector ns3::RandomWalk2dMobilityModel::DoGetVelocity() const [member function] + cls.add_method('DoGetVelocity', 'ns3::Vector', [], is_const=True, visibility='private', is_virtual=True) + return + +def register_Ns3StaticSpeedMobilityModel_methods(root_module, cls): + ## static-speed-mobility-model.h: static ns3::TypeId ns3::StaticSpeedMobilityModel::GetTypeId() [member function] + cls.add_method('GetTypeId', 'ns3::TypeId', [], is_static=True) + ## static-speed-mobility-model.h: ns3::StaticSpeedMobilityModel::StaticSpeedMobilityModel() [constructor] + cls.add_constructor([], visibility='public') + ## static-speed-mobility-model.h: void ns3::StaticSpeedMobilityModel::SetSpeed(ns3::Vector const & speed) [member function] + cls.add_method('SetSpeed', 'void', [param('ns3::Vector&', 'speed', is_const=True)]) + ## static-speed-mobility-model.h: ns3::Vector ns3::StaticSpeedMobilityModel::DoGetPosition() const [member function] + cls.add_method('DoGetPosition', 'ns3::Vector', [], is_const=True, visibility='private', is_virtual=True) + ## static-speed-mobility-model.h: void ns3::StaticSpeedMobilityModel::DoSetPosition(ns3::Vector const & position) [member function] + cls.add_method('DoSetPosition', 'void', [param('ns3::Vector&', 'position', is_const=True)], visibility='private', is_virtual=True) + ## static-speed-mobility-model.h: ns3::Vector ns3::StaticSpeedMobilityModel::DoGetVelocity() const [member function] + cls.add_method('DoGetVelocity', 'ns3::Vector', [], is_const=True, visibility='private', is_virtual=True) + return + +def register_Ns3HierarchicalMobilityModel_methods(root_module, cls): + ## hierarchical-mobility-model.h: static ns3::TypeId ns3::HierarchicalMobilityModel::GetTypeId() [member function] + cls.add_method('GetTypeId', 'ns3::TypeId', [], is_static=True) + ## hierarchical-mobility-model.h: ns3::HierarchicalMobilityModel::HierarchicalMobilityModel() [constructor] + cls.add_constructor([], visibility='public') + ## hierarchical-mobility-model.h: ns3::Ptr ns3::HierarchicalMobilityModel::GetChild() const [member function] + cls.add_method('GetChild', 'ns3::Ptr< ns3::MobilityModel >', [], is_const=True) + ## hierarchical-mobility-model.h: ns3::Ptr ns3::HierarchicalMobilityModel::GetParent() const [member function] + cls.add_method('GetParent', 'ns3::Ptr< ns3::MobilityModel >', [], is_const=True) + ## hierarchical-mobility-model.h: ns3::Vector ns3::HierarchicalMobilityModel::DoGetPosition() const [member function] + cls.add_method('DoGetPosition', 'ns3::Vector', [], is_const=True, visibility='private', is_virtual=True) + ## hierarchical-mobility-model.h: void ns3::HierarchicalMobilityModel::DoSetPosition(ns3::Vector const & position) [member function] + cls.add_method('DoSetPosition', 'void', [param('ns3::Vector&', 'position', is_const=True)], visibility='private', is_virtual=True) + ## hierarchical-mobility-model.h: ns3::Vector ns3::HierarchicalMobilityModel::DoGetVelocity() const [member function] + cls.add_method('DoGetVelocity', 'ns3::Vector', [], is_const=True, visibility='private', is_virtual=True) + return + +def register_Ns3StaticMobilityModel_methods(root_module, cls): + ## static-mobility-model.h: static ns3::TypeId ns3::StaticMobilityModel::GetTypeId() [member function] + cls.add_method('GetTypeId', 'ns3::TypeId', [], is_static=True) + ## static-mobility-model.h: ns3::StaticMobilityModel::StaticMobilityModel() [constructor] + cls.add_constructor([], visibility='public') + ## static-mobility-model.h: ns3::Vector ns3::StaticMobilityModel::DoGetPosition() const [member function] + cls.add_method('DoGetPosition', 'ns3::Vector', [], is_const=True, visibility='private', is_virtual=True) + ## static-mobility-model.h: void ns3::StaticMobilityModel::DoSetPosition(ns3::Vector const & position) [member function] + cls.add_method('DoSetPosition', 'void', [param('ns3::Vector&', 'position', is_const=True)], visibility='private', is_virtual=True) + ## static-mobility-model.h: ns3::Vector ns3::StaticMobilityModel::DoGetVelocity() const [member function] + cls.add_method('DoGetVelocity', 'ns3::Vector', [], is_const=True, visibility='private', is_virtual=True) + return + +def register_functions(root_module): + module = root_module + ## rectangle.h: extern ns3::Ptr ns3::MakeRectangleChecker() [free function] + module.add_function('MakeRectangleChecker', 'ns3::Ptr< ns3::AttributeChecker const >', []) + ## vector.h: extern double ns3::CalculateDistance(ns3::Vector const & a, ns3::Vector const & b) [free function] + module.add_function('CalculateDistance', 'double', [param('ns3::Vector&', 'a', is_const=True), param('ns3::Vector&', 'b', is_const=True)]) + ## vector.h: extern ns3::Ptr ns3::MakeVectorChecker() [free function] + module.add_function('MakeVectorChecker', 'ns3::Ptr< ns3::AttributeChecker const >', []) + register_functions_ns3_internal(module.get_submodule('internal'), root_module) + register_functions_ns3_TimeStepPrecision(module.get_submodule('TimeStepPrecision'), root_module) + register_functions_ns3_Config(module.get_submodule('Config'), root_module) + register_functions_ns3_olsr(module.get_submodule('olsr'), root_module) + return + +def register_functions_ns3_internal(module, root_module): + return + +def register_functions_ns3_TimeStepPrecision(module, root_module): + return + +def register_functions_ns3_Config(module, root_module): + return + +def register_functions_ns3_olsr(module, root_module): + return + diff --git a/bindings/python/ns3_module_node.py b/bindings/python/ns3_module_node.py new file mode 100644 index 000000000..a8aa6a8b4 --- /dev/null +++ b/bindings/python/ns3_module_node.py @@ -0,0 +1,1380 @@ +from pybindgen import Module, FileCodeSink, write_preamble, param, retval + +def register_types(module): + root_module = module.get_root() + + ## ethernet-header.h: ns3::ethernet_header_t [enumeration] + module.add_enum('ethernet_header_t', ['LENGTH', 'VLAN', 'QINQ']) + ## node-list.h: ns3::NodeList [class] + module.add_class('NodeList') + ## address.h: ns3::Address [class] + module.add_class('Address') + ## address.h: ns3::Address::MaxSize_e [enumeration] + module.add_enum('MaxSize_e', ['MAX_SIZE'], outer_class=root_module['ns3::Address']) + ## ipv4-address.h: ns3::Ipv4AddressChecker [class] + module.add_class('Ipv4AddressChecker', parent=root_module['ns3::AttributeChecker']) + ## mac48-address.h: ns3::Mac48Address [class] + module.add_class('Mac48Address') + ## mac48-address.h: ns3::Mac48Address [class] + root_module['ns3::Mac48Address'].implicitly_converts_to(root_module['ns3::Address']) + ## mac64-address.h: ns3::Mac64Address [class] + module.add_class('Mac64Address') + ## mac64-address.h: ns3::Mac64Address [class] + root_module['ns3::Mac64Address'].implicitly_converts_to(root_module['ns3::Address']) + ## ipv4-address-generator.h: ns3::Ipv4AddressGenerator [class] + module.add_class('Ipv4AddressGenerator') + ## mac48-address.h: ns3::Mac48AddressChecker [class] + module.add_class('Mac48AddressChecker', parent=root_module['ns3::AttributeChecker']) + ## ipv4-address.h: ns3::Ipv4MaskChecker [class] + module.add_class('Ipv4MaskChecker', parent=root_module['ns3::AttributeChecker']) + ## ipv4-route.h: ns3::Ipv4Route [class] + module.add_class('Ipv4Route') + ## ipv4-route.h: ns3::Ipv4MulticastRoute [class] + module.add_class('Ipv4MulticastRoute') + ## address.h: ns3::AddressChecker [class] + module.add_class('AddressChecker', parent=root_module['ns3::AttributeChecker']) + ## packet-socket-address.h: ns3::PacketSocketAddress [class] + module.add_class('PacketSocketAddress') + ## packet-socket-address.h: ns3::PacketSocketAddress [class] + root_module['ns3::PacketSocketAddress'].implicitly_converts_to(root_module['ns3::Address']) + ## ipv4-address.h: ns3::Ipv4Mask [class] + module.add_class('Ipv4Mask') + ## ipv4-address.h: ns3::Ipv4AddressValue [class] + module.add_class('Ipv4AddressValue', allow_subclassing=True, parent=root_module['ns3::AttributeValue']) + ## ipv4.h: ns3::Ipv4RoutingProtocol [class] + module.add_class('Ipv4RoutingProtocol', allow_subclassing=True, parent=root_module['ns3::Object']) + ## mac48-address.h: ns3::Mac48AddressValue [class] + module.add_class('Mac48AddressValue', allow_subclassing=True, parent=root_module['ns3::AttributeValue']) + ## ipv4-address.h: ns3::Ipv4MaskValue [class] + module.add_class('Ipv4MaskValue', allow_subclassing=True, parent=root_module['ns3::AttributeValue']) + ## socket.h: ns3::SocketAddressTag [class] + module.add_class('SocketAddressTag', allow_subclassing=True, parent=root_module['ns3::Tag']) + ## inet-socket-address.h: ns3::InetSocketAddress [class] + module.add_class('InetSocketAddress') + ## inet-socket-address.h: ns3::InetSocketAddress [class] + root_module['ns3::InetSocketAddress'].implicitly_converts_to(root_module['ns3::Address']) + ## ipv4-address.h: ns3::Ipv4Address [class] + module.add_class('Ipv4Address') + ## ipv4-address.h: ns3::Ipv4Address [class] + root_module['ns3::Ipv4Address'].implicitly_converts_to(root_module['ns3::Address']) + ## application.h: ns3::Application [class] + module.add_class('Application', allow_subclassing=True, parent=root_module['ns3::Object']) + ## queue.h: ns3::Queue [class] + module.add_class('Queue', allow_subclassing=True, parent=root_module['ns3::Object']) + ## socket.h: ns3::Socket [class] + module.add_class('Socket', allow_subclassing=True, parent=root_module['ns3::Object']) + ## socket.h: ns3::Socket::SocketErrno [enumeration] + module.add_enum('SocketErrno', ['ERROR_NOTERROR', 'ERROR_ISCONN', 'ERROR_NOTCONN', 'ERROR_MSGSIZE', 'ERROR_AGAIN', 'ERROR_SHUTDOWN', 'ERROR_OPNOTSUPP', 'ERROR_AFNOSUPPORT', 'ERROR_INVAL', 'ERROR_BADF', 'ERROR_NOROUTETOHOST', 'SOCKET_ERRNO_LAST'], outer_class=root_module['ns3::Socket']) + ## ipv4-header.h: ns3::Ipv4Header [class] + module.add_class('Ipv4Header', allow_subclassing=True, parent=root_module['ns3::Header']) + ## udp-socket.h: ns3::UdpSocket [class] + module.add_class('UdpSocket', allow_subclassing=True, parent=root_module['ns3::Socket']) + ## net-device.h: ns3::NetDevice [class] + module.add_class('NetDevice', allow_subclassing=True, parent=root_module['ns3::Object']) + ## channel.h: ns3::Channel [class] + module.add_class('Channel', allow_subclassing=True, parent=root_module['ns3::Object']) + ## simple-channel.h: ns3::SimpleChannel [class] + module.add_class('SimpleChannel', allow_subclassing=True, parent=root_module['ns3::Channel']) + ## address.h: ns3::AddressValue [class] + module.add_class('AddressValue', allow_subclassing=True, parent=root_module['ns3::AttributeValue']) + ## node.h: ns3::Node [class] + module.add_class('Node', allow_subclassing=True, parent=root_module['ns3::Object']) + ## tcp-socket.h: ns3::TcpSocket [class] + module.add_class('TcpSocket', allow_subclassing=True, parent=root_module['ns3::Socket']) + ## ethernet-header.h: ns3::EthernetHeader [class] + module.add_class('EthernetHeader', allow_subclassing=True, parent=root_module['ns3::Header']) + ## socket.h: ns3::SocketIpTtlTag [class] + module.add_class('SocketIpTtlTag', allow_subclassing=True, parent=root_module['ns3::Tag']) + ## ipv4.h: ns3::Ipv4 [class] + module.add_class('Ipv4', allow_subclassing=True, parent=root_module['ns3::Object']) + ## socket-factory.h: ns3::SocketFactory [class] + module.add_class('SocketFactory', allow_subclassing=True, parent=root_module['ns3::Object']) + ## drop-tail-queue.h: ns3::DropTailQueue [class] + module.add_class('DropTailQueue', allow_subclassing=True, parent=root_module['ns3::Queue']) + ## ethernet-trailer.h: ns3::EthernetTrailer [class] + module.add_class('EthernetTrailer', allow_subclassing=True, parent=root_module['ns3::Trailer']) + ## llc-snap-header.h: ns3::LlcSnapHeader [class] + module.add_class('LlcSnapHeader', allow_subclassing=True, parent=root_module['ns3::Header']) + ## udp-socket-factory.h: ns3::UdpSocketFactory [class] + module.add_class('UdpSocketFactory', allow_subclassing=True, parent=root_module['ns3::SocketFactory']) + ## simple-net-device.h: ns3::SimpleNetDevice [class] + module.add_class('SimpleNetDevice', allow_subclassing=True, parent=root_module['ns3::NetDevice']) + ## tcp-socket-factory.h: ns3::TcpSocketFactory [class] + module.add_class('TcpSocketFactory', allow_subclassing=True, parent=root_module['ns3::SocketFactory']) + ## packet-socket-factory.h: ns3::PacketSocketFactory [class] + module.add_class('PacketSocketFactory', allow_subclassing=True, parent=root_module['ns3::SocketFactory']) + + ## Register a nested module for the namespace internal + + nested_module = module.add_cpp_namespace('internal') + register_types_ns3_internal(nested_module) + + + ## Register a nested module for the namespace TimeStepPrecision + + nested_module = module.add_cpp_namespace('TimeStepPrecision') + register_types_ns3_TimeStepPrecision(nested_module) + + + ## Register a nested module for the namespace Config + + nested_module = module.add_cpp_namespace('Config') + register_types_ns3_Config(nested_module) + + + ## Register a nested module for the namespace olsr + + nested_module = module.add_cpp_namespace('olsr') + register_types_ns3_olsr(nested_module) + + +def register_types_ns3_internal(module): + root_module = module.get_root() + + +def register_types_ns3_TimeStepPrecision(module): + root_module = module.get_root() + + +def register_types_ns3_Config(module): + root_module = module.get_root() + + +def register_types_ns3_olsr(module): + root_module = module.get_root() + + +def register_methods(root_module): + register_Ns3NodeList_methods(root_module, root_module['ns3::NodeList']) + register_Ns3Address_methods(root_module, root_module['ns3::Address']) + register_Ns3Ipv4AddressChecker_methods(root_module, root_module['ns3::Ipv4AddressChecker']) + register_Ns3Mac48Address_methods(root_module, root_module['ns3::Mac48Address']) + register_Ns3Mac64Address_methods(root_module, root_module['ns3::Mac64Address']) + register_Ns3Ipv4AddressGenerator_methods(root_module, root_module['ns3::Ipv4AddressGenerator']) + register_Ns3Mac48AddressChecker_methods(root_module, root_module['ns3::Mac48AddressChecker']) + register_Ns3Ipv4MaskChecker_methods(root_module, root_module['ns3::Ipv4MaskChecker']) + register_Ns3Ipv4Route_methods(root_module, root_module['ns3::Ipv4Route']) + register_Ns3Ipv4MulticastRoute_methods(root_module, root_module['ns3::Ipv4MulticastRoute']) + register_Ns3AddressChecker_methods(root_module, root_module['ns3::AddressChecker']) + register_Ns3PacketSocketAddress_methods(root_module, root_module['ns3::PacketSocketAddress']) + register_Ns3Ipv4Mask_methods(root_module, root_module['ns3::Ipv4Mask']) + register_Ns3Ipv4AddressValue_methods(root_module, root_module['ns3::Ipv4AddressValue']) + register_Ns3Ipv4RoutingProtocol_methods(root_module, root_module['ns3::Ipv4RoutingProtocol']) + register_Ns3Mac48AddressValue_methods(root_module, root_module['ns3::Mac48AddressValue']) + register_Ns3Ipv4MaskValue_methods(root_module, root_module['ns3::Ipv4MaskValue']) + register_Ns3SocketAddressTag_methods(root_module, root_module['ns3::SocketAddressTag']) + register_Ns3InetSocketAddress_methods(root_module, root_module['ns3::InetSocketAddress']) + register_Ns3Ipv4Address_methods(root_module, root_module['ns3::Ipv4Address']) + register_Ns3Application_methods(root_module, root_module['ns3::Application']) + register_Ns3Queue_methods(root_module, root_module['ns3::Queue']) + register_Ns3Socket_methods(root_module, root_module['ns3::Socket']) + register_Ns3Ipv4Header_methods(root_module, root_module['ns3::Ipv4Header']) + register_Ns3UdpSocket_methods(root_module, root_module['ns3::UdpSocket']) + register_Ns3NetDevice_methods(root_module, root_module['ns3::NetDevice']) + register_Ns3Channel_methods(root_module, root_module['ns3::Channel']) + register_Ns3SimpleChannel_methods(root_module, root_module['ns3::SimpleChannel']) + register_Ns3AddressValue_methods(root_module, root_module['ns3::AddressValue']) + register_Ns3Node_methods(root_module, root_module['ns3::Node']) + register_Ns3TcpSocket_methods(root_module, root_module['ns3::TcpSocket']) + register_Ns3EthernetHeader_methods(root_module, root_module['ns3::EthernetHeader']) + register_Ns3SocketIpTtlTag_methods(root_module, root_module['ns3::SocketIpTtlTag']) + register_Ns3Ipv4_methods(root_module, root_module['ns3::Ipv4']) + register_Ns3SocketFactory_methods(root_module, root_module['ns3::SocketFactory']) + register_Ns3DropTailQueue_methods(root_module, root_module['ns3::DropTailQueue']) + register_Ns3EthernetTrailer_methods(root_module, root_module['ns3::EthernetTrailer']) + register_Ns3LlcSnapHeader_methods(root_module, root_module['ns3::LlcSnapHeader']) + register_Ns3UdpSocketFactory_methods(root_module, root_module['ns3::UdpSocketFactory']) + register_Ns3SimpleNetDevice_methods(root_module, root_module['ns3::SimpleNetDevice']) + register_Ns3TcpSocketFactory_methods(root_module, root_module['ns3::TcpSocketFactory']) + register_Ns3PacketSocketFactory_methods(root_module, root_module['ns3::PacketSocketFactory']) + return + +def register_Ns3NodeList_methods(root_module, cls): + ## node-list.h: static uint32_t ns3::NodeList::Add(ns3::Ptr node) [member function] + cls.add_method('Add', 'uint32_t', [param('ns3::Ptr< ns3::Node >', 'node')], is_static=True) + ## node-list.h: static __gnu_cxx::__normal_iterator*,std::vector, std::allocator > > > ns3::NodeList::Begin() [member function] + cls.add_method('Begin', '__gnu_cxx::__normal_iterator< const ns3::Ptr< ns3::Node >, std::vector< ns3::Ptr< ns3::Node >, std::allocator< ns3::Ptr< ns3::Node > > > >', [], is_static=True) + ## node-list.h: static __gnu_cxx::__normal_iterator*,std::vector, std::allocator > > > ns3::NodeList::End() [member function] + cls.add_method('End', '__gnu_cxx::__normal_iterator< const ns3::Ptr< ns3::Node >, std::vector< ns3::Ptr< ns3::Node >, std::allocator< ns3::Ptr< ns3::Node > > > >', [], is_static=True) + ## node-list.h: static ns3::Ptr ns3::NodeList::GetNode(uint32_t n) [member function] + cls.add_method('GetNode', 'ns3::Ptr< ns3::Node >', [param('uint32_t', 'n')], is_static=True) + ## node-list.h: static uint32_t ns3::NodeList::GetNNodes() [member function] + cls.add_method('GetNNodes', 'uint32_t', [], is_static=True) + cls.add_constructor([]) + return + +def register_Ns3Address_methods(root_module, cls): + ## address.h: ns3::Address::Address() [constructor] + cls.add_constructor([], visibility='public') + ## address.h: ns3::Address::Address(uint8_t type, uint8_t const * buffer, uint8_t len) [constructor] + cls.add_constructor([param('uint8_t', 'type'), param('uint8_t *', 'buffer', transfer_ownership=False, is_const=True), param('uint8_t', 'len')], visibility='public') + ## address.h: ns3::Address::Address(ns3::Address const & address) [copy constructor] + cls.add_constructor([param('ns3::Address&', 'address', is_const=True)], visibility='public') + ## address.h: bool ns3::Address::CheckCompatible(uint8_t type, uint8_t len) const [member function] + cls.add_method('CheckCompatible', 'bool', [param('uint8_t', 'type'), param('uint8_t', 'len')], is_const=True) + ## address.h: uint32_t ns3::Address::CopyAllFrom(uint8_t const * buffer, uint8_t len) [member function] + cls.add_method('CopyAllFrom', 'uint32_t', [param('uint8_t *', 'buffer', transfer_ownership=False, is_const=True), param('uint8_t', 'len')]) + ## address.h: uint32_t ns3::Address::CopyAllTo(uint8_t * buffer, uint8_t len) const [member function] + cls.add_method('CopyAllTo', 'uint32_t', [param('uint8_t *', 'buffer'), param('uint8_t', 'len')], is_const=True) + ## address.h: uint32_t ns3::Address::CopyFrom(uint8_t const * buffer, uint8_t len) [member function] + cls.add_method('CopyFrom', 'uint32_t', [param('uint8_t *', 'buffer', transfer_ownership=False, is_const=True), param('uint8_t', 'len')]) + ## address.h: uint32_t ns3::Address::CopyTo(uint8_t * buffer) const [member function] + cls.add_method('CopyTo', 'uint32_t', [param('uint8_t *', 'buffer')], is_const=True) + ## address.h: void ns3::Address::Deserialize(ns3::TagBuffer buffer) [member function] + cls.add_method('Deserialize', 'void', [param('ns3::TagBuffer', 'buffer')]) + ## address.h: uint8_t ns3::Address::GetLength() const [member function] + cls.add_method('GetLength', 'uint8_t', [], is_const=True) + ## address.h: uint32_t ns3::Address::GetSerializedSize() const [member function] + cls.add_method('GetSerializedSize', 'uint32_t', [], is_const=True) + ## address.h: bool ns3::Address::IsInvalid() const [member function] + cls.add_method('IsInvalid', 'bool', [], is_const=True) + ## address.h: bool ns3::Address::IsMatchingType(uint8_t type) const [member function] + cls.add_method('IsMatchingType', 'bool', [param('uint8_t', 'type')], is_const=True) + ## address.h: static uint8_t ns3::Address::Register() [member function] + cls.add_method('Register', 'uint8_t', [], is_static=True) + ## address.h: void ns3::Address::Serialize(ns3::TagBuffer buffer) const [member function] + cls.add_method('Serialize', 'void', [param('ns3::TagBuffer', 'buffer')], is_const=True) + cls.add_output_stream_operator() + return + +def register_Ns3Ipv4AddressChecker_methods(root_module, cls): + cls.add_constructor([]) + return + +def register_Ns3Mac48Address_methods(root_module, cls): + ## mac48-address.h: ns3::Mac48Address::Mac48Address(ns3::Mac48Address const & arg0) [copy constructor] + cls.add_constructor([param('ns3::Mac48Address&', 'arg0', is_const=True)], visibility='public') + ## mac48-address.h: ns3::Mac48Address::Mac48Address() [constructor] + cls.add_constructor([], visibility='public') + ## mac48-address.h: ns3::Mac48Address::Mac48Address(char const * str) [constructor] + cls.add_constructor([param('char *', 'str', transfer_ownership=False, is_const=True)], visibility='public') + ## mac48-address.h: static ns3::Mac48Address ns3::Mac48Address::Allocate() [member function] + cls.add_method('Allocate', 'ns3::Mac48Address', [], is_static=True) + ## mac48-address.h: static ns3::Mac48Address ns3::Mac48Address::ConvertFrom(ns3::Address const & address) [member function] + cls.add_method('ConvertFrom', 'ns3::Mac48Address', [param('ns3::Address&', 'address', is_const=True)], is_static=True) + ## mac48-address.h: void ns3::Mac48Address::CopyFrom(uint8_t const * buffer) [member function] + cls.add_method('CopyFrom', 'void', [param('uint8_t *', 'buffer', transfer_ownership=False, is_const=True)]) + ## mac48-address.h: void ns3::Mac48Address::CopyTo(uint8_t * buffer) const [member function] + cls.add_method('CopyTo', 'void', [param('uint8_t *', 'buffer')], is_const=True) + ## mac48-address.h: static ns3::Mac48Address ns3::Mac48Address::GetBroadcast() [member function] + cls.add_method('GetBroadcast', 'ns3::Mac48Address', [], is_static=True) + ## mac48-address.h: bool ns3::Mac48Address::IsBroadcast() const [member function] + cls.add_method('IsBroadcast', 'bool', [], is_const=True) + ## mac48-address.h: static bool ns3::Mac48Address::IsMatchingType(ns3::Address const & address) [member function] + cls.add_method('IsMatchingType', 'bool', [param('ns3::Address&', 'address', is_const=True)], is_static=True) + ## mac48-address.h: bool ns3::Mac48Address::IsMulticast() const [member function] + cls.add_method('IsMulticast', 'bool', [], is_const=True) + cls.add_output_stream_operator() + return + +def register_Ns3Mac64Address_methods(root_module, cls): + ## mac64-address.h: ns3::Mac64Address::Mac64Address(ns3::Mac64Address const & arg0) [copy constructor] + cls.add_constructor([param('ns3::Mac64Address&', 'arg0', is_const=True)], visibility='public') + ## mac64-address.h: ns3::Mac64Address::Mac64Address() [constructor] + cls.add_constructor([], visibility='public') + ## mac64-address.h: ns3::Mac64Address::Mac64Address(char const * str) [constructor] + cls.add_constructor([param('char *', 'str', transfer_ownership=False, is_const=True)], visibility='public') + ## mac64-address.h: static ns3::Mac64Address ns3::Mac64Address::Allocate() [member function] + cls.add_method('Allocate', 'ns3::Mac64Address', [], is_static=True) + ## mac64-address.h: static ns3::Mac64Address ns3::Mac64Address::ConvertFrom(ns3::Address const & address) [member function] + cls.add_method('ConvertFrom', 'ns3::Mac64Address', [param('ns3::Address&', 'address', is_const=True)], is_static=True) + ## mac64-address.h: void ns3::Mac64Address::CopyFrom(uint8_t const * buffer) [member function] + cls.add_method('CopyFrom', 'void', [param('uint8_t *', 'buffer', transfer_ownership=False, is_const=True)]) + ## mac64-address.h: void ns3::Mac64Address::CopyTo(uint8_t * buffer) const [member function] + cls.add_method('CopyTo', 'void', [param('uint8_t *', 'buffer')], is_const=True) + ## mac64-address.h: static bool ns3::Mac64Address::IsMatchingType(ns3::Address const & address) [member function] + cls.add_method('IsMatchingType', 'bool', [param('ns3::Address&', 'address', is_const=True)], is_static=True) + cls.add_output_stream_operator() + return + +def register_Ns3Ipv4AddressGenerator_methods(root_module, cls): + ## ipv4-address-generator.h: static void ns3::Ipv4AddressGenerator::Init(ns3::Ipv4Address const net, ns3::Ipv4Mask const mask, ns3::Ipv4Address const addr="0.0.0.1") [member function] + cls.add_method('Init', 'void', [param('ns3::Ipv4Address', 'net', is_const=True), param('ns3::Ipv4Mask', 'mask', is_const=True), param('ns3::Ipv4Address', 'addr', default_value='"0.0.0.1"', is_const=True)], is_static=True) + ## ipv4-address-generator.h: static ns3::Ipv4Address ns3::Ipv4AddressGenerator::NextNetwork(ns3::Ipv4Mask const mask) [member function] + cls.add_method('NextNetwork', 'ns3::Ipv4Address', [param('ns3::Ipv4Mask', 'mask', is_const=True)], is_static=True) + ## ipv4-address-generator.h: static ns3::Ipv4Address ns3::Ipv4AddressGenerator::GetNetwork(ns3::Ipv4Mask const mask) [member function] + cls.add_method('GetNetwork', 'ns3::Ipv4Address', [param('ns3::Ipv4Mask', 'mask', is_const=True)], is_static=True) + ## ipv4-address-generator.h: static void ns3::Ipv4AddressGenerator::InitAddress(ns3::Ipv4Address const addr, ns3::Ipv4Mask const mask) [member function] + cls.add_method('InitAddress', 'void', [param('ns3::Ipv4Address', 'addr', is_const=True), param('ns3::Ipv4Mask', 'mask', is_const=True)], is_static=True) + ## ipv4-address-generator.h: static ns3::Ipv4Address ns3::Ipv4AddressGenerator::NextAddress(ns3::Ipv4Mask const mask) [member function] + cls.add_method('NextAddress', 'ns3::Ipv4Address', [param('ns3::Ipv4Mask', 'mask', is_const=True)], is_static=True) + ## ipv4-address-generator.h: static ns3::Ipv4Address ns3::Ipv4AddressGenerator::GetAddress(ns3::Ipv4Mask const mask) [member function] + cls.add_method('GetAddress', 'ns3::Ipv4Address', [param('ns3::Ipv4Mask', 'mask', is_const=True)], is_static=True) + ## ipv4-address-generator.h: static void ns3::Ipv4AddressGenerator::Reset() [member function] + cls.add_method('Reset', 'void', [], is_static=True) + ## ipv4-address-generator.h: static bool ns3::Ipv4AddressGenerator::AddAllocated(ns3::Ipv4Address const addr) [member function] + cls.add_method('AddAllocated', 'bool', [param('ns3::Ipv4Address', 'addr', is_const=True)], is_static=True) + ## ipv4-address-generator.h: static void ns3::Ipv4AddressGenerator::TestMode() [member function] + cls.add_method('TestMode', 'void', [], is_static=True) + cls.add_constructor([]) + return + +def register_Ns3Mac48AddressChecker_methods(root_module, cls): + cls.add_constructor([]) + return + +def register_Ns3Ipv4MaskChecker_methods(root_module, cls): + cls.add_constructor([]) + return + +def register_Ns3Ipv4Route_methods(root_module, cls): + ## ipv4-route.h: ns3::Ipv4Route::Ipv4Route() [constructor] + cls.add_constructor([], visibility='public') + ## ipv4-route.h: ns3::Ipv4Route::Ipv4Route(ns3::Ipv4Route const & route) [copy constructor] + cls.add_constructor([param('ns3::Ipv4Route&', 'route', is_const=True)], visibility='public') + ## ipv4-route.h: ns3::Ipv4Route::Ipv4Route(ns3::Ipv4Route const * route) [constructor] + cls.add_constructor([param('ns3::Ipv4Route *', 'route', transfer_ownership=False, is_const=True)], visibility='public') + ## ipv4-route.h: static ns3::Ipv4Route ns3::Ipv4Route::CreateDefaultRoute(ns3::Ipv4Address nextHop, uint32_t interface) [member function] + cls.add_method('CreateDefaultRoute', 'ns3::Ipv4Route', [param('ns3::Ipv4Address', 'nextHop'), param('uint32_t', 'interface')], is_static=True) + ## ipv4-route.h: static ns3::Ipv4Route ns3::Ipv4Route::CreateHostRouteTo(ns3::Ipv4Address dest, ns3::Ipv4Address nextHop, uint32_t interface) [member function] + cls.add_method('CreateHostRouteTo', 'ns3::Ipv4Route', [param('ns3::Ipv4Address', 'dest'), param('ns3::Ipv4Address', 'nextHop'), param('uint32_t', 'interface')], is_static=True) + ## ipv4-route.h: static ns3::Ipv4Route ns3::Ipv4Route::CreateHostRouteTo(ns3::Ipv4Address dest, uint32_t interface) [member function] + cls.add_method('CreateHostRouteTo', 'ns3::Ipv4Route', [param('ns3::Ipv4Address', 'dest'), param('uint32_t', 'interface')], is_static=True) + ## ipv4-route.h: static ns3::Ipv4Route ns3::Ipv4Route::CreateNetworkRouteTo(ns3::Ipv4Address network, ns3::Ipv4Mask networkMask, ns3::Ipv4Address nextHop, uint32_t interface) [member function] + cls.add_method('CreateNetworkRouteTo', 'ns3::Ipv4Route', [param('ns3::Ipv4Address', 'network'), param('ns3::Ipv4Mask', 'networkMask'), param('ns3::Ipv4Address', 'nextHop'), param('uint32_t', 'interface')], is_static=True) + ## ipv4-route.h: static ns3::Ipv4Route ns3::Ipv4Route::CreateNetworkRouteTo(ns3::Ipv4Address network, ns3::Ipv4Mask networkMask, uint32_t interface) [member function] + cls.add_method('CreateNetworkRouteTo', 'ns3::Ipv4Route', [param('ns3::Ipv4Address', 'network'), param('ns3::Ipv4Mask', 'networkMask'), param('uint32_t', 'interface')], is_static=True) + ## ipv4-route.h: ns3::Ipv4Address ns3::Ipv4Route::GetDest() const [member function] + cls.add_method('GetDest', 'ns3::Ipv4Address', [], is_const=True) + ## ipv4-route.h: ns3::Ipv4Address ns3::Ipv4Route::GetDestNetwork() const [member function] + cls.add_method('GetDestNetwork', 'ns3::Ipv4Address', [], is_const=True) + ## ipv4-route.h: ns3::Ipv4Mask ns3::Ipv4Route::GetDestNetworkMask() const [member function] + cls.add_method('GetDestNetworkMask', 'ns3::Ipv4Mask', [], is_const=True) + ## ipv4-route.h: ns3::Ipv4Address ns3::Ipv4Route::GetGateway() const [member function] + cls.add_method('GetGateway', 'ns3::Ipv4Address', [], is_const=True) + ## ipv4-route.h: uint32_t ns3::Ipv4Route::GetInterface() const [member function] + cls.add_method('GetInterface', 'uint32_t', [], is_const=True) + ## ipv4-route.h: bool ns3::Ipv4Route::IsDefault() const [member function] + cls.add_method('IsDefault', 'bool', [], is_const=True) + ## ipv4-route.h: bool ns3::Ipv4Route::IsGateway() const [member function] + cls.add_method('IsGateway', 'bool', [], is_const=True) + ## ipv4-route.h: bool ns3::Ipv4Route::IsHost() const [member function] + cls.add_method('IsHost', 'bool', [], is_const=True) + ## ipv4-route.h: bool ns3::Ipv4Route::IsNetwork() const [member function] + cls.add_method('IsNetwork', 'bool', [], is_const=True) + cls.add_output_stream_operator() + return + +def register_Ns3Ipv4MulticastRoute_methods(root_module, cls): + ## ipv4-route.h: ns3::Ipv4MulticastRoute::Ipv4MulticastRoute() [constructor] + cls.add_constructor([], visibility='public') + ## ipv4-route.h: ns3::Ipv4MulticastRoute::Ipv4MulticastRoute(ns3::Ipv4MulticastRoute const & route) [copy constructor] + cls.add_constructor([param('ns3::Ipv4MulticastRoute&', 'route', is_const=True)], visibility='public') + ## ipv4-route.h: ns3::Ipv4MulticastRoute::Ipv4MulticastRoute(ns3::Ipv4MulticastRoute const * route) [constructor] + cls.add_constructor([param('ns3::Ipv4MulticastRoute *', 'route', transfer_ownership=False, is_const=True)], visibility='public') + ## ipv4-route.h: static ns3::Ipv4MulticastRoute ns3::Ipv4MulticastRoute::CreateMulticastRoute(ns3::Ipv4Address origin, ns3::Ipv4Address group, uint32_t inputInterface, std::vector > outputInterfaces) [member function] + cls.add_method('CreateMulticastRoute', 'ns3::Ipv4MulticastRoute', [param('ns3::Ipv4Address', 'origin'), param('ns3::Ipv4Address', 'group'), param('uint32_t', 'inputInterface'), param('std::vector< unsigned int, std::allocator< unsigned int > >', 'outputInterfaces')], is_static=True) + ## ipv4-route.h: ns3::Ipv4Address ns3::Ipv4MulticastRoute::GetGroup() const [member function] + cls.add_method('GetGroup', 'ns3::Ipv4Address', [], is_const=True) + ## ipv4-route.h: uint32_t ns3::Ipv4MulticastRoute::GetInputInterface() const [member function] + cls.add_method('GetInputInterface', 'uint32_t', [], is_const=True) + ## ipv4-route.h: uint32_t ns3::Ipv4MulticastRoute::GetNOutputInterfaces() const [member function] + cls.add_method('GetNOutputInterfaces', 'uint32_t', [], is_const=True) + ## ipv4-route.h: ns3::Ipv4Address ns3::Ipv4MulticastRoute::GetOrigin() const [member function] + cls.add_method('GetOrigin', 'ns3::Ipv4Address', [], is_const=True) + ## ipv4-route.h: uint32_t ns3::Ipv4MulticastRoute::GetOutputInterface(uint32_t n) const [member function] + cls.add_method('GetOutputInterface', 'uint32_t', [param('uint32_t', 'n')], is_const=True) + ## ipv4-route.h: std::vector > ns3::Ipv4MulticastRoute::GetOutputInterfaces() const [member function] + cls.add_method('GetOutputInterfaces', 'std::vector< unsigned int, std::allocator< unsigned int > >', [], is_const=True) + cls.add_output_stream_operator() + return + +def register_Ns3AddressChecker_methods(root_module, cls): + cls.add_constructor([]) + return + +def register_Ns3PacketSocketAddress_methods(root_module, cls): + ## packet-socket-address.h: ns3::PacketSocketAddress::PacketSocketAddress() [constructor] + cls.add_constructor([], visibility='public') + ## packet-socket-address.h: void ns3::PacketSocketAddress::SetProtocol(uint16_t protocol) [member function] + cls.add_method('SetProtocol', 'void', [param('uint16_t', 'protocol')]) + ## packet-socket-address.h: void ns3::PacketSocketAddress::SetAllDevices() [member function] + cls.add_method('SetAllDevices', 'void', []) + ## packet-socket-address.h: void ns3::PacketSocketAddress::SetSingleDevice(uint32_t device) [member function] + cls.add_method('SetSingleDevice', 'void', [param('uint32_t', 'device')]) + ## packet-socket-address.h: void ns3::PacketSocketAddress::SetPhysicalAddress(ns3::Address const address) [member function] + cls.add_method('SetPhysicalAddress', 'void', [param('ns3::Address', 'address', is_const=True)]) + ## packet-socket-address.h: uint16_t ns3::PacketSocketAddress::GetProtocol() const [member function] + cls.add_method('GetProtocol', 'uint16_t', [], is_const=True) + ## packet-socket-address.h: uint32_t ns3::PacketSocketAddress::GetSingleDevice() const [member function] + cls.add_method('GetSingleDevice', 'uint32_t', [], is_const=True) + ## packet-socket-address.h: bool ns3::PacketSocketAddress::IsSingleDevice() const [member function] + cls.add_method('IsSingleDevice', 'bool', [], is_const=True) + ## packet-socket-address.h: ns3::Address ns3::PacketSocketAddress::GetPhysicalAddress() const [member function] + cls.add_method('GetPhysicalAddress', 'ns3::Address', [], is_const=True) + ## packet-socket-address.h: static ns3::PacketSocketAddress ns3::PacketSocketAddress::ConvertFrom(ns3::Address const & address) [member function] + cls.add_method('ConvertFrom', 'ns3::PacketSocketAddress', [param('ns3::Address&', 'address', is_const=True)], is_static=True) + ## packet-socket-address.h: static bool ns3::PacketSocketAddress::IsMatchingType(ns3::Address const & address) [member function] + cls.add_method('IsMatchingType', 'bool', [param('ns3::Address&', 'address', is_const=True)], is_static=True) + return + +def register_Ns3Ipv4Mask_methods(root_module, cls): + ## ipv4-address.h: ns3::Ipv4Mask::Ipv4Mask(ns3::Ipv4Mask const & arg0) [copy constructor] + cls.add_constructor([param('ns3::Ipv4Mask&', 'arg0', is_const=True)], visibility='public') + ## ipv4-address.h: ns3::Ipv4Mask::Ipv4Mask() [constructor] + cls.add_constructor([], visibility='public') + ## ipv4-address.h: ns3::Ipv4Mask::Ipv4Mask(uint32_t mask) [constructor] + cls.add_constructor([param('uint32_t', 'mask')], visibility='public') + ## ipv4-address.h: ns3::Ipv4Mask::Ipv4Mask(char const * mask) [constructor] + cls.add_constructor([param('char *', 'mask', transfer_ownership=False, is_const=True)], visibility='public') + ## ipv4-address.h: uint32_t ns3::Ipv4Mask::Get() const [member function] + cls.add_method('Get', 'uint32_t', [], is_const=True) + ## ipv4-address.h: uint32_t ns3::Ipv4Mask::GetInverse() const [member function] + cls.add_method('GetInverse', 'uint32_t', [], is_const=True) + ## ipv4-address.h: static ns3::Ipv4Mask ns3::Ipv4Mask::GetLoopback() [member function] + cls.add_method('GetLoopback', 'ns3::Ipv4Mask', [], is_static=True) + ## ipv4-address.h: static ns3::Ipv4Mask ns3::Ipv4Mask::GetZero() [member function] + cls.add_method('GetZero', 'ns3::Ipv4Mask', [], is_static=True) + ## ipv4-address.h: bool ns3::Ipv4Mask::IsEqual(ns3::Ipv4Mask other) const [member function] + cls.add_method('IsEqual', 'bool', [param('ns3::Ipv4Mask', 'other')], is_const=True) + ## ipv4-address.h: bool ns3::Ipv4Mask::IsMatch(ns3::Ipv4Address a, ns3::Ipv4Address b) const [member function] + cls.add_method('IsMatch', 'bool', [param('ns3::Ipv4Address', 'a'), param('ns3::Ipv4Address', 'b')], is_const=True) + ## ipv4-address.h: void ns3::Ipv4Mask::Print(std::ostream & os) const [member function] + cls.add_method('Print', 'void', [param('std::ostream&', 'os')], is_const=True) + ## ipv4-address.h: void ns3::Ipv4Mask::Set(uint32_t mask) [member function] + cls.add_method('Set', 'void', [param('uint32_t', 'mask')]) + cls.add_output_stream_operator() + return + +def register_Ns3Ipv4AddressValue_methods(root_module, cls): + ## ipv4-address.h: ns3::Ipv4AddressValue::Ipv4AddressValue() [constructor] + cls.add_constructor([], visibility='public') + ## ipv4-address.h: ns3::Ipv4AddressValue::Ipv4AddressValue(ns3::Ipv4Address const & value) [constructor] + cls.add_constructor([param('ns3::Ipv4Address&', 'value', is_const=True)], visibility='public') + ## ipv4-address.h: void ns3::Ipv4AddressValue::Set(ns3::Ipv4Address const & value) [member function] + cls.add_method('Set', 'void', [param('ns3::Ipv4Address&', 'value', is_const=True)]) + ## ipv4-address.h: ns3::Ipv4Address ns3::Ipv4AddressValue::Get() const [member function] + cls.add_method('Get', 'ns3::Ipv4Address', [], is_const=True) + ## ipv4-address.h: ns3::Ptr ns3::Ipv4AddressValue::Copy() const [member function] + cls.add_method('Copy', 'ns3::Ptr< ns3::AttributeValue >', [], is_const=True, is_virtual=True) + ## ipv4-address.h: std::string ns3::Ipv4AddressValue::SerializeToString(ns3::Ptr checker) const [member function] + cls.add_method('SerializeToString', 'std::string', [param('ns3::Ptr< ns3::AttributeChecker const >', 'checker')], is_const=True, is_virtual=True) + ## ipv4-address.h: bool ns3::Ipv4AddressValue::DeserializeFromString(std::string value, ns3::Ptr checker) [member function] + cls.add_method('DeserializeFromString', 'bool', [param('std::string', 'value'), param('ns3::Ptr< ns3::AttributeChecker const >', 'checker')], is_virtual=True) + return + +def register_Ns3Ipv4RoutingProtocol_methods(root_module, cls): + ## ipv4.h: ns3::Ipv4RoutingProtocol::IF_INDEX_ANY [variable] + cls.add_static_attribute('IF_INDEX_ANY', retval('uint32_t', is_const=True), is_const=True) + ## ipv4.h: bool ns3::Ipv4RoutingProtocol::RequestRoute(uint32_t ifIndex, ns3::Ipv4Header const & ipHeader, ns3::Ptr packet, ns3::Callback,const ns3::Ipv4Header&,ns3::empty,ns3::empty> routeReply) [member function] + cls.add_method('RequestRoute', 'bool', [param('uint32_t', 'ifIndex'), param('ns3::Ipv4Header&', 'ipHeader', is_const=True), param('ns3::Ptr< ns3::Packet >', 'packet'), param('ns3::Callback< void, bool, const ns3::Ipv4Route&, ns3::Ptr< ns3::Packet >, const ns3::Ipv4Header&, ns3::empty, ns3::empty >', 'routeReply')], is_pure_virtual=True, is_virtual=True) + ## ipv4.h: bool ns3::Ipv4RoutingProtocol::RequestIfIndex(ns3::Ipv4Address destination, uint32_t & ifIndex) [member function] + cls.add_method('RequestIfIndex', 'bool', [param('ns3::Ipv4Address', 'destination'), param('uint32_t&', 'ifIndex')], is_pure_virtual=True, is_virtual=True) + cls.add_constructor([]) + return + +def register_Ns3Mac48AddressValue_methods(root_module, cls): + ## mac48-address.h: ns3::Mac48AddressValue::Mac48AddressValue() [constructor] + cls.add_constructor([], visibility='public') + ## mac48-address.h: ns3::Mac48AddressValue::Mac48AddressValue(ns3::Mac48Address const & value) [constructor] + cls.add_constructor([param('ns3::Mac48Address&', 'value', is_const=True)], visibility='public') + ## mac48-address.h: void ns3::Mac48AddressValue::Set(ns3::Mac48Address const & value) [member function] + cls.add_method('Set', 'void', [param('ns3::Mac48Address&', 'value', is_const=True)]) + ## mac48-address.h: ns3::Mac48Address ns3::Mac48AddressValue::Get() const [member function] + cls.add_method('Get', 'ns3::Mac48Address', [], is_const=True) + ## mac48-address.h: ns3::Ptr ns3::Mac48AddressValue::Copy() const [member function] + cls.add_method('Copy', 'ns3::Ptr< ns3::AttributeValue >', [], is_const=True, is_virtual=True) + ## mac48-address.h: std::string ns3::Mac48AddressValue::SerializeToString(ns3::Ptr checker) const [member function] + cls.add_method('SerializeToString', 'std::string', [param('ns3::Ptr< ns3::AttributeChecker const >', 'checker')], is_const=True, is_virtual=True) + ## mac48-address.h: bool ns3::Mac48AddressValue::DeserializeFromString(std::string value, ns3::Ptr checker) [member function] + cls.add_method('DeserializeFromString', 'bool', [param('std::string', 'value'), param('ns3::Ptr< ns3::AttributeChecker const >', 'checker')], is_virtual=True) + return + +def register_Ns3Ipv4MaskValue_methods(root_module, cls): + ## ipv4-address.h: ns3::Ipv4MaskValue::Ipv4MaskValue() [constructor] + cls.add_constructor([], visibility='public') + ## ipv4-address.h: ns3::Ipv4MaskValue::Ipv4MaskValue(ns3::Ipv4Mask const & value) [constructor] + cls.add_constructor([param('ns3::Ipv4Mask&', 'value', is_const=True)], visibility='public') + ## ipv4-address.h: void ns3::Ipv4MaskValue::Set(ns3::Ipv4Mask const & value) [member function] + cls.add_method('Set', 'void', [param('ns3::Ipv4Mask&', 'value', is_const=True)]) + ## ipv4-address.h: ns3::Ipv4Mask ns3::Ipv4MaskValue::Get() const [member function] + cls.add_method('Get', 'ns3::Ipv4Mask', [], is_const=True) + ## ipv4-address.h: ns3::Ptr ns3::Ipv4MaskValue::Copy() const [member function] + cls.add_method('Copy', 'ns3::Ptr< ns3::AttributeValue >', [], is_const=True, is_virtual=True) + ## ipv4-address.h: std::string ns3::Ipv4MaskValue::SerializeToString(ns3::Ptr checker) const [member function] + cls.add_method('SerializeToString', 'std::string', [param('ns3::Ptr< ns3::AttributeChecker const >', 'checker')], is_const=True, is_virtual=True) + ## ipv4-address.h: bool ns3::Ipv4MaskValue::DeserializeFromString(std::string value, ns3::Ptr checker) [member function] + cls.add_method('DeserializeFromString', 'bool', [param('std::string', 'value'), param('ns3::Ptr< ns3::AttributeChecker const >', 'checker')], is_virtual=True) + return + +def register_Ns3SocketAddressTag_methods(root_module, cls): + ## socket.h: ns3::SocketAddressTag::SocketAddressTag() [constructor] + cls.add_constructor([], visibility='public') + ## socket.h: void ns3::SocketAddressTag::SetAddress(ns3::Address addr) [member function] + cls.add_method('SetAddress', 'void', [param('ns3::Address', 'addr')]) + ## socket.h: ns3::Address ns3::SocketAddressTag::GetAddress() const [member function] + cls.add_method('GetAddress', 'ns3::Address', [], is_const=True) + ## socket.h: static ns3::TypeId ns3::SocketAddressTag::GetTypeId() [member function] + cls.add_method('GetTypeId', 'ns3::TypeId', [], is_static=True) + ## socket.h: ns3::TypeId ns3::SocketAddressTag::GetInstanceTypeId() const [member function] + cls.add_method('GetInstanceTypeId', 'ns3::TypeId', [], is_const=True, is_virtual=True) + ## socket.h: uint32_t ns3::SocketAddressTag::GetSerializedSize() const [member function] + cls.add_method('GetSerializedSize', 'uint32_t', [], is_const=True, is_virtual=True) + ## socket.h: void ns3::SocketAddressTag::Serialize(ns3::TagBuffer i) const [member function] + cls.add_method('Serialize', 'void', [param('ns3::TagBuffer', 'i')], is_const=True, is_virtual=True) + ## socket.h: void ns3::SocketAddressTag::Deserialize(ns3::TagBuffer i) [member function] + cls.add_method('Deserialize', 'void', [param('ns3::TagBuffer', 'i')], is_virtual=True) + ## socket.h: void ns3::SocketAddressTag::Print(std::ostream & os) const [member function] + cls.add_method('Print', 'void', [param('std::ostream&', 'os')], is_const=True, is_virtual=True) + return + +def register_Ns3InetSocketAddress_methods(root_module, cls): + ## inet-socket-address.h: ns3::InetSocketAddress::InetSocketAddress(ns3::Ipv4Address ipv4, uint16_t port) [constructor] + cls.add_constructor([param('ns3::Ipv4Address', 'ipv4'), param('uint16_t', 'port')], visibility='public') + ## inet-socket-address.h: ns3::InetSocketAddress::InetSocketAddress(ns3::Ipv4Address ipv4) [constructor] + cls.add_constructor([param('ns3::Ipv4Address', 'ipv4')], visibility='public') + ## inet-socket-address.h: ns3::InetSocketAddress::InetSocketAddress(uint16_t port) [constructor] + cls.add_constructor([param('uint16_t', 'port')], visibility='public') + ## inet-socket-address.h: ns3::InetSocketAddress::InetSocketAddress(char const * ipv4, uint16_t port) [constructor] + cls.add_constructor([param('char *', 'ipv4', transfer_ownership=False, is_const=True), param('uint16_t', 'port')], visibility='public') + ## inet-socket-address.h: ns3::InetSocketAddress::InetSocketAddress(char const * ipv4) [constructor] + cls.add_constructor([param('char *', 'ipv4', transfer_ownership=False, is_const=True)], visibility='public') + ## inet-socket-address.h: uint16_t ns3::InetSocketAddress::GetPort() const [member function] + cls.add_method('GetPort', 'uint16_t', [], is_const=True) + ## inet-socket-address.h: ns3::Ipv4Address ns3::InetSocketAddress::GetIpv4() const [member function] + cls.add_method('GetIpv4', 'ns3::Ipv4Address', [], is_const=True) + ## inet-socket-address.h: void ns3::InetSocketAddress::SetPort(uint16_t port) [member function] + cls.add_method('SetPort', 'void', [param('uint16_t', 'port')]) + ## inet-socket-address.h: void ns3::InetSocketAddress::SetIpv4(ns3::Ipv4Address address) [member function] + cls.add_method('SetIpv4', 'void', [param('ns3::Ipv4Address', 'address')]) + ## inet-socket-address.h: static bool ns3::InetSocketAddress::IsMatchingType(ns3::Address const & address) [member function] + cls.add_method('IsMatchingType', 'bool', [param('ns3::Address&', 'address', is_const=True)], is_static=True) + ## inet-socket-address.h: static ns3::InetSocketAddress ns3::InetSocketAddress::ConvertFrom(ns3::Address const & address) [member function] + cls.add_method('ConvertFrom', 'ns3::InetSocketAddress', [param('ns3::Address&', 'address', is_const=True)], is_static=True) + return + +def register_Ns3Ipv4Address_methods(root_module, cls): + ## ipv4-address.h: ns3::Ipv4Address::Ipv4Address(ns3::Ipv4Address const & arg0) [copy constructor] + cls.add_constructor([param('ns3::Ipv4Address&', 'arg0', is_const=True)], visibility='public') + ## ipv4-address.h: ns3::Ipv4Address::Ipv4Address() [constructor] + cls.add_constructor([], visibility='public') + ## ipv4-address.h: ns3::Ipv4Address::Ipv4Address(uint32_t address) [constructor] + cls.add_constructor([param('uint32_t', 'address')], visibility='public') + ## ipv4-address.h: ns3::Ipv4Address::Ipv4Address(char const * address) [constructor] + cls.add_constructor([param('char *', 'address', transfer_ownership=False, is_const=True)], visibility='public') + ## ipv4-address.h: ns3::Ipv4Address ns3::Ipv4Address::CombineMask(ns3::Ipv4Mask const & mask) const [member function] + cls.add_method('CombineMask', 'ns3::Ipv4Address', [param('ns3::Ipv4Mask&', 'mask', is_const=True)], is_const=True) + ## ipv4-address.h: static ns3::Ipv4Address ns3::Ipv4Address::ConvertFrom(ns3::Address const & address) [member function] + cls.add_method('ConvertFrom', 'ns3::Ipv4Address', [param('ns3::Address&', 'address', is_const=True)], is_static=True) + ## ipv4-address.h: static ns3::Ipv4Address ns3::Ipv4Address::Deserialize(uint8_t const * buf) [member function] + cls.add_method('Deserialize', 'ns3::Ipv4Address', [param('uint8_t *', 'buf', transfer_ownership=False, is_const=True)], is_static=True) + ## ipv4-address.h: uint32_t ns3::Ipv4Address::Get() const [member function] + cls.add_method('Get', 'uint32_t', [], is_const=True) + ## ipv4-address.h: static ns3::Ipv4Address ns3::Ipv4Address::GetAny() [member function] + cls.add_method('GetAny', 'ns3::Ipv4Address', [], is_static=True) + ## ipv4-address.h: static ns3::Ipv4Address ns3::Ipv4Address::GetBroadcast() [member function] + cls.add_method('GetBroadcast', 'ns3::Ipv4Address', [], is_static=True) + ## ipv4-address.h: static ns3::Ipv4Address ns3::Ipv4Address::GetLoopback() [member function] + cls.add_method('GetLoopback', 'ns3::Ipv4Address', [], is_static=True) + ## ipv4-address.h: ns3::Ipv4Address ns3::Ipv4Address::GetSubnetDirectedBroadcast(ns3::Ipv4Mask const & mask) const [member function] + cls.add_method('GetSubnetDirectedBroadcast', 'ns3::Ipv4Address', [param('ns3::Ipv4Mask&', 'mask', is_const=True)], is_const=True) + ## ipv4-address.h: static ns3::Ipv4Address ns3::Ipv4Address::GetZero() [member function] + cls.add_method('GetZero', 'ns3::Ipv4Address', [], is_static=True) + ## ipv4-address.h: bool ns3::Ipv4Address::IsBroadcast() const [member function] + cls.add_method('IsBroadcast', 'bool', [], is_const=True) + ## ipv4-address.h: bool ns3::Ipv4Address::IsEqual(ns3::Ipv4Address const & other) const [member function] + cls.add_method('IsEqual', 'bool', [param('ns3::Ipv4Address&', 'other', is_const=True)], is_const=True) + ## ipv4-address.h: static bool ns3::Ipv4Address::IsMatchingType(ns3::Address const & address) [member function] + cls.add_method('IsMatchingType', 'bool', [param('ns3::Address&', 'address', is_const=True)], is_static=True) + ## ipv4-address.h: bool ns3::Ipv4Address::IsMulticast() const [member function] + cls.add_method('IsMulticast', 'bool', [], is_const=True) + ## ipv4-address.h: bool ns3::Ipv4Address::IsSubnetDirectedBroadcast(ns3::Ipv4Mask const & mask) const [member function] + cls.add_method('IsSubnetDirectedBroadcast', 'bool', [param('ns3::Ipv4Mask&', 'mask', is_const=True)], is_const=True) + ## ipv4-address.h: void ns3::Ipv4Address::Print(std::ostream & os) const [member function] + cls.add_method('Print', 'void', [param('std::ostream&', 'os')], is_const=True) + ## ipv4-address.h: void ns3::Ipv4Address::Serialize(uint8_t * buf) const [member function] + cls.add_method('Serialize', 'void', [param('uint8_t *', 'buf')], is_const=True) + ## ipv4-address.h: void ns3::Ipv4Address::Set(uint32_t address) [member function] + cls.add_method('Set', 'void', [param('uint32_t', 'address')]) + ## ipv4-address.h: void ns3::Ipv4Address::Set(char const * address) [member function] + cls.add_method('Set', 'void', [param('char *', 'address', transfer_ownership=False, is_const=True)]) + cls.add_output_stream_operator() + return + +def register_Ns3Application_methods(root_module, cls): + ## application.h: static ns3::TypeId ns3::Application::GetTypeId() [member function] + cls.add_method('GetTypeId', 'ns3::TypeId', [], is_static=True) + ## application.h: ns3::Application::Application() [constructor] + cls.add_constructor([], visibility='public') + ## application.h: void ns3::Application::Start(ns3::Time const & startTime) [member function] + cls.add_method('Start', 'void', [param('ns3::Time&', 'startTime', is_const=True)]) + ## application.h: void ns3::Application::Start(ns3::RandomVariable const & startVariable) [member function] + cls.add_method('Start', 'void', [param('ns3::RandomVariable&', 'startVariable', is_const=True)]) + ## application.h: void ns3::Application::Stop(ns3::Time const & stopTime) [member function] + cls.add_method('Stop', 'void', [param('ns3::Time&', 'stopTime', is_const=True)]) + ## application.h: void ns3::Application::Stop(ns3::RandomVariable const & stopVariable) [member function] + cls.add_method('Stop', 'void', [param('ns3::RandomVariable&', 'stopVariable', is_const=True)]) + ## application.h: ns3::Ptr ns3::Application::GetNode() const [member function] + cls.add_method('GetNode', 'ns3::Ptr< ns3::Node >', [], is_const=True) + ## application.h: void ns3::Application::SetNode(ns3::Ptr node) [member function] + cls.add_method('SetNode', 'void', [param('ns3::Ptr< ns3::Node >', 'node')]) + ## application.h: void ns3::Application::DoDispose() [member function] + cls.add_method('DoDispose', 'void', [], visibility='protected', is_virtual=True) + ## application.h: void ns3::Application::StartApplication() [member function] + cls.add_method('StartApplication', 'void', [], visibility='private', is_virtual=True) + ## application.h: void ns3::Application::StopApplication() [member function] + cls.add_method('StopApplication', 'void', [], visibility='private', is_virtual=True) + return + +def register_Ns3Queue_methods(root_module, cls): + ## queue.h: static ns3::TypeId ns3::Queue::GetTypeId() [member function] + cls.add_method('GetTypeId', 'ns3::TypeId', [], is_static=True) + ## queue.h: ns3::Queue::Queue() [constructor] + cls.add_constructor([], visibility='public') + ## queue.h: bool ns3::Queue::IsEmpty() const [member function] + cls.add_method('IsEmpty', 'bool', [], is_const=True) + ## queue.h: bool ns3::Queue::Enqueue(ns3::Ptr p) [member function] + cls.add_method('Enqueue', 'bool', [param('ns3::Ptr< ns3::Packet >', 'p')]) + ## queue.h: ns3::Ptr ns3::Queue::Dequeue() [member function] + cls.add_method('Dequeue', 'ns3::Ptr< ns3::Packet >', []) + ## queue.h: ns3::Ptr ns3::Queue::Peek() const [member function] + cls.add_method('Peek', 'ns3::Ptr< ns3::Packet >', [], is_const=True) + ## queue.h: void ns3::Queue::DequeueAll() [member function] + cls.add_method('DequeueAll', 'void', []) + ## queue.h: uint32_t ns3::Queue::GetNPackets() const [member function] + cls.add_method('GetNPackets', 'uint32_t', [], is_const=True) + ## queue.h: uint32_t ns3::Queue::GetNBytes() const [member function] + cls.add_method('GetNBytes', 'uint32_t', [], is_const=True) + ## queue.h: uint32_t ns3::Queue::GetTotalReceivedBytes() const [member function] + cls.add_method('GetTotalReceivedBytes', 'uint32_t', [], is_const=True) + ## queue.h: uint32_t ns3::Queue::GetTotalReceivedPackets() const [member function] + cls.add_method('GetTotalReceivedPackets', 'uint32_t', [], is_const=True) + ## queue.h: uint32_t ns3::Queue::GetTotalDroppedBytes() const [member function] + cls.add_method('GetTotalDroppedBytes', 'uint32_t', [], is_const=True) + ## queue.h: uint32_t ns3::Queue::GetTotalDroppedPackets() const [member function] + cls.add_method('GetTotalDroppedPackets', 'uint32_t', [], is_const=True) + ## queue.h: void ns3::Queue::ResetStatistics() [member function] + cls.add_method('ResetStatistics', 'void', []) + ## queue.h: void ns3::Queue::Drop(ns3::Ptr packet) [member function] + cls.add_method('Drop', 'void', [param('ns3::Ptr< ns3::Packet >', 'packet')], visibility='protected') + ## queue.h: bool ns3::Queue::DoEnqueue(ns3::Ptr p) [member function] + cls.add_method('DoEnqueue', 'bool', [param('ns3::Ptr< ns3::Packet >', 'p')], is_pure_virtual=True, visibility='private', is_virtual=True) + ## queue.h: ns3::Ptr ns3::Queue::DoDequeue() [member function] + cls.add_method('DoDequeue', 'ns3::Ptr< ns3::Packet >', [], is_pure_virtual=True, visibility='private', is_virtual=True) + ## queue.h: ns3::Ptr ns3::Queue::DoPeek() const [member function] + cls.add_method('DoPeek', 'ns3::Ptr< ns3::Packet >', [], is_pure_virtual=True, is_const=True, visibility='private', is_virtual=True) + return + +def register_Ns3Socket_methods(root_module, cls): + ## socket.h: ns3::Socket::Socket() [constructor] + cls.add_constructor([], visibility='public') + ## socket.h: static ns3::Ptr ns3::Socket::CreateSocket(ns3::Ptr node, ns3::TypeId tid) [member function] + cls.add_method('CreateSocket', 'ns3::Ptr< ns3::Socket >', [param('ns3::Ptr< ns3::Node >', 'node'), param('ns3::TypeId', 'tid')], is_static=True) + ## socket.h: ns3::Socket::SocketErrno ns3::Socket::GetErrno() const [member function] + cls.add_method('GetErrno', 'ns3::Socket::SocketErrno', [], is_pure_virtual=True, is_const=True, is_virtual=True) + ## socket.h: ns3::Ptr ns3::Socket::GetNode() const [member function] + cls.add_method('GetNode', 'ns3::Ptr< ns3::Node >', [], is_pure_virtual=True, is_const=True, is_virtual=True) + ## socket.h: void ns3::Socket::SetConnectCallback(ns3::Callback, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty> connectionSucceeded, ns3::Callback, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty> connectionFailed) [member function] + cls.add_method('SetConnectCallback', 'void', [param('ns3::Callback< void, ns3::Ptr< ns3::Socket >, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty >', 'connectionSucceeded'), param('ns3::Callback< void, ns3::Ptr< ns3::Socket >, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty >', 'connectionFailed')]) + ## socket.h: void ns3::Socket::SetAcceptCallback(ns3::Callback, ns3::Address const&, ns3::empty, ns3::empty, ns3::empty, ns3::empty> connectionRequest, ns3::Callback, ns3::Address const&, ns3::empty, ns3::empty, ns3::empty, ns3::empty> newConnectionCreated) [member function] + cls.add_method('SetAcceptCallback', 'void', [param('ns3::Callback< bool, ns3::Ptr< ns3::Socket >, ns3::Address const&, ns3::empty, ns3::empty, ns3::empty, ns3::empty >', 'connectionRequest'), param('ns3::Callback< void, ns3::Ptr< ns3::Socket >, ns3::Address const&, ns3::empty, ns3::empty, ns3::empty, ns3::empty >', 'newConnectionCreated')]) + ## socket.h: bool ns3::Socket::SetDataSentCallback(ns3::Callback, unsigned int, ns3::empty, ns3::empty, ns3::empty, ns3::empty> dataSent) [member function] + cls.add_method('SetDataSentCallback', 'bool', [param('ns3::Callback< void, ns3::Ptr< ns3::Socket >, unsigned int, ns3::empty, ns3::empty, ns3::empty, ns3::empty >', 'dataSent')], is_virtual=True) + ## socket.h: void ns3::Socket::SetSendCallback(ns3::Callback, unsigned int, ns3::empty, ns3::empty, ns3::empty, ns3::empty> sendCb) [member function] + cls.add_method('SetSendCallback', 'void', [param('ns3::Callback< void, ns3::Ptr< ns3::Socket >, unsigned int, ns3::empty, ns3::empty, ns3::empty, ns3::empty >', 'sendCb')]) + ## socket.h: void ns3::Socket::SetRecvCallback(ns3::Callback, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty> arg0) [member function] + cls.add_method('SetRecvCallback', 'void', [param('ns3::Callback< void, ns3::Ptr< ns3::Socket >, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty >', 'arg0')]) + ## socket.h: int ns3::Socket::Bind(ns3::Address const & address) [member function] + cls.add_method('Bind', 'int', [param('ns3::Address&', 'address', is_const=True)], is_pure_virtual=True, is_virtual=True) + ## socket.h: int ns3::Socket::Bind() [member function] + cls.add_method('Bind', 'int', [], is_pure_virtual=True, is_virtual=True) + ## socket.h: int ns3::Socket::Close() [member function] + cls.add_method('Close', 'int', [], is_pure_virtual=True, is_virtual=True) + ## socket.h: int ns3::Socket::ShutdownSend() [member function] + cls.add_method('ShutdownSend', 'int', [], is_pure_virtual=True, is_virtual=True) + ## socket.h: int ns3::Socket::ShutdownRecv() [member function] + cls.add_method('ShutdownRecv', 'int', [], is_pure_virtual=True, is_virtual=True) + ## socket.h: int ns3::Socket::Connect(ns3::Address const & address) [member function] + cls.add_method('Connect', 'int', [param('ns3::Address&', 'address', is_const=True)], is_pure_virtual=True, is_virtual=True) + ## socket.h: int ns3::Socket::Listen(uint32_t queueLimit) [member function] + cls.add_method('Listen', 'int', [param('uint32_t', 'queueLimit')], is_pure_virtual=True, is_virtual=True) + ## socket.h: uint32_t ns3::Socket::GetTxAvailable() const [member function] + cls.add_method('GetTxAvailable', 'uint32_t', [], is_pure_virtual=True, is_const=True, is_virtual=True) + ## socket.h: int ns3::Socket::Send(ns3::Ptr p, uint32_t flags) [member function] + cls.add_method('Send', 'int', [param('ns3::Ptr< ns3::Packet >', 'p'), param('uint32_t', 'flags')], is_pure_virtual=True, is_virtual=True) + ## socket.h: int ns3::Socket::SendTo(ns3::Ptr p, uint32_t flags, ns3::Address const & toAddress) [member function] + cls.add_method('SendTo', 'int', [param('ns3::Ptr< ns3::Packet >', 'p'), param('uint32_t', 'flags'), param('ns3::Address&', 'toAddress', is_const=True)], is_pure_virtual=True, is_virtual=True) + ## socket.h: uint32_t ns3::Socket::GetRxAvailable() const [member function] + cls.add_method('GetRxAvailable', 'uint32_t', [], is_pure_virtual=True, is_const=True, is_virtual=True) + ## socket.h: ns3::Ptr ns3::Socket::Recv(uint32_t maxSize, uint32_t flags) [member function] + cls.add_method('Recv', 'ns3::Ptr< ns3::Packet >', [param('uint32_t', 'maxSize'), param('uint32_t', 'flags')], is_pure_virtual=True, is_virtual=True) + ## socket.h: ns3::Ptr ns3::Socket::RecvFrom(uint32_t maxSize, uint32_t flags, ns3::Address & fromAddress) [member function] + cls.add_method('RecvFrom', 'ns3::Ptr< ns3::Packet >', [param('uint32_t', 'maxSize'), param('uint32_t', 'flags'), param('ns3::Address&', 'fromAddress')], is_pure_virtual=True, is_virtual=True) + ## socket.h: int ns3::Socket::Send(ns3::Ptr p) [member function] + cls.add_method('Send', 'int', [param('ns3::Ptr< ns3::Packet >', 'p')]) + ## socket.h: int ns3::Socket::Send(uint8_t const * buf, uint32_t size, uint32_t flags) [member function] + cls.add_method('Send', 'int', [param('uint8_t *', 'buf', transfer_ownership=False, is_const=True), param('uint32_t', 'size'), param('uint32_t', 'flags')]) + ## socket.h: int ns3::Socket::SendTo(uint8_t const * buf, uint32_t size, uint32_t flags, ns3::Address const & address) [member function] + cls.add_method('SendTo', 'int', [param('uint8_t *', 'buf', transfer_ownership=False, is_const=True), param('uint32_t', 'size'), param('uint32_t', 'flags'), param('ns3::Address&', 'address', is_const=True)]) + ## socket.h: ns3::Ptr ns3::Socket::Recv() [member function] + cls.add_method('Recv', 'ns3::Ptr< ns3::Packet >', []) + ## socket.h: int ns3::Socket::Recv(uint8_t * buf, uint32_t size, uint32_t flags) [member function] + cls.add_method('Recv', 'int', [param('uint8_t *', 'buf'), param('uint32_t', 'size'), param('uint32_t', 'flags')]) + ## socket.h: ns3::Ptr ns3::Socket::RecvFrom(ns3::Address & fromAddress) [member function] + cls.add_method('RecvFrom', 'ns3::Ptr< ns3::Packet >', [param('ns3::Address&', 'fromAddress')]) + ## socket.h: int ns3::Socket::RecvFrom(uint8_t * buf, uint32_t size, uint32_t flags, ns3::Address & fromAddress) [member function] + cls.add_method('RecvFrom', 'int', [param('uint8_t *', 'buf'), param('uint32_t', 'size'), param('uint32_t', 'flags'), param('ns3::Address&', 'fromAddress')]) + ## socket.h: void ns3::Socket::NotifyConnectionSucceeded() [member function] + cls.add_method('NotifyConnectionSucceeded', 'void', [], visibility='protected') + ## socket.h: void ns3::Socket::NotifyConnectionFailed() [member function] + cls.add_method('NotifyConnectionFailed', 'void', [], visibility='protected') + ## socket.h: bool ns3::Socket::NotifyConnectionRequest(ns3::Address const & from) [member function] + cls.add_method('NotifyConnectionRequest', 'bool', [param('ns3::Address&', 'from', is_const=True)], visibility='protected') + ## socket.h: void ns3::Socket::NotifyNewConnectionCreated(ns3::Ptr socket, ns3::Address const & from) [member function] + cls.add_method('NotifyNewConnectionCreated', 'void', [param('ns3::Ptr< ns3::Socket >', 'socket'), param('ns3::Address&', 'from', is_const=True)], visibility='protected') + ## socket.h: void ns3::Socket::NotifyDataSent(uint32_t size) [member function] + cls.add_method('NotifyDataSent', 'void', [param('uint32_t', 'size')], visibility='protected') + ## socket.h: void ns3::Socket::NotifySend(uint32_t spaceAvailable) [member function] + cls.add_method('NotifySend', 'void', [param('uint32_t', 'spaceAvailable')], visibility='protected') + ## socket.h: void ns3::Socket::NotifyDataRecv() [member function] + cls.add_method('NotifyDataRecv', 'void', [], visibility='protected') + return + +def register_Ns3Ipv4Header_methods(root_module, cls): + ## ipv4-header.h: ns3::Ipv4Header::Ipv4Header() [constructor] + cls.add_constructor([], visibility='public') + ## ipv4-header.h: void ns3::Ipv4Header::EnableChecksum() [member function] + cls.add_method('EnableChecksum', 'void', []) + ## ipv4-header.h: void ns3::Ipv4Header::SetPayloadSize(uint16_t size) [member function] + cls.add_method('SetPayloadSize', 'void', [param('uint16_t', 'size')]) + ## ipv4-header.h: void ns3::Ipv4Header::SetIdentification(uint16_t identification) [member function] + cls.add_method('SetIdentification', 'void', [param('uint16_t', 'identification')]) + ## ipv4-header.h: void ns3::Ipv4Header::SetTos(uint8_t tos) [member function] + cls.add_method('SetTos', 'void', [param('uint8_t', 'tos')]) + ## ipv4-header.h: void ns3::Ipv4Header::SetMoreFragments() [member function] + cls.add_method('SetMoreFragments', 'void', []) + ## ipv4-header.h: void ns3::Ipv4Header::SetLastFragment() [member function] + cls.add_method('SetLastFragment', 'void', []) + ## ipv4-header.h: void ns3::Ipv4Header::SetDontFragment() [member function] + cls.add_method('SetDontFragment', 'void', []) + ## ipv4-header.h: void ns3::Ipv4Header::SetMayFragment() [member function] + cls.add_method('SetMayFragment', 'void', []) + ## ipv4-header.h: void ns3::Ipv4Header::SetFragmentOffset(uint16_t offset) [member function] + cls.add_method('SetFragmentOffset', 'void', [param('uint16_t', 'offset')]) + ## ipv4-header.h: void ns3::Ipv4Header::SetTtl(uint8_t ttl) [member function] + cls.add_method('SetTtl', 'void', [param('uint8_t', 'ttl')]) + ## ipv4-header.h: void ns3::Ipv4Header::SetProtocol(uint8_t num) [member function] + cls.add_method('SetProtocol', 'void', [param('uint8_t', 'num')]) + ## ipv4-header.h: void ns3::Ipv4Header::SetSource(ns3::Ipv4Address source) [member function] + cls.add_method('SetSource', 'void', [param('ns3::Ipv4Address', 'source')]) + ## ipv4-header.h: void ns3::Ipv4Header::SetDestination(ns3::Ipv4Address destination) [member function] + cls.add_method('SetDestination', 'void', [param('ns3::Ipv4Address', 'destination')]) + ## ipv4-header.h: uint16_t ns3::Ipv4Header::GetPayloadSize() const [member function] + cls.add_method('GetPayloadSize', 'uint16_t', [], is_const=True) + ## ipv4-header.h: uint16_t ns3::Ipv4Header::GetIdentification() const [member function] + cls.add_method('GetIdentification', 'uint16_t', [], is_const=True) + ## ipv4-header.h: uint8_t ns3::Ipv4Header::GetTos() const [member function] + cls.add_method('GetTos', 'uint8_t', [], is_const=True) + ## ipv4-header.h: bool ns3::Ipv4Header::IsLastFragment() const [member function] + cls.add_method('IsLastFragment', 'bool', [], is_const=True) + ## ipv4-header.h: bool ns3::Ipv4Header::IsDontFragment() const [member function] + cls.add_method('IsDontFragment', 'bool', [], is_const=True) + ## ipv4-header.h: uint16_t ns3::Ipv4Header::GetFragmentOffset() const [member function] + cls.add_method('GetFragmentOffset', 'uint16_t', [], is_const=True) + ## ipv4-header.h: uint8_t ns3::Ipv4Header::GetTtl() const [member function] + cls.add_method('GetTtl', 'uint8_t', [], is_const=True) + ## ipv4-header.h: uint8_t ns3::Ipv4Header::GetProtocol() const [member function] + cls.add_method('GetProtocol', 'uint8_t', [], is_const=True) + ## ipv4-header.h: ns3::Ipv4Address ns3::Ipv4Header::GetSource() const [member function] + cls.add_method('GetSource', 'ns3::Ipv4Address', [], is_const=True) + ## ipv4-header.h: ns3::Ipv4Address ns3::Ipv4Header::GetDestination() const [member function] + cls.add_method('GetDestination', 'ns3::Ipv4Address', [], is_const=True) + ## ipv4-header.h: bool ns3::Ipv4Header::IsChecksumOk() const [member function] + cls.add_method('IsChecksumOk', 'bool', [], is_const=True) + ## ipv4-header.h: static ns3::TypeId ns3::Ipv4Header::GetTypeId() [member function] + cls.add_method('GetTypeId', 'ns3::TypeId', [], is_static=True) + ## ipv4-header.h: ns3::TypeId ns3::Ipv4Header::GetInstanceTypeId() const [member function] + cls.add_method('GetInstanceTypeId', 'ns3::TypeId', [], is_const=True, is_virtual=True) + ## ipv4-header.h: void ns3::Ipv4Header::Print(std::ostream & os) const [member function] + cls.add_method('Print', 'void', [param('std::ostream&', 'os')], is_const=True, is_virtual=True) + ## ipv4-header.h: uint32_t ns3::Ipv4Header::GetSerializedSize() const [member function] + cls.add_method('GetSerializedSize', 'uint32_t', [], is_const=True, is_virtual=True) + ## ipv4-header.h: void ns3::Ipv4Header::Serialize(ns3::Buffer::Iterator start) const [member function] + cls.add_method('Serialize', 'void', [param('ns3::Buffer::Iterator', 'start')], is_const=True, is_virtual=True) + ## ipv4-header.h: uint32_t ns3::Ipv4Header::Deserialize(ns3::Buffer::Iterator start) [member function] + cls.add_method('Deserialize', 'uint32_t', [param('ns3::Buffer::Iterator', 'start')], is_virtual=True) + return + +def register_Ns3UdpSocket_methods(root_module, cls): + ## udp-socket.h: static ns3::TypeId ns3::UdpSocket::GetTypeId() [member function] + cls.add_method('GetTypeId', 'ns3::TypeId', [], is_static=True) + ## udp-socket.h: ns3::UdpSocket::UdpSocket() [constructor] + cls.add_constructor([], visibility='public') + ## udp-socket.h: ns3::Socket::SocketErrno ns3::UdpSocket::GetErrno() const [member function] + cls.add_method('GetErrno', 'ns3::Socket::SocketErrno', [], is_pure_virtual=True, is_const=True, is_virtual=True) + ## udp-socket.h: ns3::Ptr ns3::UdpSocket::GetNode() const [member function] + cls.add_method('GetNode', 'ns3::Ptr< ns3::Node >', [], is_pure_virtual=True, is_const=True, is_virtual=True) + ## udp-socket.h: int ns3::UdpSocket::Bind() [member function] + cls.add_method('Bind', 'int', [], is_pure_virtual=True, is_virtual=True) + ## udp-socket.h: int ns3::UdpSocket::Close() [member function] + cls.add_method('Close', 'int', [], is_pure_virtual=True, is_virtual=True) + ## udp-socket.h: int ns3::UdpSocket::ShutdownSend() [member function] + cls.add_method('ShutdownSend', 'int', [], is_pure_virtual=True, is_virtual=True) + ## udp-socket.h: int ns3::UdpSocket::ShutdownRecv() [member function] + cls.add_method('ShutdownRecv', 'int', [], is_pure_virtual=True, is_virtual=True) + ## udp-socket.h: int ns3::UdpSocket::Connect(ns3::Address const & address) [member function] + cls.add_method('Connect', 'int', [param('ns3::Address&', 'address', is_const=True)], is_pure_virtual=True, is_virtual=True) + ## udp-socket.h: uint32_t ns3::UdpSocket::GetTxAvailable() const [member function] + cls.add_method('GetTxAvailable', 'uint32_t', [], is_pure_virtual=True, is_const=True, is_virtual=True) + ## udp-socket.h: int ns3::UdpSocket::Send(ns3::Ptr p, uint32_t flags) [member function] + cls.add_method('Send', 'int', [param('ns3::Ptr< ns3::Packet >', 'p'), param('uint32_t', 'flags')], is_pure_virtual=True, is_virtual=True) + ## udp-socket.h: int ns3::UdpSocket::SendTo(ns3::Ptr p, uint32_t flags, ns3::Address const & toAddress) [member function] + cls.add_method('SendTo', 'int', [param('ns3::Ptr< ns3::Packet >', 'p'), param('uint32_t', 'flags'), param('ns3::Address&', 'toAddress', is_const=True)], is_pure_virtual=True, is_virtual=True) + ## udp-socket.h: uint32_t ns3::UdpSocket::GetRxAvailable() const [member function] + cls.add_method('GetRxAvailable', 'uint32_t', [], is_pure_virtual=True, is_const=True, is_virtual=True) + ## udp-socket.h: ns3::Ptr ns3::UdpSocket::Recv(uint32_t maxSize, uint32_t flags) [member function] + cls.add_method('Recv', 'ns3::Ptr< ns3::Packet >', [param('uint32_t', 'maxSize'), param('uint32_t', 'flags')], is_pure_virtual=True, is_virtual=True) + ## udp-socket.h: ns3::Ptr ns3::UdpSocket::RecvFrom(uint32_t maxSize, uint32_t flags, ns3::Address & fromAddress) [member function] + cls.add_method('RecvFrom', 'ns3::Ptr< ns3::Packet >', [param('uint32_t', 'maxSize'), param('uint32_t', 'flags'), param('ns3::Address&', 'fromAddress')], is_pure_virtual=True, is_virtual=True) + ## udp-socket.h: void ns3::UdpSocket::SetRcvBufSize(uint32_t size) [member function] + cls.add_method('SetRcvBufSize', 'void', [param('uint32_t', 'size')], is_pure_virtual=True, visibility='private', is_virtual=True) + ## udp-socket.h: uint32_t ns3::UdpSocket::GetRcvBufSize() const [member function] + cls.add_method('GetRcvBufSize', 'uint32_t', [], is_pure_virtual=True, is_const=True, visibility='private', is_virtual=True) + ## udp-socket.h: void ns3::UdpSocket::SetIpTtl(uint32_t ipTtl) [member function] + cls.add_method('SetIpTtl', 'void', [param('uint32_t', 'ipTtl')], is_pure_virtual=True, visibility='private', is_virtual=True) + ## udp-socket.h: uint32_t ns3::UdpSocket::GetIpTtl() const [member function] + cls.add_method('GetIpTtl', 'uint32_t', [], is_pure_virtual=True, is_const=True, visibility='private', is_virtual=True) + ## udp-socket.h: void ns3::UdpSocket::SetIpMulticastTtl(uint32_t ipTtl) [member function] + cls.add_method('SetIpMulticastTtl', 'void', [param('uint32_t', 'ipTtl')], is_pure_virtual=True, visibility='private', is_virtual=True) + ## udp-socket.h: uint32_t ns3::UdpSocket::GetIpMulticastTtl() const [member function] + cls.add_method('GetIpMulticastTtl', 'uint32_t', [], is_pure_virtual=True, is_const=True, visibility='private', is_virtual=True) + return + +def register_Ns3NetDevice_methods(root_module, cls): + ## net-device.h: static ns3::TypeId ns3::NetDevice::GetTypeId() [member function] + cls.add_method('GetTypeId', 'ns3::TypeId', [], is_static=True) + ## net-device.h: void ns3::NetDevice::SetName(std::string const name) [member function] + cls.add_method('SetName', 'void', [param('std::string', 'name', is_const=True)], is_pure_virtual=True, is_virtual=True) + ## net-device.h: std::string ns3::NetDevice::GetName() const [member function] + cls.add_method('GetName', 'std::string', [], is_pure_virtual=True, is_const=True, is_virtual=True) + ## net-device.h: void ns3::NetDevice::SetIfIndex(uint32_t const index) [member function] + cls.add_method('SetIfIndex', 'void', [param('uint32_t', 'index', is_const=True)], is_pure_virtual=True, is_virtual=True) + ## net-device.h: uint32_t ns3::NetDevice::GetIfIndex() const [member function] + cls.add_method('GetIfIndex', 'uint32_t', [], is_pure_virtual=True, is_const=True, is_virtual=True) + ## net-device.h: ns3::Ptr ns3::NetDevice::GetChannel() const [member function] + cls.add_method('GetChannel', 'ns3::Ptr< ns3::Channel >', [], is_pure_virtual=True, is_const=True, is_virtual=True) + ## net-device.h: ns3::Address ns3::NetDevice::GetAddress() const [member function] + cls.add_method('GetAddress', 'ns3::Address', [], is_pure_virtual=True, is_const=True, is_virtual=True) + ## net-device.h: bool ns3::NetDevice::SetMtu(uint16_t const mtu) [member function] + cls.add_method('SetMtu', 'bool', [param('uint16_t', 'mtu', is_const=True)], is_pure_virtual=True, is_virtual=True) + ## net-device.h: uint16_t ns3::NetDevice::GetMtu() const [member function] + cls.add_method('GetMtu', 'uint16_t', [], is_pure_virtual=True, is_const=True, is_virtual=True) + ## net-device.h: bool ns3::NetDevice::IsLinkUp() const [member function] + cls.add_method('IsLinkUp', 'bool', [], is_pure_virtual=True, is_const=True, is_virtual=True) + ## net-device.h: void ns3::NetDevice::SetLinkChangeCallback(ns3::Callback callback) [member function] + cls.add_method('SetLinkChangeCallback', 'void', [param('ns3::Callback< void, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty >', 'callback')], is_pure_virtual=True, is_virtual=True) + ## net-device.h: bool ns3::NetDevice::IsBroadcast() const [member function] + cls.add_method('IsBroadcast', 'bool', [], is_pure_virtual=True, is_const=True, is_virtual=True) + ## net-device.h: ns3::Address ns3::NetDevice::GetBroadcast() const [member function] + cls.add_method('GetBroadcast', 'ns3::Address', [], is_pure_virtual=True, is_const=True, is_virtual=True) + ## net-device.h: bool ns3::NetDevice::IsMulticast() const [member function] + cls.add_method('IsMulticast', 'bool', [], is_pure_virtual=True, is_const=True, is_virtual=True) + ## net-device.h: ns3::Address ns3::NetDevice::GetMulticast() const [member function] + cls.add_method('GetMulticast', 'ns3::Address', [], is_pure_virtual=True, is_const=True, is_virtual=True) + ## net-device.h: ns3::Address ns3::NetDevice::MakeMulticastAddress(ns3::Ipv4Address multicastGroup) const [member function] + cls.add_method('MakeMulticastAddress', 'ns3::Address', [param('ns3::Ipv4Address', 'multicastGroup')], is_pure_virtual=True, is_const=True, is_virtual=True) + ## net-device.h: bool ns3::NetDevice::IsPointToPoint() const [member function] + cls.add_method('IsPointToPoint', 'bool', [], is_pure_virtual=True, is_const=True, is_virtual=True) + ## net-device.h: bool ns3::NetDevice::Send(ns3::Ptr packet, ns3::Address const & dest, uint16_t protocolNumber) [member function] + cls.add_method('Send', 'bool', [param('ns3::Ptr< ns3::Packet >', 'packet'), param('ns3::Address&', 'dest', is_const=True), param('uint16_t', 'protocolNumber')], is_pure_virtual=True, is_virtual=True) + ## net-device.h: ns3::Ptr ns3::NetDevice::GetNode() const [member function] + cls.add_method('GetNode', 'ns3::Ptr< ns3::Node >', [], is_pure_virtual=True, is_const=True, is_virtual=True) + ## net-device.h: void ns3::NetDevice::SetNode(ns3::Ptr node) [member function] + cls.add_method('SetNode', 'void', [param('ns3::Ptr< ns3::Node >', 'node')], is_pure_virtual=True, is_virtual=True) + ## net-device.h: bool ns3::NetDevice::NeedsArp() const [member function] + cls.add_method('NeedsArp', 'bool', [], is_pure_virtual=True, is_const=True, is_virtual=True) + ## net-device.h: void ns3::NetDevice::SetReceiveCallback(ns3::Callback, ns3::Ptr, unsigned short, ns3::Address const&, ns3::empty, ns3::empty> cb) [member function] + cls.add_method('SetReceiveCallback', 'void', [param('ns3::Callback< bool, ns3::Ptr< ns3::NetDevice >, ns3::Ptr< ns3::Packet >, unsigned short, ns3::Address const&, ns3::empty, ns3::empty >', 'cb')], is_pure_virtual=True, is_virtual=True) + cls.add_constructor([]) + return + +def register_Ns3Channel_methods(root_module, cls): + ## channel.h: static ns3::TypeId ns3::Channel::GetTypeId() [member function] + cls.add_method('GetTypeId', 'ns3::TypeId', [], is_static=True) + ## channel.h: ns3::Channel::Channel() [constructor] + cls.add_constructor([], visibility='public') + ## channel.h: ns3::Channel::Channel(std::string name) [constructor] + cls.add_constructor([param('std::string', 'name')], visibility='public') + ## channel.h: void ns3::Channel::SetName(std::string arg0) [member function] + cls.add_method('SetName', 'void', [param('std::string', 'arg0')]) + ## channel.h: std::string ns3::Channel::GetName() [member function] + cls.add_method('GetName', 'std::string', []) + ## channel.h: uint32_t ns3::Channel::GetNDevices() const [member function] + cls.add_method('GetNDevices', 'uint32_t', [], is_pure_virtual=True, is_const=True, is_virtual=True) + ## channel.h: ns3::Ptr ns3::Channel::GetDevice(uint32_t i) const [member function] + cls.add_method('GetDevice', 'ns3::Ptr< ns3::NetDevice >', [param('uint32_t', 'i')], is_pure_virtual=True, is_const=True, is_virtual=True) + return + +def register_Ns3SimpleChannel_methods(root_module, cls): + ## simple-channel.h: static ns3::TypeId ns3::SimpleChannel::GetTypeId() [member function] + cls.add_method('GetTypeId', 'ns3::TypeId', [], is_static=True) + ## simple-channel.h: ns3::SimpleChannel::SimpleChannel() [constructor] + cls.add_constructor([], visibility='public') + ## simple-channel.h: void ns3::SimpleChannel::Send(ns3::Ptr p, uint16_t protocol, ns3::Mac48Address to, ns3::Mac48Address from, ns3::Ptr sender) [member function] + cls.add_method('Send', 'void', [param('ns3::Ptr< ns3::Packet >', 'p'), param('uint16_t', 'protocol'), param('ns3::Mac48Address', 'to'), param('ns3::Mac48Address', 'from'), param('ns3::Ptr< ns3::SimpleNetDevice >', 'sender')]) + ## simple-channel.h: void ns3::SimpleChannel::Add(ns3::Ptr device) [member function] + cls.add_method('Add', 'void', [param('ns3::Ptr< ns3::SimpleNetDevice >', 'device')]) + ## simple-channel.h: uint32_t ns3::SimpleChannel::GetNDevices() const [member function] + cls.add_method('GetNDevices', 'uint32_t', [], is_const=True, is_virtual=True) + ## simple-channel.h: ns3::Ptr ns3::SimpleChannel::GetDevice(uint32_t i) const [member function] + cls.add_method('GetDevice', 'ns3::Ptr< ns3::NetDevice >', [param('uint32_t', 'i')], is_const=True, is_virtual=True) + return + +def register_Ns3AddressValue_methods(root_module, cls): + ## address.h: ns3::AddressValue::AddressValue() [constructor] + cls.add_constructor([], visibility='public') + ## address.h: ns3::AddressValue::AddressValue(ns3::Address const & value) [constructor] + cls.add_constructor([param('ns3::Address&', 'value', is_const=True)], visibility='public') + ## address.h: void ns3::AddressValue::Set(ns3::Address const & value) [member function] + cls.add_method('Set', 'void', [param('ns3::Address&', 'value', is_const=True)]) + ## address.h: ns3::Address ns3::AddressValue::Get() const [member function] + cls.add_method('Get', 'ns3::Address', [], is_const=True) + ## address.h: ns3::Ptr ns3::AddressValue::Copy() const [member function] + cls.add_method('Copy', 'ns3::Ptr< ns3::AttributeValue >', [], is_const=True, is_virtual=True) + ## address.h: std::string ns3::AddressValue::SerializeToString(ns3::Ptr checker) const [member function] + cls.add_method('SerializeToString', 'std::string', [param('ns3::Ptr< ns3::AttributeChecker const >', 'checker')], is_const=True, is_virtual=True) + ## address.h: bool ns3::AddressValue::DeserializeFromString(std::string value, ns3::Ptr checker) [member function] + cls.add_method('DeserializeFromString', 'bool', [param('std::string', 'value'), param('ns3::Ptr< ns3::AttributeChecker const >', 'checker')], is_virtual=True) + return + +def register_Ns3Node_methods(root_module, cls): + ## node.h: static ns3::TypeId ns3::Node::GetTypeId() [member function] + cls.add_method('GetTypeId', 'ns3::TypeId', [], is_static=True) + ## node.h: ns3::Node::Node() [constructor] + cls.add_constructor([], visibility='public') + ## node.h: ns3::Node::Node(uint32_t systemId) [constructor] + cls.add_constructor([param('uint32_t', 'systemId')], visibility='public') + ## node.h: uint32_t ns3::Node::GetId() const [member function] + cls.add_method('GetId', 'uint32_t', [], is_const=True) + ## node.h: uint32_t ns3::Node::GetSystemId() const [member function] + cls.add_method('GetSystemId', 'uint32_t', [], is_const=True) + ## node.h: uint32_t ns3::Node::AddDevice(ns3::Ptr device) [member function] + cls.add_method('AddDevice', 'uint32_t', [param('ns3::Ptr< ns3::NetDevice >', 'device')]) + ## node.h: ns3::Ptr ns3::Node::GetDevice(uint32_t index) const [member function] + cls.add_method('GetDevice', 'ns3::Ptr< ns3::NetDevice >', [param('uint32_t', 'index')], is_const=True) + ## node.h: uint32_t ns3::Node::GetNDevices() const [member function] + cls.add_method('GetNDevices', 'uint32_t', [], is_const=True) + ## node.h: uint32_t ns3::Node::AddApplication(ns3::Ptr application) [member function] + cls.add_method('AddApplication', 'uint32_t', [param('ns3::Ptr< ns3::Application >', 'application')]) + ## node.h: ns3::Ptr ns3::Node::GetApplication(uint32_t index) const [member function] + cls.add_method('GetApplication', 'ns3::Ptr< ns3::Application >', [param('uint32_t', 'index')], is_const=True) + ## node.h: ns3::Ptr ns3::Node::GetFirstApplication(ns3::TypeId tid) [member function] + cls.add_method('GetFirstApplication', 'ns3::Ptr< ns3::Application >', [param('ns3::TypeId', 'tid')]) + ## node.h: uint32_t ns3::Node::GetNApplications() const [member function] + cls.add_method('GetNApplications', 'uint32_t', [], is_const=True) + ## node.h: void ns3::Node::RegisterProtocolHandler(ns3::Callback, ns3::Ptr, unsigned short, ns3::Address const&, ns3::empty, ns3::empty> handler, uint16_t protocolType, ns3::Ptr device) [member function] + cls.add_method('RegisterProtocolHandler', 'void', [param('ns3::Callback< void, ns3::Ptr< ns3::NetDevice >, ns3::Ptr< ns3::Packet >, unsigned short, ns3::Address const&, ns3::empty, ns3::empty >', 'handler'), param('uint16_t', 'protocolType'), param('ns3::Ptr< ns3::NetDevice >', 'device')]) + ## node.h: void ns3::Node::UnregisterProtocolHandler(ns3::Callback, ns3::Ptr, unsigned short, ns3::Address const&, ns3::empty, ns3::empty> handler) [member function] + cls.add_method('UnregisterProtocolHandler', 'void', [param('ns3::Callback< void, ns3::Ptr< ns3::NetDevice >, ns3::Ptr< ns3::Packet >, unsigned short, ns3::Address const&, ns3::empty, ns3::empty >', 'handler')]) + ## node.h: void ns3::Node::DoDispose() [member function] + cls.add_method('DoDispose', 'void', [], visibility='protected', is_virtual=True) + ## node.h: void ns3::Node::NotifyDeviceAdded(ns3::Ptr device) [member function] + cls.add_method('NotifyDeviceAdded', 'void', [param('ns3::Ptr< ns3::NetDevice >', 'device')], visibility='private', is_virtual=True) + return + +def register_Ns3TcpSocket_methods(root_module, cls): + ## tcp-socket.h: static ns3::TypeId ns3::TcpSocket::GetTypeId() [member function] + cls.add_method('GetTypeId', 'ns3::TypeId', [], is_static=True) + ## tcp-socket.h: ns3::TcpSocket::TcpSocket() [constructor] + cls.add_constructor([], visibility='public') + ## tcp-socket.h: ns3::Socket::SocketErrno ns3::TcpSocket::GetErrno() const [member function] + cls.add_method('GetErrno', 'ns3::Socket::SocketErrno', [], is_pure_virtual=True, is_const=True, is_virtual=True) + ## tcp-socket.h: ns3::Ptr ns3::TcpSocket::GetNode() const [member function] + cls.add_method('GetNode', 'ns3::Ptr< ns3::Node >', [], is_pure_virtual=True, is_const=True, is_virtual=True) + ## tcp-socket.h: int ns3::TcpSocket::Bind() [member function] + cls.add_method('Bind', 'int', [], is_pure_virtual=True, is_virtual=True) + ## tcp-socket.h: int ns3::TcpSocket::Close() [member function] + cls.add_method('Close', 'int', [], is_pure_virtual=True, is_virtual=True) + ## tcp-socket.h: int ns3::TcpSocket::ShutdownSend() [member function] + cls.add_method('ShutdownSend', 'int', [], is_pure_virtual=True, is_virtual=True) + ## tcp-socket.h: int ns3::TcpSocket::ShutdownRecv() [member function] + cls.add_method('ShutdownRecv', 'int', [], is_pure_virtual=True, is_virtual=True) + ## tcp-socket.h: int ns3::TcpSocket::Connect(ns3::Address const & address) [member function] + cls.add_method('Connect', 'int', [param('ns3::Address&', 'address', is_const=True)], is_pure_virtual=True, is_virtual=True) + ## tcp-socket.h: uint32_t ns3::TcpSocket::GetTxAvailable() const [member function] + cls.add_method('GetTxAvailable', 'uint32_t', [], is_pure_virtual=True, is_const=True, is_virtual=True) + ## tcp-socket.h: int ns3::TcpSocket::Send(ns3::Ptr p, uint32_t flags) [member function] + cls.add_method('Send', 'int', [param('ns3::Ptr< ns3::Packet >', 'p'), param('uint32_t', 'flags')], is_pure_virtual=True, is_virtual=True) + ## tcp-socket.h: int ns3::TcpSocket::SendTo(ns3::Ptr p, uint32_t flags, ns3::Address const & toAddress) [member function] + cls.add_method('SendTo', 'int', [param('ns3::Ptr< ns3::Packet >', 'p'), param('uint32_t', 'flags'), param('ns3::Address&', 'toAddress', is_const=True)], is_pure_virtual=True, is_virtual=True) + ## tcp-socket.h: uint32_t ns3::TcpSocket::GetRxAvailable() const [member function] + cls.add_method('GetRxAvailable', 'uint32_t', [], is_pure_virtual=True, is_const=True, is_virtual=True) + ## tcp-socket.h: ns3::Ptr ns3::TcpSocket::Recv(uint32_t maxSize, uint32_t flags) [member function] + cls.add_method('Recv', 'ns3::Ptr< ns3::Packet >', [param('uint32_t', 'maxSize'), param('uint32_t', 'flags')], is_pure_virtual=True, is_virtual=True) + ## tcp-socket.h: ns3::Ptr ns3::TcpSocket::RecvFrom(uint32_t maxSize, uint32_t flags, ns3::Address & fromAddress) [member function] + cls.add_method('RecvFrom', 'ns3::Ptr< ns3::Packet >', [param('uint32_t', 'maxSize'), param('uint32_t', 'flags'), param('ns3::Address&', 'fromAddress')], is_pure_virtual=True, is_virtual=True) + ## tcp-socket.h: void ns3::TcpSocket::SetSndBufSize(uint32_t size) [member function] + cls.add_method('SetSndBufSize', 'void', [param('uint32_t', 'size')], is_pure_virtual=True, visibility='private', is_virtual=True) + ## tcp-socket.h: uint32_t ns3::TcpSocket::GetSndBufSize() const [member function] + cls.add_method('GetSndBufSize', 'uint32_t', [], is_pure_virtual=True, is_const=True, visibility='private', is_virtual=True) + ## tcp-socket.h: void ns3::TcpSocket::SetRcvBufSize(uint32_t size) [member function] + cls.add_method('SetRcvBufSize', 'void', [param('uint32_t', 'size')], is_pure_virtual=True, visibility='private', is_virtual=True) + ## tcp-socket.h: uint32_t ns3::TcpSocket::GetRcvBufSize() const [member function] + cls.add_method('GetRcvBufSize', 'uint32_t', [], is_pure_virtual=True, is_const=True, visibility='private', is_virtual=True) + ## tcp-socket.h: void ns3::TcpSocket::SetSegSize(uint32_t size) [member function] + cls.add_method('SetSegSize', 'void', [param('uint32_t', 'size')], is_pure_virtual=True, visibility='private', is_virtual=True) + ## tcp-socket.h: uint32_t ns3::TcpSocket::GetSegSize() const [member function] + cls.add_method('GetSegSize', 'uint32_t', [], is_pure_virtual=True, is_const=True, visibility='private', is_virtual=True) + ## tcp-socket.h: void ns3::TcpSocket::SetAdvWin(uint32_t window) [member function] + cls.add_method('SetAdvWin', 'void', [param('uint32_t', 'window')], is_pure_virtual=True, visibility='private', is_virtual=True) + ## tcp-socket.h: uint32_t ns3::TcpSocket::GetAdvWin() const [member function] + cls.add_method('GetAdvWin', 'uint32_t', [], is_pure_virtual=True, is_const=True, visibility='private', is_virtual=True) + ## tcp-socket.h: void ns3::TcpSocket::SetSSThresh(uint32_t threshold) [member function] + cls.add_method('SetSSThresh', 'void', [param('uint32_t', 'threshold')], is_pure_virtual=True, visibility='private', is_virtual=True) + ## tcp-socket.h: uint32_t ns3::TcpSocket::GetSSThresh() const [member function] + cls.add_method('GetSSThresh', 'uint32_t', [], is_pure_virtual=True, is_const=True, visibility='private', is_virtual=True) + ## tcp-socket.h: void ns3::TcpSocket::SetInitialCwnd(uint32_t count) [member function] + cls.add_method('SetInitialCwnd', 'void', [param('uint32_t', 'count')], is_pure_virtual=True, visibility='private', is_virtual=True) + ## tcp-socket.h: uint32_t ns3::TcpSocket::GetInitialCwnd() const [member function] + cls.add_method('GetInitialCwnd', 'uint32_t', [], is_pure_virtual=True, is_const=True, visibility='private', is_virtual=True) + ## tcp-socket.h: void ns3::TcpSocket::SetConnTimeout(ns3::Time timeout) [member function] + cls.add_method('SetConnTimeout', 'void', [param('ns3::Time', 'timeout')], is_pure_virtual=True, visibility='private', is_virtual=True) + ## tcp-socket.h: ns3::Time ns3::TcpSocket::GetConnTimeout() const [member function] + cls.add_method('GetConnTimeout', 'ns3::Time', [], is_pure_virtual=True, is_const=True, visibility='private', is_virtual=True) + ## tcp-socket.h: void ns3::TcpSocket::SetConnCount(uint32_t count) [member function] + cls.add_method('SetConnCount', 'void', [param('uint32_t', 'count')], is_pure_virtual=True, visibility='private', is_virtual=True) + ## tcp-socket.h: uint32_t ns3::TcpSocket::GetConnCount() const [member function] + cls.add_method('GetConnCount', 'uint32_t', [], is_pure_virtual=True, is_const=True, visibility='private', is_virtual=True) + ## tcp-socket.h: void ns3::TcpSocket::SetDelAckTimeout(ns3::Time timeout) [member function] + cls.add_method('SetDelAckTimeout', 'void', [param('ns3::Time', 'timeout')], is_pure_virtual=True, visibility='private', is_virtual=True) + ## tcp-socket.h: ns3::Time ns3::TcpSocket::GetDelAckTimeout() const [member function] + cls.add_method('GetDelAckTimeout', 'ns3::Time', [], is_pure_virtual=True, is_const=True, visibility='private', is_virtual=True) + ## tcp-socket.h: void ns3::TcpSocket::SetDelAckMaxCount(uint32_t count) [member function] + cls.add_method('SetDelAckMaxCount', 'void', [param('uint32_t', 'count')], is_pure_virtual=True, visibility='private', is_virtual=True) + ## tcp-socket.h: uint32_t ns3::TcpSocket::GetDelAckMaxCount() const [member function] + cls.add_method('GetDelAckMaxCount', 'uint32_t', [], is_pure_virtual=True, is_const=True, visibility='private', is_virtual=True) + return + +def register_Ns3EthernetHeader_methods(root_module, cls): + ## ethernet-header.h: ns3::EthernetHeader::EthernetHeader(bool hasPreamble) [constructor] + cls.add_constructor([param('bool', 'hasPreamble')], visibility='public') + ## ethernet-header.h: ns3::EthernetHeader::EthernetHeader() [constructor] + cls.add_constructor([], visibility='public') + ## ethernet-header.h: void ns3::EthernetHeader::SetLengthType(uint16_t size) [member function] + cls.add_method('SetLengthType', 'void', [param('uint16_t', 'size')]) + ## ethernet-header.h: void ns3::EthernetHeader::SetSource(ns3::Mac48Address source) [member function] + cls.add_method('SetSource', 'void', [param('ns3::Mac48Address', 'source')]) + ## ethernet-header.h: void ns3::EthernetHeader::SetDestination(ns3::Mac48Address destination) [member function] + cls.add_method('SetDestination', 'void', [param('ns3::Mac48Address', 'destination')]) + ## ethernet-header.h: void ns3::EthernetHeader::SetPreambleSfd(uint64_t preambleSfd) [member function] + cls.add_method('SetPreambleSfd', 'void', [param('uint64_t', 'preambleSfd')]) + ## ethernet-header.h: uint16_t ns3::EthernetHeader::GetLengthType() const [member function] + cls.add_method('GetLengthType', 'uint16_t', [], is_const=True) + ## ethernet-header.h: ns3::ethernet_header_t ns3::EthernetHeader::GetPacketType() const [member function] + cls.add_method('GetPacketType', 'ns3::ethernet_header_t', [], is_const=True) + ## ethernet-header.h: ns3::Mac48Address ns3::EthernetHeader::GetSource() const [member function] + cls.add_method('GetSource', 'ns3::Mac48Address', [], is_const=True) + ## ethernet-header.h: ns3::Mac48Address ns3::EthernetHeader::GetDestination() const [member function] + cls.add_method('GetDestination', 'ns3::Mac48Address', [], is_const=True) + ## ethernet-header.h: uint64_t ns3::EthernetHeader::GetPreambleSfd() const [member function] + cls.add_method('GetPreambleSfd', 'uint64_t', [], is_const=True) + ## ethernet-header.h: uint32_t ns3::EthernetHeader::GetHeaderSize() const [member function] + cls.add_method('GetHeaderSize', 'uint32_t', [], is_const=True) + ## ethernet-header.h: static ns3::TypeId ns3::EthernetHeader::GetTypeId() [member function] + cls.add_method('GetTypeId', 'ns3::TypeId', [], is_static=True) + ## ethernet-header.h: ns3::TypeId ns3::EthernetHeader::GetInstanceTypeId() const [member function] + cls.add_method('GetInstanceTypeId', 'ns3::TypeId', [], is_const=True, is_virtual=True) + ## ethernet-header.h: void ns3::EthernetHeader::Print(std::ostream & os) const [member function] + cls.add_method('Print', 'void', [param('std::ostream&', 'os')], is_const=True, is_virtual=True) + ## ethernet-header.h: uint32_t ns3::EthernetHeader::GetSerializedSize() const [member function] + cls.add_method('GetSerializedSize', 'uint32_t', [], is_const=True, is_virtual=True) + ## ethernet-header.h: void ns3::EthernetHeader::Serialize(ns3::Buffer::Iterator start) const [member function] + cls.add_method('Serialize', 'void', [param('ns3::Buffer::Iterator', 'start')], is_const=True, is_virtual=True) + ## ethernet-header.h: uint32_t ns3::EthernetHeader::Deserialize(ns3::Buffer::Iterator start) [member function] + cls.add_method('Deserialize', 'uint32_t', [param('ns3::Buffer::Iterator', 'start')], is_virtual=True) + return + +def register_Ns3SocketIpTtlTag_methods(root_module, cls): + ## socket.h: ns3::SocketIpTtlTag::SocketIpTtlTag() [constructor] + cls.add_constructor([], visibility='public') + ## socket.h: void ns3::SocketIpTtlTag::SetTtl(uint8_t ttl) [member function] + cls.add_method('SetTtl', 'void', [param('uint8_t', 'ttl')]) + ## socket.h: uint8_t ns3::SocketIpTtlTag::GetTtl() const [member function] + cls.add_method('GetTtl', 'uint8_t', [], is_const=True) + ## socket.h: static ns3::TypeId ns3::SocketIpTtlTag::GetTypeId() [member function] + cls.add_method('GetTypeId', 'ns3::TypeId', [], is_static=True) + ## socket.h: ns3::TypeId ns3::SocketIpTtlTag::GetInstanceTypeId() const [member function] + cls.add_method('GetInstanceTypeId', 'ns3::TypeId', [], is_const=True, is_virtual=True) + ## socket.h: uint32_t ns3::SocketIpTtlTag::GetSerializedSize() const [member function] + cls.add_method('GetSerializedSize', 'uint32_t', [], is_const=True, is_virtual=True) + ## socket.h: void ns3::SocketIpTtlTag::Serialize(ns3::TagBuffer i) const [member function] + cls.add_method('Serialize', 'void', [param('ns3::TagBuffer', 'i')], is_const=True, is_virtual=True) + ## socket.h: void ns3::SocketIpTtlTag::Deserialize(ns3::TagBuffer i) [member function] + cls.add_method('Deserialize', 'void', [param('ns3::TagBuffer', 'i')], is_virtual=True) + ## socket.h: void ns3::SocketIpTtlTag::Print(std::ostream & os) const [member function] + cls.add_method('Print', 'void', [param('std::ostream&', 'os')], is_const=True, is_virtual=True) + return + +def register_Ns3Ipv4_methods(root_module, cls): + ## ipv4.h: static ns3::TypeId ns3::Ipv4::GetTypeId() [member function] + cls.add_method('GetTypeId', 'ns3::TypeId', [], is_static=True) + ## ipv4.h: ns3::Ipv4::Ipv4() [constructor] + cls.add_constructor([], visibility='public') + ## ipv4.h: void ns3::Ipv4::AddRoutingProtocol(ns3::Ptr routingProtocol, int16_t priority) [member function] + cls.add_method('AddRoutingProtocol', 'void', [param('ns3::Ptr< ns3::Ipv4RoutingProtocol >', 'routingProtocol'), param('int16_t', 'priority')], is_pure_virtual=True, is_virtual=True) + ## ipv4.h: void ns3::Ipv4::AddHostRouteTo(ns3::Ipv4Address dest, ns3::Ipv4Address nextHop, uint32_t interface) [member function] + cls.add_method('AddHostRouteTo', 'void', [param('ns3::Ipv4Address', 'dest'), param('ns3::Ipv4Address', 'nextHop'), param('uint32_t', 'interface')], is_pure_virtual=True, is_virtual=True) + ## ipv4.h: void ns3::Ipv4::AddHostRouteTo(ns3::Ipv4Address dest, uint32_t interface) [member function] + cls.add_method('AddHostRouteTo', 'void', [param('ns3::Ipv4Address', 'dest'), param('uint32_t', 'interface')], is_pure_virtual=True, is_virtual=True) + ## ipv4.h: void ns3::Ipv4::AddNetworkRouteTo(ns3::Ipv4Address network, ns3::Ipv4Mask networkMask, ns3::Ipv4Address nextHop, uint32_t interface) [member function] + cls.add_method('AddNetworkRouteTo', 'void', [param('ns3::Ipv4Address', 'network'), param('ns3::Ipv4Mask', 'networkMask'), param('ns3::Ipv4Address', 'nextHop'), param('uint32_t', 'interface')], is_pure_virtual=True, is_virtual=True) + ## ipv4.h: void ns3::Ipv4::AddNetworkRouteTo(ns3::Ipv4Address network, ns3::Ipv4Mask networkMask, uint32_t interface) [member function] + cls.add_method('AddNetworkRouteTo', 'void', [param('ns3::Ipv4Address', 'network'), param('ns3::Ipv4Mask', 'networkMask'), param('uint32_t', 'interface')], is_pure_virtual=True, is_virtual=True) + ## ipv4.h: void ns3::Ipv4::SetDefaultRoute(ns3::Ipv4Address nextHop, uint32_t interface) [member function] + cls.add_method('SetDefaultRoute', 'void', [param('ns3::Ipv4Address', 'nextHop'), param('uint32_t', 'interface')], is_pure_virtual=True, is_virtual=True) + ## ipv4.h: uint32_t ns3::Ipv4::GetNRoutes() [member function] + cls.add_method('GetNRoutes', 'uint32_t', [], is_pure_virtual=True, is_virtual=True) + ## ipv4.h: ns3::Ipv4Route ns3::Ipv4::GetRoute(uint32_t i) [member function] + cls.add_method('GetRoute', 'ns3::Ipv4Route', [param('uint32_t', 'i')], is_pure_virtual=True, is_virtual=True) + ## ipv4.h: void ns3::Ipv4::RemoveRoute(uint32_t i) [member function] + cls.add_method('RemoveRoute', 'void', [param('uint32_t', 'i')], is_pure_virtual=True, is_virtual=True) + ## ipv4.h: void ns3::Ipv4::AddMulticastRoute(ns3::Ipv4Address origin, ns3::Ipv4Address group, uint32_t inputInterface, std::vector > outputInterfaces) [member function] + cls.add_method('AddMulticastRoute', 'void', [param('ns3::Ipv4Address', 'origin'), param('ns3::Ipv4Address', 'group'), param('uint32_t', 'inputInterface'), param('std::vector< unsigned int, std::allocator< unsigned int > >', 'outputInterfaces')], is_pure_virtual=True, is_virtual=True) + ## ipv4.h: void ns3::Ipv4::RemoveMulticastRoute(ns3::Ipv4Address origin, ns3::Ipv4Address group, uint32_t inputInterface) [member function] + cls.add_method('RemoveMulticastRoute', 'void', [param('ns3::Ipv4Address', 'origin'), param('ns3::Ipv4Address', 'group'), param('uint32_t', 'inputInterface')], is_pure_virtual=True, is_virtual=True) + ## ipv4.h: void ns3::Ipv4::SetDefaultMulticastRoute(uint32_t outputInterface) [member function] + cls.add_method('SetDefaultMulticastRoute', 'void', [param('uint32_t', 'outputInterface')], is_pure_virtual=True, is_virtual=True) + ## ipv4.h: uint32_t ns3::Ipv4::GetNMulticastRoutes() const [member function] + cls.add_method('GetNMulticastRoutes', 'uint32_t', [], is_pure_virtual=True, is_const=True, is_virtual=True) + ## ipv4.h: ns3::Ipv4MulticastRoute ns3::Ipv4::GetMulticastRoute(uint32_t i) const [member function] + cls.add_method('GetMulticastRoute', 'ns3::Ipv4MulticastRoute', [param('uint32_t', 'i')], is_pure_virtual=True, is_const=True, is_virtual=True) + ## ipv4.h: void ns3::Ipv4::RemoveMulticastRoute(uint32_t i) [member function] + cls.add_method('RemoveMulticastRoute', 'void', [param('uint32_t', 'i')], is_pure_virtual=True, is_virtual=True) + ## ipv4.h: uint32_t ns3::Ipv4::AddInterface(ns3::Ptr device) [member function] + cls.add_method('AddInterface', 'uint32_t', [param('ns3::Ptr< ns3::NetDevice >', 'device')], is_pure_virtual=True, is_virtual=True) + ## ipv4.h: uint32_t ns3::Ipv4::GetNInterfaces() [member function] + cls.add_method('GetNInterfaces', 'uint32_t', [], is_pure_virtual=True, is_virtual=True) + ## ipv4.h: uint32_t ns3::Ipv4::FindInterfaceForAddr(ns3::Ipv4Address addr) const [member function] + cls.add_method('FindInterfaceForAddr', 'uint32_t', [param('ns3::Ipv4Address', 'addr')], is_pure_virtual=True, is_const=True, is_virtual=True) + ## ipv4.h: uint32_t ns3::Ipv4::FindInterfaceForAddr(ns3::Ipv4Address addr, ns3::Ipv4Mask mask) const [member function] + cls.add_method('FindInterfaceForAddr', 'uint32_t', [param('ns3::Ipv4Address', 'addr'), param('ns3::Ipv4Mask', 'mask')], is_pure_virtual=True, is_const=True, is_virtual=True) + ## ipv4.h: int32_t ns3::Ipv4::FindInterfaceForDevice(ns3::Ptr nd) const [member function] + cls.add_method('FindInterfaceForDevice', 'int32_t', [param('ns3::Ptr< ns3::NetDevice >', 'nd')], is_pure_virtual=True, is_const=True, is_virtual=True) + ## ipv4.h: ns3::Ptr ns3::Ipv4::GetNetDevice(uint32_t i) [member function] + cls.add_method('GetNetDevice', 'ns3::Ptr< ns3::NetDevice >', [param('uint32_t', 'i')], is_pure_virtual=True, is_virtual=True) + ## ipv4.h: void ns3::Ipv4::JoinMulticastGroup(ns3::Ipv4Address origin, ns3::Ipv4Address group) [member function] + cls.add_method('JoinMulticastGroup', 'void', [param('ns3::Ipv4Address', 'origin'), param('ns3::Ipv4Address', 'group')], is_pure_virtual=True, is_virtual=True) + ## ipv4.h: void ns3::Ipv4::LeaveMulticastGroup(ns3::Ipv4Address origin, ns3::Ipv4Address group) [member function] + cls.add_method('LeaveMulticastGroup', 'void', [param('ns3::Ipv4Address', 'origin'), param('ns3::Ipv4Address', 'group')], is_pure_virtual=True, is_virtual=True) + ## ipv4.h: void ns3::Ipv4::SetAddress(uint32_t i, ns3::Ipv4Address address) [member function] + cls.add_method('SetAddress', 'void', [param('uint32_t', 'i'), param('ns3::Ipv4Address', 'address')], is_pure_virtual=True, is_virtual=True) + ## ipv4.h: void ns3::Ipv4::SetNetworkMask(uint32_t i, ns3::Ipv4Mask mask) [member function] + cls.add_method('SetNetworkMask', 'void', [param('uint32_t', 'i'), param('ns3::Ipv4Mask', 'mask')], is_pure_virtual=True, is_virtual=True) + ## ipv4.h: ns3::Ipv4Mask ns3::Ipv4::GetNetworkMask(uint32_t i) const [member function] + cls.add_method('GetNetworkMask', 'ns3::Ipv4Mask', [param('uint32_t', 'i')], is_pure_virtual=True, is_const=True, is_virtual=True) + ## ipv4.h: void ns3::Ipv4::SetMetric(uint32_t i, uint16_t metric) [member function] + cls.add_method('SetMetric', 'void', [param('uint32_t', 'i'), param('uint16_t', 'metric')], is_pure_virtual=True, is_virtual=True) + ## ipv4.h: uint16_t ns3::Ipv4::GetMetric(uint32_t i) const [member function] + cls.add_method('GetMetric', 'uint16_t', [param('uint32_t', 'i')], is_pure_virtual=True, is_const=True, is_virtual=True) + ## ipv4.h: ns3::Ipv4Address ns3::Ipv4::GetAddress(uint32_t i) const [member function] + cls.add_method('GetAddress', 'ns3::Ipv4Address', [param('uint32_t', 'i')], is_pure_virtual=True, is_const=True, is_virtual=True) + ## ipv4.h: ns3::Ipv4Address ns3::Ipv4::GetSourceAddress(ns3::Ipv4Address destination) const [member function] + cls.add_method('GetSourceAddress', 'ns3::Ipv4Address', [param('ns3::Ipv4Address', 'destination')], is_pure_virtual=True, is_const=True, is_virtual=True) + ## ipv4.h: bool ns3::Ipv4::GetIfIndexForDestination(ns3::Ipv4Address dest, uint32_t & ifIndex) const [member function] + cls.add_method('GetIfIndexForDestination', 'bool', [param('ns3::Ipv4Address', 'dest'), param('uint32_t&', 'ifIndex')], is_pure_virtual=True, is_const=True, is_virtual=True) + ## ipv4.h: uint16_t ns3::Ipv4::GetMtu(uint32_t i) const [member function] + cls.add_method('GetMtu', 'uint16_t', [param('uint32_t', 'i')], is_pure_virtual=True, is_const=True, is_virtual=True) + ## ipv4.h: bool ns3::Ipv4::IsUp(uint32_t i) const [member function] + cls.add_method('IsUp', 'bool', [param('uint32_t', 'i')], is_pure_virtual=True, is_const=True, is_virtual=True) + ## ipv4.h: void ns3::Ipv4::SetUp(uint32_t i) [member function] + cls.add_method('SetUp', 'void', [param('uint32_t', 'i')], is_pure_virtual=True, is_virtual=True) + ## ipv4.h: void ns3::Ipv4::SetDown(uint32_t i) [member function] + cls.add_method('SetDown', 'void', [param('uint32_t', 'i')], is_pure_virtual=True, is_virtual=True) + ## ipv4.h: uint32_t ns3::Ipv4::GetIfIndexByAddress(ns3::Ipv4Address addr, ns3::Ipv4Mask mask=ns3::Ipv4Mask(((const char*)"255.255.255.255"))) [member function] + cls.add_method('GetIfIndexByAddress', 'uint32_t', [param('ns3::Ipv4Address', 'addr'), param('ns3::Ipv4Mask', 'mask', default_value='ns3::Ipv4Mask(((const char*)"255.255.255.255"))')], is_virtual=True) + return + +def register_Ns3SocketFactory_methods(root_module, cls): + ## socket-factory.h: static ns3::TypeId ns3::SocketFactory::GetTypeId() [member function] + cls.add_method('GetTypeId', 'ns3::TypeId', [], is_static=True) + ## socket-factory.h: ns3::SocketFactory::SocketFactory() [constructor] + cls.add_constructor([], visibility='public') + ## socket-factory.h: ns3::Ptr ns3::SocketFactory::CreateSocket() [member function] + cls.add_method('CreateSocket', 'ns3::Ptr< ns3::Socket >', [], is_pure_virtual=True, is_virtual=True) + return + +def register_Ns3DropTailQueue_methods(root_module, cls): + ## drop-tail-queue.h: static ns3::TypeId ns3::DropTailQueue::GetTypeId() [member function] + cls.add_method('GetTypeId', 'ns3::TypeId', [], is_static=True) + ## drop-tail-queue.h: ns3::DropTailQueue::DropTailQueue() [constructor] + cls.add_constructor([], visibility='public') + ## drop-tail-queue.h: bool ns3::DropTailQueue::DoEnqueue(ns3::Ptr p) [member function] + cls.add_method('DoEnqueue', 'bool', [param('ns3::Ptr< ns3::Packet >', 'p')], visibility='private', is_virtual=True) + ## drop-tail-queue.h: ns3::Ptr ns3::DropTailQueue::DoDequeue() [member function] + cls.add_method('DoDequeue', 'ns3::Ptr< ns3::Packet >', [], visibility='private', is_virtual=True) + ## drop-tail-queue.h: ns3::Ptr ns3::DropTailQueue::DoPeek() const [member function] + cls.add_method('DoPeek', 'ns3::Ptr< ns3::Packet >', [], is_const=True, visibility='private', is_virtual=True) + return + +def register_Ns3EthernetTrailer_methods(root_module, cls): + ## ethernet-trailer.h: ns3::EthernetTrailer::EthernetTrailer() [constructor] + cls.add_constructor([], visibility='public') + ## ethernet-trailer.h: static void ns3::EthernetTrailer::EnableFcs(bool enable) [member function] + cls.add_method('EnableFcs', 'void', [param('bool', 'enable')], is_static=True) + ## ethernet-trailer.h: void ns3::EthernetTrailer::CalcFcs(ns3::Ptr p) [member function] + cls.add_method('CalcFcs', 'void', [param('ns3::Ptr< ns3::Packet >', 'p')]) + ## ethernet-trailer.h: void ns3::EthernetTrailer::SetFcs(uint32_t fcs) [member function] + cls.add_method('SetFcs', 'void', [param('uint32_t', 'fcs')]) + ## ethernet-trailer.h: uint32_t ns3::EthernetTrailer::GetFcs() [member function] + cls.add_method('GetFcs', 'uint32_t', []) + ## ethernet-trailer.h: bool ns3::EthernetTrailer::CheckFcs(ns3::Ptr p) const [member function] + cls.add_method('CheckFcs', 'bool', [param('ns3::Ptr< ns3::Packet >', 'p')], is_const=True) + ## ethernet-trailer.h: uint32_t ns3::EthernetTrailer::GetTrailerSize() const [member function] + cls.add_method('GetTrailerSize', 'uint32_t', [], is_const=True) + ## ethernet-trailer.h: static ns3::TypeId ns3::EthernetTrailer::GetTypeId() [member function] + cls.add_method('GetTypeId', 'ns3::TypeId', [], is_static=True) + ## ethernet-trailer.h: ns3::TypeId ns3::EthernetTrailer::GetInstanceTypeId() const [member function] + cls.add_method('GetInstanceTypeId', 'ns3::TypeId', [], is_const=True, is_virtual=True) + ## ethernet-trailer.h: void ns3::EthernetTrailer::Print(std::ostream & os) const [member function] + cls.add_method('Print', 'void', [param('std::ostream&', 'os')], is_const=True, is_virtual=True) + ## ethernet-trailer.h: uint32_t ns3::EthernetTrailer::GetSerializedSize() const [member function] + cls.add_method('GetSerializedSize', 'uint32_t', [], is_const=True, is_virtual=True) + ## ethernet-trailer.h: void ns3::EthernetTrailer::Serialize(ns3::Buffer::Iterator end) const [member function] + cls.add_method('Serialize', 'void', [param('ns3::Buffer::Iterator', 'end')], is_const=True, is_virtual=True) + ## ethernet-trailer.h: uint32_t ns3::EthernetTrailer::Deserialize(ns3::Buffer::Iterator end) [member function] + cls.add_method('Deserialize', 'uint32_t', [param('ns3::Buffer::Iterator', 'end')], is_virtual=True) + return + +def register_Ns3LlcSnapHeader_methods(root_module, cls): + ## llc-snap-header.h: ns3::LlcSnapHeader::LlcSnapHeader() [constructor] + cls.add_constructor([], visibility='public') + ## llc-snap-header.h: void ns3::LlcSnapHeader::SetType(uint16_t type) [member function] + cls.add_method('SetType', 'void', [param('uint16_t', 'type')]) + ## llc-snap-header.h: uint16_t ns3::LlcSnapHeader::GetType() [member function] + cls.add_method('GetType', 'uint16_t', []) + ## llc-snap-header.h: static ns3::TypeId ns3::LlcSnapHeader::GetTypeId() [member function] + cls.add_method('GetTypeId', 'ns3::TypeId', [], is_static=True) + ## llc-snap-header.h: ns3::TypeId ns3::LlcSnapHeader::GetInstanceTypeId() const [member function] + cls.add_method('GetInstanceTypeId', 'ns3::TypeId', [], is_const=True, is_virtual=True) + ## llc-snap-header.h: void ns3::LlcSnapHeader::Print(std::ostream & os) const [member function] + cls.add_method('Print', 'void', [param('std::ostream&', 'os')], is_const=True, is_virtual=True) + ## llc-snap-header.h: uint32_t ns3::LlcSnapHeader::GetSerializedSize() const [member function] + cls.add_method('GetSerializedSize', 'uint32_t', [], is_const=True, is_virtual=True) + ## llc-snap-header.h: void ns3::LlcSnapHeader::Serialize(ns3::Buffer::Iterator start) const [member function] + cls.add_method('Serialize', 'void', [param('ns3::Buffer::Iterator', 'start')], is_const=True, is_virtual=True) + ## llc-snap-header.h: uint32_t ns3::LlcSnapHeader::Deserialize(ns3::Buffer::Iterator start) [member function] + cls.add_method('Deserialize', 'uint32_t', [param('ns3::Buffer::Iterator', 'start')], is_virtual=True) + return + +def register_Ns3UdpSocketFactory_methods(root_module, cls): + ## udp-socket-factory.h: static ns3::TypeId ns3::UdpSocketFactory::GetTypeId() [member function] + cls.add_method('GetTypeId', 'ns3::TypeId', [], is_static=True) + ## udp-socket-factory.h: ns3::Ptr ns3::UdpSocketFactory::CreateSocket() [member function] + cls.add_method('CreateSocket', 'ns3::Ptr< ns3::Socket >', [], is_pure_virtual=True, is_virtual=True) + cls.add_constructor([]) + return + +def register_Ns3SimpleNetDevice_methods(root_module, cls): + ## simple-net-device.h: static ns3::TypeId ns3::SimpleNetDevice::GetTypeId() [member function] + cls.add_method('GetTypeId', 'ns3::TypeId', [], is_static=True) + ## simple-net-device.h: ns3::SimpleNetDevice::SimpleNetDevice() [constructor] + cls.add_constructor([], visibility='public') + ## simple-net-device.h: void ns3::SimpleNetDevice::Receive(ns3::Ptr packet, uint16_t protocol, ns3::Mac48Address to, ns3::Mac48Address from) [member function] + cls.add_method('Receive', 'void', [param('ns3::Ptr< ns3::Packet >', 'packet'), param('uint16_t', 'protocol'), param('ns3::Mac48Address', 'to'), param('ns3::Mac48Address', 'from')]) + ## simple-net-device.h: void ns3::SimpleNetDevice::SetChannel(ns3::Ptr channel) [member function] + cls.add_method('SetChannel', 'void', [param('ns3::Ptr< ns3::SimpleChannel >', 'channel')]) + ## simple-net-device.h: void ns3::SimpleNetDevice::SetAddress(ns3::Mac48Address address) [member function] + cls.add_method('SetAddress', 'void', [param('ns3::Mac48Address', 'address')]) + ## simple-net-device.h: void ns3::SimpleNetDevice::SetName(std::string const name) [member function] + cls.add_method('SetName', 'void', [param('std::string', 'name', is_const=True)], is_virtual=True) + ## simple-net-device.h: std::string ns3::SimpleNetDevice::GetName() const [member function] + cls.add_method('GetName', 'std::string', [], is_const=True, is_virtual=True) + ## simple-net-device.h: void ns3::SimpleNetDevice::SetIfIndex(uint32_t const index) [member function] + cls.add_method('SetIfIndex', 'void', [param('uint32_t', 'index', is_const=True)], is_virtual=True) + ## simple-net-device.h: uint32_t ns3::SimpleNetDevice::GetIfIndex() const [member function] + cls.add_method('GetIfIndex', 'uint32_t', [], is_const=True, is_virtual=True) + ## simple-net-device.h: ns3::Ptr ns3::SimpleNetDevice::GetChannel() const [member function] + cls.add_method('GetChannel', 'ns3::Ptr< ns3::Channel >', [], is_const=True, is_virtual=True) + ## simple-net-device.h: ns3::Address ns3::SimpleNetDevice::GetAddress() const [member function] + cls.add_method('GetAddress', 'ns3::Address', [], is_const=True, is_virtual=True) + ## simple-net-device.h: bool ns3::SimpleNetDevice::SetMtu(uint16_t const mtu) [member function] + cls.add_method('SetMtu', 'bool', [param('uint16_t', 'mtu', is_const=True)], is_virtual=True) + ## simple-net-device.h: uint16_t ns3::SimpleNetDevice::GetMtu() const [member function] + cls.add_method('GetMtu', 'uint16_t', [], is_const=True, is_virtual=True) + ## simple-net-device.h: bool ns3::SimpleNetDevice::IsLinkUp() const [member function] + cls.add_method('IsLinkUp', 'bool', [], is_const=True, is_virtual=True) + ## simple-net-device.h: void ns3::SimpleNetDevice::SetLinkChangeCallback(ns3::Callback callback) [member function] + cls.add_method('SetLinkChangeCallback', 'void', [param('ns3::Callback< void, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty >', 'callback')], is_virtual=True) + ## simple-net-device.h: bool ns3::SimpleNetDevice::IsBroadcast() const [member function] + cls.add_method('IsBroadcast', 'bool', [], is_const=True, is_virtual=True) + ## simple-net-device.h: ns3::Address ns3::SimpleNetDevice::GetBroadcast() const [member function] + cls.add_method('GetBroadcast', 'ns3::Address', [], is_const=True, is_virtual=True) + ## simple-net-device.h: bool ns3::SimpleNetDevice::IsMulticast() const [member function] + cls.add_method('IsMulticast', 'bool', [], is_const=True, is_virtual=True) + ## simple-net-device.h: ns3::Address ns3::SimpleNetDevice::GetMulticast() const [member function] + cls.add_method('GetMulticast', 'ns3::Address', [], is_const=True, is_virtual=True) + ## simple-net-device.h: ns3::Address ns3::SimpleNetDevice::MakeMulticastAddress(ns3::Ipv4Address multicastGroup) const [member function] + cls.add_method('MakeMulticastAddress', 'ns3::Address', [param('ns3::Ipv4Address', 'multicastGroup')], is_const=True, is_virtual=True) + ## simple-net-device.h: bool ns3::SimpleNetDevice::IsPointToPoint() const [member function] + cls.add_method('IsPointToPoint', 'bool', [], is_const=True, is_virtual=True) + ## simple-net-device.h: bool ns3::SimpleNetDevice::Send(ns3::Ptr packet, ns3::Address const & dest, uint16_t protocolNumber) [member function] + cls.add_method('Send', 'bool', [param('ns3::Ptr< ns3::Packet >', 'packet'), param('ns3::Address&', 'dest', is_const=True), param('uint16_t', 'protocolNumber')], is_virtual=True) + ## simple-net-device.h: ns3::Ptr ns3::SimpleNetDevice::GetNode() const [member function] + cls.add_method('GetNode', 'ns3::Ptr< ns3::Node >', [], is_const=True, is_virtual=True) + ## simple-net-device.h: void ns3::SimpleNetDevice::SetNode(ns3::Ptr node) [member function] + cls.add_method('SetNode', 'void', [param('ns3::Ptr< ns3::Node >', 'node')], is_virtual=True) + ## simple-net-device.h: bool ns3::SimpleNetDevice::NeedsArp() const [member function] + cls.add_method('NeedsArp', 'bool', [], is_const=True, is_virtual=True) + ## simple-net-device.h: void ns3::SimpleNetDevice::SetReceiveCallback(ns3::Callback, ns3::Ptr, unsigned short, ns3::Address const&, ns3::empty, ns3::empty> cb) [member function] + cls.add_method('SetReceiveCallback', 'void', [param('ns3::Callback< bool, ns3::Ptr< ns3::NetDevice >, ns3::Ptr< ns3::Packet >, unsigned short, ns3::Address const&, ns3::empty, ns3::empty >', 'cb')], is_virtual=True) + ## simple-net-device.h: void ns3::SimpleNetDevice::DoDispose() [member function] + cls.add_method('DoDispose', 'void', [], visibility='protected', is_virtual=True) + return + +def register_Ns3TcpSocketFactory_methods(root_module, cls): + ## tcp-socket-factory.h: static ns3::TypeId ns3::TcpSocketFactory::GetTypeId() [member function] + cls.add_method('GetTypeId', 'ns3::TypeId', [], is_static=True) + ## tcp-socket-factory.h: ns3::Ptr ns3::TcpSocketFactory::CreateSocket() [member function] + cls.add_method('CreateSocket', 'ns3::Ptr< ns3::Socket >', [], is_pure_virtual=True, is_virtual=True) + cls.add_constructor([]) + return + +def register_Ns3PacketSocketFactory_methods(root_module, cls): + ## packet-socket-factory.h: static ns3::TypeId ns3::PacketSocketFactory::GetTypeId() [member function] + cls.add_method('GetTypeId', 'ns3::TypeId', [], is_static=True) + ## packet-socket-factory.h: ns3::PacketSocketFactory::PacketSocketFactory() [constructor] + cls.add_constructor([], visibility='public') + ## packet-socket-factory.h: ns3::Ptr ns3::PacketSocketFactory::CreateSocket() [member function] + cls.add_method('CreateSocket', 'ns3::Ptr< ns3::Socket >', [], is_virtual=True) + return + +def register_functions(root_module): + module = root_module + ## mac48-address.h: extern ns3::Ptr ns3::MakeMac48AddressChecker() [free function] + module.add_function('MakeMac48AddressChecker', 'ns3::Ptr< ns3::AttributeChecker const >', []) + ## ipv4-address.h: extern ns3::Ptr ns3::MakeIpv4AddressChecker() [free function] + module.add_function('MakeIpv4AddressChecker', 'ns3::Ptr< ns3::AttributeChecker const >', []) + ## address-utils.h: extern void ns3::WriteTo(ns3::Buffer::Iterator & i, ns3::Mac48Address ad) [free function] + module.add_function('WriteTo', 'void', [param('ns3::Buffer::Iterator&', 'i'), param('ns3::Mac48Address', 'ad')]) + ## address-utils.h: extern void ns3::WriteTo(ns3::Buffer::Iterator & i, ns3::Address const & ad) [free function] + module.add_function('WriteTo', 'void', [param('ns3::Buffer::Iterator&', 'i'), param('ns3::Address&', 'ad', is_const=True)]) + ## address-utils.h: extern void ns3::WriteTo(ns3::Buffer::Iterator & i, ns3::Ipv4Address ad) [free function] + module.add_function('WriteTo', 'void', [param('ns3::Buffer::Iterator&', 'i'), param('ns3::Ipv4Address', 'ad')]) + ## address.h: extern ns3::Ptr ns3::MakeAddressChecker() [free function] + module.add_function('MakeAddressChecker', 'ns3::Ptr< ns3::AttributeChecker const >', []) + ## ipv4-address.h: extern ns3::Ptr ns3::MakeIpv4MaskChecker() [free function] + module.add_function('MakeIpv4MaskChecker', 'ns3::Ptr< ns3::AttributeChecker const >', []) + ## address-utils.h: extern void ns3::ReadFrom(ns3::Buffer::Iterator & i, ns3::Mac48Address & ad) [free function] + module.add_function('ReadFrom', 'void', [param('ns3::Buffer::Iterator&', 'i'), param('ns3::Mac48Address&', 'ad')]) + ## address-utils.h: extern void ns3::ReadFrom(ns3::Buffer::Iterator & i, ns3::Address & ad, uint32_t len) [free function] + module.add_function('ReadFrom', 'void', [param('ns3::Buffer::Iterator&', 'i'), param('ns3::Address&', 'ad'), param('uint32_t', 'len')]) + ## address-utils.h: extern void ns3::ReadFrom(ns3::Buffer::Iterator & i, ns3::Ipv4Address & ad) [free function] + module.add_function('ReadFrom', 'void', [param('ns3::Buffer::Iterator&', 'i'), param('ns3::Ipv4Address&', 'ad')]) + register_functions_ns3_internal(module.get_submodule('internal'), root_module) + register_functions_ns3_TimeStepPrecision(module.get_submodule('TimeStepPrecision'), root_module) + register_functions_ns3_Config(module.get_submodule('Config'), root_module) + register_functions_ns3_olsr(module.get_submodule('olsr'), root_module) + return + +def register_functions_ns3_internal(module, root_module): + return + +def register_functions_ns3_TimeStepPrecision(module, root_module): + return + +def register_functions_ns3_Config(module, root_module): + return + +def register_functions_ns3_olsr(module, root_module): + return + diff --git a/bindings/python/ns3_module_olsr.py b/bindings/python/ns3_module_olsr.py new file mode 100644 index 000000000..68089d125 --- /dev/null +++ b/bindings/python/ns3_module_olsr.py @@ -0,0 +1,288 @@ +from pybindgen import Module, FileCodeSink, write_preamble, param, retval + +def register_types(module): + root_module = module.get_root() + + + ## Register a nested module for the namespace internal + + nested_module = module.add_cpp_namespace('internal') + register_types_ns3_internal(nested_module) + + + ## Register a nested module for the namespace TimeStepPrecision + + nested_module = module.add_cpp_namespace('TimeStepPrecision') + register_types_ns3_TimeStepPrecision(nested_module) + + + ## Register a nested module for the namespace Config + + nested_module = module.add_cpp_namespace('Config') + register_types_ns3_Config(nested_module) + + + ## Register a nested module for the namespace olsr + + nested_module = module.add_cpp_namespace('olsr') + register_types_ns3_olsr(nested_module) + + +def register_types_ns3_internal(module): + root_module = module.get_root() + + +def register_types_ns3_TimeStepPrecision(module): + root_module = module.get_root() + + +def register_types_ns3_Config(module): + root_module = module.get_root() + + +def register_types_ns3_olsr(module): + root_module = module.get_root() + + ## olsr-header.h: ns3::olsr::MessageHeader [class] + module.add_class('MessageHeader', allow_subclassing=True, parent=root_module['ns3::Header']) + ## olsr-header.h: ns3::olsr::MessageHeader::MessageType [enumeration] + module.add_enum('MessageType', ['HELLO_MESSAGE', 'TC_MESSAGE', 'MID_MESSAGE', 'HNA_MESSAGE'], outer_class=root_module['ns3::olsr::MessageHeader']) + ## olsr-header.h: ns3::olsr::MessageHeader::Mid [struct] + module.add_class('Mid', outer_class=root_module['ns3::olsr::MessageHeader']) + ## olsr-header.h: ns3::olsr::MessageHeader::Hello [struct] + module.add_class('Hello', outer_class=root_module['ns3::olsr::MessageHeader']) + ## olsr-header.h: ns3::olsr::MessageHeader::Hello::LinkMessage [struct] + module.add_class('LinkMessage', outer_class=root_module['ns3::olsr::MessageHeader::Hello']) + ## olsr-header.h: ns3::olsr::MessageHeader::Tc [struct] + module.add_class('Tc', outer_class=root_module['ns3::olsr::MessageHeader']) + ## olsr-header.h: ns3::olsr::MessageHeader::Hna [struct] + module.add_class('Hna', outer_class=root_module['ns3::olsr::MessageHeader']) + ## olsr-header.h: ns3::olsr::MessageHeader::Hna::Association [struct] + module.add_class('Association', outer_class=root_module['ns3::olsr::MessageHeader::Hna']) + ## olsr-agent.h: ns3::olsr::Agent [class] + module.add_class('Agent', allow_subclassing=True, parent=root_module['ns3::Object']) + ## olsr-header.h: ns3::olsr::PacketHeader [class] + module.add_class('PacketHeader', allow_subclassing=True, parent=root_module['ns3::Header']) + +def register_methods(root_module): + register_Ns3OlsrMessageHeader_methods(root_module, root_module['ns3::olsr::MessageHeader']) + register_Ns3OlsrMessageHeaderMid_methods(root_module, root_module['ns3::olsr::MessageHeader::Mid']) + register_Ns3OlsrMessageHeaderHello_methods(root_module, root_module['ns3::olsr::MessageHeader::Hello']) + register_Ns3OlsrMessageHeaderHelloLinkMessage_methods(root_module, root_module['ns3::olsr::MessageHeader::Hello::LinkMessage']) + register_Ns3OlsrMessageHeaderTc_methods(root_module, root_module['ns3::olsr::MessageHeader::Tc']) + register_Ns3OlsrMessageHeaderHna_methods(root_module, root_module['ns3::olsr::MessageHeader::Hna']) + register_Ns3OlsrMessageHeaderHnaAssociation_methods(root_module, root_module['ns3::olsr::MessageHeader::Hna::Association']) + register_Ns3OlsrAgent_methods(root_module, root_module['ns3::olsr::Agent']) + register_Ns3OlsrPacketHeader_methods(root_module, root_module['ns3::olsr::PacketHeader']) + return + +def register_Ns3OlsrMessageHeader_methods(root_module, cls): + ## olsr-header.h: ns3::olsr::MessageHeader::MessageHeader(ns3::olsr::MessageHeader const & arg0) [copy constructor] + cls.add_constructor([param('ns3::olsr::MessageHeader&', 'arg0', is_const=True)], visibility='public') + ## olsr-header.h: ns3::olsr::MessageHeader::MessageHeader() [constructor] + cls.add_constructor([], visibility='public') + ## olsr-header.h: uint32_t ns3::olsr::MessageHeader::Deserialize(ns3::Buffer::Iterator start) [member function] + cls.add_method('Deserialize', 'uint32_t', [param('ns3::Buffer::Iterator', 'start')], is_virtual=True) + ## olsr-header.h: ns3::olsr::MessageHeader::Hello & ns3::olsr::MessageHeader::GetHello() [member function] + cls.add_method('GetHello', 'ns3::olsr::MessageHeader::Hello&', []) + ## olsr-header.h: ns3::olsr::MessageHeader::Hello const & ns3::olsr::MessageHeader::GetHello() const [member function] + cls.add_method('GetHello', retval('ns3::olsr::MessageHeader::Hello&', is_const=True), [], is_const=True) + ## olsr-header.h: ns3::olsr::MessageHeader::Hna & ns3::olsr::MessageHeader::GetHna() [member function] + cls.add_method('GetHna', 'ns3::olsr::MessageHeader::Hna&', []) + ## olsr-header.h: ns3::olsr::MessageHeader::Hna const & ns3::olsr::MessageHeader::GetHna() const [member function] + cls.add_method('GetHna', retval('ns3::olsr::MessageHeader::Hna&', is_const=True), [], is_const=True) + ## olsr-header.h: uint8_t ns3::olsr::MessageHeader::GetHopCount() const [member function] + cls.add_method('GetHopCount', 'uint8_t', [], is_const=True) + ## olsr-header.h: ns3::TypeId ns3::olsr::MessageHeader::GetInstanceTypeId() const [member function] + cls.add_method('GetInstanceTypeId', 'ns3::TypeId', [], is_const=True, is_virtual=True) + ## olsr-header.h: uint16_t ns3::olsr::MessageHeader::GetMessageSequenceNumber() const [member function] + cls.add_method('GetMessageSequenceNumber', 'uint16_t', [], is_const=True) + ## olsr-header.h: ns3::olsr::MessageHeader::MessageType ns3::olsr::MessageHeader::GetMessageType() const [member function] + cls.add_method('GetMessageType', 'ns3::olsr::MessageHeader::MessageType', [], is_const=True) + ## olsr-header.h: ns3::olsr::MessageHeader::Mid & ns3::olsr::MessageHeader::GetMid() [member function] + cls.add_method('GetMid', 'ns3::olsr::MessageHeader::Mid&', []) + ## olsr-header.h: ns3::olsr::MessageHeader::Mid const & ns3::olsr::MessageHeader::GetMid() const [member function] + cls.add_method('GetMid', retval('ns3::olsr::MessageHeader::Mid&', is_const=True), [], is_const=True) + ## olsr-header.h: ns3::Ipv4Address ns3::olsr::MessageHeader::GetOriginatorAddress() const [member function] + cls.add_method('GetOriginatorAddress', 'ns3::Ipv4Address', [], is_const=True) + ## olsr-header.h: uint32_t ns3::olsr::MessageHeader::GetSerializedSize() const [member function] + cls.add_method('GetSerializedSize', 'uint32_t', [], is_const=True, is_virtual=True) + ## olsr-header.h: ns3::olsr::MessageHeader::Tc & ns3::olsr::MessageHeader::GetTc() [member function] + cls.add_method('GetTc', 'ns3::olsr::MessageHeader::Tc&', []) + ## olsr-header.h: ns3::olsr::MessageHeader::Tc const & ns3::olsr::MessageHeader::GetTc() const [member function] + cls.add_method('GetTc', retval('ns3::olsr::MessageHeader::Tc&', is_const=True), [], is_const=True) + ## olsr-header.h: uint8_t ns3::olsr::MessageHeader::GetTimeToLive() const [member function] + cls.add_method('GetTimeToLive', 'uint8_t', [], is_const=True) + ## olsr-header.h: static ns3::TypeId ns3::olsr::MessageHeader::GetTypeId() [member function] + cls.add_method('GetTypeId', 'ns3::TypeId', [], is_static=True) + ## olsr-header.h: ns3::Time ns3::olsr::MessageHeader::GetVTime() const [member function] + cls.add_method('GetVTime', 'ns3::Time', [], is_const=True) + ## olsr-header.h: void ns3::olsr::MessageHeader::Print(std::ostream & os) const [member function] + cls.add_method('Print', 'void', [param('std::ostream&', 'os')], is_const=True, is_virtual=True) + ## olsr-header.h: void ns3::olsr::MessageHeader::Serialize(ns3::Buffer::Iterator start) const [member function] + cls.add_method('Serialize', 'void', [param('ns3::Buffer::Iterator', 'start')], is_const=True, is_virtual=True) + ## olsr-header.h: void ns3::olsr::MessageHeader::SetHopCount(uint8_t hopCount) [member function] + cls.add_method('SetHopCount', 'void', [param('uint8_t', 'hopCount')]) + ## olsr-header.h: void ns3::olsr::MessageHeader::SetMessageSequenceNumber(uint16_t messageSequenceNumber) [member function] + cls.add_method('SetMessageSequenceNumber', 'void', [param('uint16_t', 'messageSequenceNumber')]) + ## olsr-header.h: void ns3::olsr::MessageHeader::SetMessageType(ns3::olsr::MessageHeader::MessageType messageType) [member function] + cls.add_method('SetMessageType', 'void', [param('ns3::olsr::MessageHeader::MessageType', 'messageType')]) + ## olsr-header.h: void ns3::olsr::MessageHeader::SetOriginatorAddress(ns3::Ipv4Address originatorAddress) [member function] + cls.add_method('SetOriginatorAddress', 'void', [param('ns3::Ipv4Address', 'originatorAddress')]) + ## olsr-header.h: void ns3::olsr::MessageHeader::SetTimeToLive(uint8_t timeToLive) [member function] + cls.add_method('SetTimeToLive', 'void', [param('uint8_t', 'timeToLive')]) + ## olsr-header.h: void ns3::olsr::MessageHeader::SetVTime(ns3::Time time) [member function] + cls.add_method('SetVTime', 'void', [param('ns3::Time', 'time')]) + cls.add_output_stream_operator() + return + +def register_Ns3OlsrMessageHeaderMid_methods(root_module, cls): + ## olsr-header.h: ns3::olsr::MessageHeader::Mid::Mid(ns3::olsr::MessageHeader::Mid const & arg0) [copy constructor] + cls.add_constructor([param('ns3::olsr::MessageHeader::Mid&', 'arg0', is_const=True)], visibility='public') + ## olsr-header.h: uint32_t ns3::olsr::MessageHeader::Mid::Deserialize(ns3::Buffer::Iterator start, uint32_t messageSize) [member function] + cls.add_method('Deserialize', 'uint32_t', [param('ns3::Buffer::Iterator', 'start'), param('uint32_t', 'messageSize')]) + ## olsr-header.h: uint32_t ns3::olsr::MessageHeader::Mid::GetSerializedSize() const [member function] + cls.add_method('GetSerializedSize', 'uint32_t', [], is_const=True) + ## olsr-header.h: void ns3::olsr::MessageHeader::Mid::Print(std::ostream & os) const [member function] + cls.add_method('Print', 'void', [param('std::ostream&', 'os')], is_const=True) + ## olsr-header.h: void ns3::olsr::MessageHeader::Mid::Serialize(ns3::Buffer::Iterator start) const [member function] + cls.add_method('Serialize', 'void', [param('ns3::Buffer::Iterator', 'start')], is_const=True) + ## olsr-header.h: ns3::olsr::MessageHeader::Mid::interfaceAddresses [variable] + cls.add_instance_attribute('interfaceAddresses', 'std::vector< ns3::Ipv4Address, std::allocator< ns3::Ipv4Address > >', is_const=False) + return + +def register_Ns3OlsrMessageHeaderHello_methods(root_module, cls): + ## olsr-header.h: ns3::olsr::MessageHeader::Hello::Hello(ns3::olsr::MessageHeader::Hello const & arg0) [copy constructor] + cls.add_constructor([param('ns3::olsr::MessageHeader::Hello&', 'arg0', is_const=True)], visibility='public') + ## olsr-header.h: uint32_t ns3::olsr::MessageHeader::Hello::Deserialize(ns3::Buffer::Iterator start, uint32_t messageSize) [member function] + cls.add_method('Deserialize', 'uint32_t', [param('ns3::Buffer::Iterator', 'start'), param('uint32_t', 'messageSize')]) + ## olsr-header.h: ns3::Time ns3::olsr::MessageHeader::Hello::GetHTime() const [member function] + cls.add_method('GetHTime', 'ns3::Time', [], is_const=True) + ## olsr-header.h: uint32_t ns3::olsr::MessageHeader::Hello::GetSerializedSize() const [member function] + cls.add_method('GetSerializedSize', 'uint32_t', [], is_const=True) + ## olsr-header.h: void ns3::olsr::MessageHeader::Hello::Print(std::ostream & os) const [member function] + cls.add_method('Print', 'void', [param('std::ostream&', 'os')], is_const=True) + ## olsr-header.h: void ns3::olsr::MessageHeader::Hello::Serialize(ns3::Buffer::Iterator start) const [member function] + cls.add_method('Serialize', 'void', [param('ns3::Buffer::Iterator', 'start')], is_const=True) + ## olsr-header.h: void ns3::olsr::MessageHeader::Hello::SetHTime(ns3::Time time) [member function] + cls.add_method('SetHTime', 'void', [param('ns3::Time', 'time')]) + ## olsr-header.h: ns3::olsr::MessageHeader::Hello::hTime [variable] + cls.add_instance_attribute('hTime', 'uint8_t', is_const=False) + ## olsr-header.h: ns3::olsr::MessageHeader::Hello::linkMessages [variable] + cls.add_instance_attribute('linkMessages', 'std::vector< ns3::olsr::MessageHeader::Hello::LinkMessage, std::allocator< ns3::olsr::MessageHeader::Hello::LinkMessage > >', is_const=False) + ## olsr-header.h: ns3::olsr::MessageHeader::Hello::willingness [variable] + cls.add_instance_attribute('willingness', 'uint8_t', is_const=False) + return + +def register_Ns3OlsrMessageHeaderHelloLinkMessage_methods(root_module, cls): + ## olsr-header.h: ns3::olsr::MessageHeader::Hello::LinkMessage::linkCode [variable] + cls.add_instance_attribute('linkCode', 'uint8_t', is_const=False) + ## olsr-header.h: ns3::olsr::MessageHeader::Hello::LinkMessage::neighborInterfaceAddresses [variable] + cls.add_instance_attribute('neighborInterfaceAddresses', 'std::vector< ns3::Ipv4Address, std::allocator< ns3::Ipv4Address > >', is_const=False) + cls.add_constructor([]) + return + +def register_Ns3OlsrMessageHeaderTc_methods(root_module, cls): + ## olsr-header.h: ns3::olsr::MessageHeader::Tc::Tc(ns3::olsr::MessageHeader::Tc const & arg0) [copy constructor] + cls.add_constructor([param('ns3::olsr::MessageHeader::Tc&', 'arg0', is_const=True)], visibility='public') + ## olsr-header.h: uint32_t ns3::olsr::MessageHeader::Tc::Deserialize(ns3::Buffer::Iterator start, uint32_t messageSize) [member function] + cls.add_method('Deserialize', 'uint32_t', [param('ns3::Buffer::Iterator', 'start'), param('uint32_t', 'messageSize')]) + ## olsr-header.h: uint32_t ns3::olsr::MessageHeader::Tc::GetSerializedSize() const [member function] + cls.add_method('GetSerializedSize', 'uint32_t', [], is_const=True) + ## olsr-header.h: void ns3::olsr::MessageHeader::Tc::Print(std::ostream & os) const [member function] + cls.add_method('Print', 'void', [param('std::ostream&', 'os')], is_const=True) + ## olsr-header.h: void ns3::olsr::MessageHeader::Tc::Serialize(ns3::Buffer::Iterator start) const [member function] + cls.add_method('Serialize', 'void', [param('ns3::Buffer::Iterator', 'start')], is_const=True) + ## olsr-header.h: ns3::olsr::MessageHeader::Tc::ansn [variable] + cls.add_instance_attribute('ansn', 'uint16_t', is_const=False) + ## olsr-header.h: ns3::olsr::MessageHeader::Tc::neighborAddresses [variable] + cls.add_instance_attribute('neighborAddresses', 'std::vector< ns3::Ipv4Address, std::allocator< ns3::Ipv4Address > >', is_const=False) + return + +def register_Ns3OlsrMessageHeaderHna_methods(root_module, cls): + ## olsr-header.h: ns3::olsr::MessageHeader::Hna::Hna(ns3::olsr::MessageHeader::Hna const & arg0) [copy constructor] + cls.add_constructor([param('ns3::olsr::MessageHeader::Hna&', 'arg0', is_const=True)], visibility='public') + ## olsr-header.h: uint32_t ns3::olsr::MessageHeader::Hna::Deserialize(ns3::Buffer::Iterator start, uint32_t messageSize) [member function] + cls.add_method('Deserialize', 'uint32_t', [param('ns3::Buffer::Iterator', 'start'), param('uint32_t', 'messageSize')]) + ## olsr-header.h: uint32_t ns3::olsr::MessageHeader::Hna::GetSerializedSize() const [member function] + cls.add_method('GetSerializedSize', 'uint32_t', [], is_const=True) + ## olsr-header.h: void ns3::olsr::MessageHeader::Hna::Print(std::ostream & os) const [member function] + cls.add_method('Print', 'void', [param('std::ostream&', 'os')], is_const=True) + ## olsr-header.h: void ns3::olsr::MessageHeader::Hna::Serialize(ns3::Buffer::Iterator start) const [member function] + cls.add_method('Serialize', 'void', [param('ns3::Buffer::Iterator', 'start')], is_const=True) + ## olsr-header.h: ns3::olsr::MessageHeader::Hna::associations [variable] + cls.add_instance_attribute('associations', 'std::vector< ns3::olsr::MessageHeader::Hna::Association, std::allocator< ns3::olsr::MessageHeader::Hna::Association > >', is_const=False) + return + +def register_Ns3OlsrMessageHeaderHnaAssociation_methods(root_module, cls): + ## olsr-header.h: ns3::olsr::MessageHeader::Hna::Association::address [variable] + cls.add_instance_attribute('address', 'ns3::Ipv4Address', is_const=False) + ## olsr-header.h: ns3::olsr::MessageHeader::Hna::Association::mask [variable] + cls.add_instance_attribute('mask', 'ns3::Ipv4Mask', is_const=False) + cls.add_constructor([]) + return + +def register_Ns3OlsrAgent_methods(root_module, cls): + ## olsr-agent.h: static ns3::TypeId ns3::olsr::Agent::GetTypeId() [member function] + cls.add_method('GetTypeId', 'ns3::TypeId', [], is_static=True) + ## olsr-agent.h: void ns3::olsr::Agent::SetNode(ns3::Ptr node) [member function] + cls.add_method('SetNode', 'void', [param('ns3::Ptr< ns3::Node >', 'node')], is_pure_virtual=True, is_virtual=True) + ## olsr-agent.h: void ns3::olsr::Agent::SetMainInterface(uint32_t interface) [member function] + cls.add_method('SetMainInterface', 'void', [param('uint32_t', 'interface')], is_pure_virtual=True, is_virtual=True) + ## olsr-agent.h: void ns3::olsr::Agent::Start() [member function] + cls.add_method('Start', 'void', [], is_pure_virtual=True, is_virtual=True) + cls.add_constructor([]) + return + +def register_Ns3OlsrPacketHeader_methods(root_module, cls): + ## olsr-header.h: ns3::olsr::PacketHeader::PacketHeader(ns3::olsr::PacketHeader const & arg0) [copy constructor] + cls.add_constructor([param('ns3::olsr::PacketHeader&', 'arg0', is_const=True)], visibility='public') + ## olsr-header.h: ns3::olsr::PacketHeader::PacketHeader() [constructor] + cls.add_constructor([], visibility='public') + ## olsr-header.h: uint32_t ns3::olsr::PacketHeader::Deserialize(ns3::Buffer::Iterator start) [member function] + cls.add_method('Deserialize', 'uint32_t', [param('ns3::Buffer::Iterator', 'start')], is_virtual=True) + ## olsr-header.h: ns3::TypeId ns3::olsr::PacketHeader::GetInstanceTypeId() const [member function] + cls.add_method('GetInstanceTypeId', 'ns3::TypeId', [], is_const=True, is_virtual=True) + ## olsr-header.h: uint16_t ns3::olsr::PacketHeader::GetPacketLength() const [member function] + cls.add_method('GetPacketLength', 'uint16_t', [], is_const=True) + ## olsr-header.h: uint16_t ns3::olsr::PacketHeader::GetPacketSequenceNumber() const [member function] + cls.add_method('GetPacketSequenceNumber', 'uint16_t', [], is_const=True) + ## olsr-header.h: uint32_t ns3::olsr::PacketHeader::GetSerializedSize() const [member function] + cls.add_method('GetSerializedSize', 'uint32_t', [], is_const=True, is_virtual=True) + ## olsr-header.h: static ns3::TypeId ns3::olsr::PacketHeader::GetTypeId() [member function] + cls.add_method('GetTypeId', 'ns3::TypeId', [], is_static=True) + ## olsr-header.h: void ns3::olsr::PacketHeader::Print(std::ostream & os) const [member function] + cls.add_method('Print', 'void', [param('std::ostream&', 'os')], is_const=True, is_virtual=True) + ## olsr-header.h: void ns3::olsr::PacketHeader::Serialize(ns3::Buffer::Iterator start) const [member function] + cls.add_method('Serialize', 'void', [param('ns3::Buffer::Iterator', 'start')], is_const=True, is_virtual=True) + ## olsr-header.h: void ns3::olsr::PacketHeader::SetPacketLength(uint16_t length) [member function] + cls.add_method('SetPacketLength', 'void', [param('uint16_t', 'length')]) + ## olsr-header.h: void ns3::olsr::PacketHeader::SetPacketSequenceNumber(uint16_t seqnum) [member function] + cls.add_method('SetPacketSequenceNumber', 'void', [param('uint16_t', 'seqnum')]) + cls.add_output_stream_operator() + return + +def register_functions(root_module): + module = root_module + register_functions_ns3_internal(module.get_submodule('internal'), root_module) + register_functions_ns3_TimeStepPrecision(module.get_submodule('TimeStepPrecision'), root_module) + register_functions_ns3_Config(module.get_submodule('Config'), root_module) + register_functions_ns3_olsr(module.get_submodule('olsr'), root_module) + return + +def register_functions_ns3_internal(module, root_module): + return + +def register_functions_ns3_TimeStepPrecision(module, root_module): + return + +def register_functions_ns3_Config(module, root_module): + return + +def register_functions_ns3_olsr(module, root_module): + ## olsr-header.h: extern double ns3::olsr::EmfToSeconds(uint8_t emf) [free function] + module.add_function('EmfToSeconds', 'double', [param('uint8_t', 'emf')]) + ## olsr-header.h: extern uint8_t ns3::olsr::SecondsToEmf(double seconds) [free function] + module.add_function('SecondsToEmf', 'uint8_t', [param('double', 'seconds')]) + return + diff --git a/bindings/python/ns3_module_onoff.py b/bindings/python/ns3_module_onoff.py new file mode 100644 index 000000000..3bef4f8f3 --- /dev/null +++ b/bindings/python/ns3_module_onoff.py @@ -0,0 +1,87 @@ +from pybindgen import Module, FileCodeSink, write_preamble, param, retval + +def register_types(module): + root_module = module.get_root() + + ## onoff-application.h: ns3::OnOffApplication [class] + module.add_class('OnOffApplication', allow_subclassing=True, parent=root_module['ns3::Application']) + + ## Register a nested module for the namespace internal + + nested_module = module.add_cpp_namespace('internal') + register_types_ns3_internal(nested_module) + + + ## Register a nested module for the namespace TimeStepPrecision + + nested_module = module.add_cpp_namespace('TimeStepPrecision') + register_types_ns3_TimeStepPrecision(nested_module) + + + ## Register a nested module for the namespace Config + + nested_module = module.add_cpp_namespace('Config') + register_types_ns3_Config(nested_module) + + + ## Register a nested module for the namespace olsr + + nested_module = module.add_cpp_namespace('olsr') + register_types_ns3_olsr(nested_module) + + +def register_types_ns3_internal(module): + root_module = module.get_root() + + +def register_types_ns3_TimeStepPrecision(module): + root_module = module.get_root() + + +def register_types_ns3_Config(module): + root_module = module.get_root() + + +def register_types_ns3_olsr(module): + root_module = module.get_root() + + +def register_methods(root_module): + register_Ns3OnOffApplication_methods(root_module, root_module['ns3::OnOffApplication']) + return + +def register_Ns3OnOffApplication_methods(root_module, cls): + ## onoff-application.h: static ns3::TypeId ns3::OnOffApplication::GetTypeId() [member function] + cls.add_method('GetTypeId', 'ns3::TypeId', [], is_static=True) + ## onoff-application.h: ns3::OnOffApplication::OnOffApplication() [constructor] + cls.add_constructor([], visibility='public') + ## onoff-application.h: void ns3::OnOffApplication::SetMaxBytes(uint32_t maxBytes) [member function] + cls.add_method('SetMaxBytes', 'void', [param('uint32_t', 'maxBytes')]) + ## onoff-application.h: void ns3::OnOffApplication::DoDispose() [member function] + cls.add_method('DoDispose', 'void', [], visibility='protected', is_virtual=True) + ## onoff-application.h: void ns3::OnOffApplication::StartApplication() [member function] + cls.add_method('StartApplication', 'void', [], visibility='private', is_virtual=True) + ## onoff-application.h: void ns3::OnOffApplication::StopApplication() [member function] + cls.add_method('StopApplication', 'void', [], visibility='private', is_virtual=True) + return + +def register_functions(root_module): + module = root_module + register_functions_ns3_internal(module.get_submodule('internal'), root_module) + register_functions_ns3_TimeStepPrecision(module.get_submodule('TimeStepPrecision'), root_module) + register_functions_ns3_Config(module.get_submodule('Config'), root_module) + register_functions_ns3_olsr(module.get_submodule('olsr'), root_module) + return + +def register_functions_ns3_internal(module, root_module): + return + +def register_functions_ns3_TimeStepPrecision(module, root_module): + return + +def register_functions_ns3_Config(module, root_module): + return + +def register_functions_ns3_olsr(module, root_module): + return + diff --git a/bindings/python/ns3_module_packet_sink.py b/bindings/python/ns3_module_packet_sink.py new file mode 100644 index 000000000..1f24781aa --- /dev/null +++ b/bindings/python/ns3_module_packet_sink.py @@ -0,0 +1,85 @@ +from pybindgen import Module, FileCodeSink, write_preamble, param, retval + +def register_types(module): + root_module = module.get_root() + + ## packet-sink.h: ns3::PacketSink [class] + module.add_class('PacketSink', allow_subclassing=True, parent=root_module['ns3::Application']) + + ## Register a nested module for the namespace internal + + nested_module = module.add_cpp_namespace('internal') + register_types_ns3_internal(nested_module) + + + ## Register a nested module for the namespace TimeStepPrecision + + nested_module = module.add_cpp_namespace('TimeStepPrecision') + register_types_ns3_TimeStepPrecision(nested_module) + + + ## Register a nested module for the namespace Config + + nested_module = module.add_cpp_namespace('Config') + register_types_ns3_Config(nested_module) + + + ## Register a nested module for the namespace olsr + + nested_module = module.add_cpp_namespace('olsr') + register_types_ns3_olsr(nested_module) + + +def register_types_ns3_internal(module): + root_module = module.get_root() + + +def register_types_ns3_TimeStepPrecision(module): + root_module = module.get_root() + + +def register_types_ns3_Config(module): + root_module = module.get_root() + + +def register_types_ns3_olsr(module): + root_module = module.get_root() + + +def register_methods(root_module): + register_Ns3PacketSink_methods(root_module, root_module['ns3::PacketSink']) + return + +def register_Ns3PacketSink_methods(root_module, cls): + ## packet-sink.h: static ns3::TypeId ns3::PacketSink::GetTypeId() [member function] + cls.add_method('GetTypeId', 'ns3::TypeId', [], is_static=True) + ## packet-sink.h: ns3::PacketSink::PacketSink() [constructor] + cls.add_constructor([], visibility='public') + ## packet-sink.h: void ns3::PacketSink::DoDispose() [member function] + cls.add_method('DoDispose', 'void', [], visibility='protected', is_virtual=True) + ## packet-sink.h: void ns3::PacketSink::StartApplication() [member function] + cls.add_method('StartApplication', 'void', [], visibility='private', is_virtual=True) + ## packet-sink.h: void ns3::PacketSink::StopApplication() [member function] + cls.add_method('StopApplication', 'void', [], visibility='private', is_virtual=True) + return + +def register_functions(root_module): + module = root_module + register_functions_ns3_internal(module.get_submodule('internal'), root_module) + register_functions_ns3_TimeStepPrecision(module.get_submodule('TimeStepPrecision'), root_module) + register_functions_ns3_Config(module.get_submodule('Config'), root_module) + register_functions_ns3_olsr(module.get_submodule('olsr'), root_module) + return + +def register_functions_ns3_internal(module, root_module): + return + +def register_functions_ns3_TimeStepPrecision(module, root_module): + return + +def register_functions_ns3_Config(module, root_module): + return + +def register_functions_ns3_olsr(module, root_module): + return + diff --git a/bindings/python/ns3_module_point_to_point.py b/bindings/python/ns3_module_point_to_point.py new file mode 100644 index 000000000..1cb6892e9 --- /dev/null +++ b/bindings/python/ns3_module_point_to_point.py @@ -0,0 +1,157 @@ +from pybindgen import Module, FileCodeSink, write_preamble, param, retval + +def register_types(module): + root_module = module.get_root() + + ## point-to-point-channel.h: ns3::PointToPointChannel [class] + module.add_class('PointToPointChannel', allow_subclassing=True, parent=root_module['ns3::Channel']) + ## point-to-point-net-device.h: ns3::PointToPointNetDevice [class] + module.add_class('PointToPointNetDevice', allow_subclassing=True, parent=root_module['ns3::NetDevice']) + + ## Register a nested module for the namespace internal + + nested_module = module.add_cpp_namespace('internal') + register_types_ns3_internal(nested_module) + + + ## Register a nested module for the namespace TimeStepPrecision + + nested_module = module.add_cpp_namespace('TimeStepPrecision') + register_types_ns3_TimeStepPrecision(nested_module) + + + ## Register a nested module for the namespace Config + + nested_module = module.add_cpp_namespace('Config') + register_types_ns3_Config(nested_module) + + + ## Register a nested module for the namespace olsr + + nested_module = module.add_cpp_namespace('olsr') + register_types_ns3_olsr(nested_module) + + +def register_types_ns3_internal(module): + root_module = module.get_root() + + +def register_types_ns3_TimeStepPrecision(module): + root_module = module.get_root() + + +def register_types_ns3_Config(module): + root_module = module.get_root() + + +def register_types_ns3_olsr(module): + root_module = module.get_root() + + +def register_methods(root_module): + register_Ns3PointToPointChannel_methods(root_module, root_module['ns3::PointToPointChannel']) + register_Ns3PointToPointNetDevice_methods(root_module, root_module['ns3::PointToPointNetDevice']) + return + +def register_Ns3PointToPointChannel_methods(root_module, cls): + ## point-to-point-channel.h: static ns3::TypeId ns3::PointToPointChannel::GetTypeId() [member function] + cls.add_method('GetTypeId', 'ns3::TypeId', [], is_static=True) + ## point-to-point-channel.h: ns3::PointToPointChannel::PointToPointChannel() [constructor] + cls.add_constructor([], visibility='public') + ## point-to-point-channel.h: void ns3::PointToPointChannel::Attach(ns3::Ptr device) [member function] + cls.add_method('Attach', 'void', [param('ns3::Ptr< ns3::PointToPointNetDevice >', 'device')]) + ## point-to-point-channel.h: bool ns3::PointToPointChannel::TransmitStart(ns3::Ptr p, ns3::Ptr src, ns3::Time txTime) [member function] + cls.add_method('TransmitStart', 'bool', [param('ns3::Ptr< ns3::Packet >', 'p'), param('ns3::Ptr< ns3::PointToPointNetDevice >', 'src'), param('ns3::Time', 'txTime')]) + ## point-to-point-channel.h: uint32_t ns3::PointToPointChannel::GetNDevices() const [member function] + cls.add_method('GetNDevices', 'uint32_t', [], is_const=True, is_virtual=True) + ## point-to-point-channel.h: ns3::Ptr ns3::PointToPointChannel::GetPointToPointDevice(uint32_t i) const [member function] + cls.add_method('GetPointToPointDevice', 'ns3::Ptr< ns3::PointToPointNetDevice >', [param('uint32_t', 'i')], is_const=True) + ## point-to-point-channel.h: ns3::Ptr ns3::PointToPointChannel::GetDevice(uint32_t i) const [member function] + cls.add_method('GetDevice', 'ns3::Ptr< ns3::NetDevice >', [param('uint32_t', 'i')], is_const=True, is_virtual=True) + return + +def register_Ns3PointToPointNetDevice_methods(root_module, cls): + ## point-to-point-net-device.h: static ns3::TypeId ns3::PointToPointNetDevice::GetTypeId() [member function] + cls.add_method('GetTypeId', 'ns3::TypeId', [], is_static=True) + ## point-to-point-net-device.h: ns3::PointToPointNetDevice::PointToPointNetDevice() [constructor] + cls.add_constructor([], visibility='public') + ## point-to-point-net-device.h: void ns3::PointToPointNetDevice::SetDataRate(ns3::DataRate bps) [member function] + cls.add_method('SetDataRate', 'void', [param('ns3::DataRate', 'bps')]) + ## point-to-point-net-device.h: void ns3::PointToPointNetDevice::SetInterframeGap(ns3::Time t) [member function] + cls.add_method('SetInterframeGap', 'void', [param('ns3::Time', 't')]) + ## point-to-point-net-device.h: bool ns3::PointToPointNetDevice::Attach(ns3::Ptr ch) [member function] + cls.add_method('Attach', 'bool', [param('ns3::Ptr< ns3::PointToPointChannel >', 'ch')]) + ## point-to-point-net-device.h: void ns3::PointToPointNetDevice::SetQueue(ns3::Ptr queue) [member function] + cls.add_method('SetQueue', 'void', [param('ns3::Ptr< ns3::Queue >', 'queue')]) + ## point-to-point-net-device.h: void ns3::PointToPointNetDevice::SetReceiveErrorModel(ns3::Ptr em) [member function] + cls.add_method('SetReceiveErrorModel', 'void', [param('ns3::Ptr< ns3::ErrorModel >', 'em')]) + ## point-to-point-net-device.h: void ns3::PointToPointNetDevice::Receive(ns3::Ptr p) [member function] + cls.add_method('Receive', 'void', [param('ns3::Ptr< ns3::Packet >', 'p')]) + ## point-to-point-net-device.h: void ns3::PointToPointNetDevice::SetAddress(ns3::Mac48Address addr) [member function] + cls.add_method('SetAddress', 'void', [param('ns3::Mac48Address', 'addr')]) + ## point-to-point-net-device.h: void ns3::PointToPointNetDevice::SetName(std::string const name) [member function] + cls.add_method('SetName', 'void', [param('std::string', 'name', is_const=True)], is_virtual=True) + ## point-to-point-net-device.h: std::string ns3::PointToPointNetDevice::GetName() const [member function] + cls.add_method('GetName', 'std::string', [], is_const=True, is_virtual=True) + ## point-to-point-net-device.h: void ns3::PointToPointNetDevice::SetIfIndex(uint32_t const index) [member function] + cls.add_method('SetIfIndex', 'void', [param('uint32_t', 'index', is_const=True)], is_virtual=True) + ## point-to-point-net-device.h: uint32_t ns3::PointToPointNetDevice::GetIfIndex() const [member function] + cls.add_method('GetIfIndex', 'uint32_t', [], is_const=True, is_virtual=True) + ## point-to-point-net-device.h: ns3::Ptr ns3::PointToPointNetDevice::GetChannel() const [member function] + cls.add_method('GetChannel', 'ns3::Ptr< ns3::Channel >', [], is_const=True, is_virtual=True) + ## point-to-point-net-device.h: ns3::Address ns3::PointToPointNetDevice::GetAddress() const [member function] + cls.add_method('GetAddress', 'ns3::Address', [], is_const=True, is_virtual=True) + ## point-to-point-net-device.h: bool ns3::PointToPointNetDevice::SetMtu(uint16_t const mtu) [member function] + cls.add_method('SetMtu', 'bool', [param('uint16_t', 'mtu', is_const=True)], is_virtual=True) + ## point-to-point-net-device.h: uint16_t ns3::PointToPointNetDevice::GetMtu() const [member function] + cls.add_method('GetMtu', 'uint16_t', [], is_const=True, is_virtual=True) + ## point-to-point-net-device.h: bool ns3::PointToPointNetDevice::IsLinkUp() const [member function] + cls.add_method('IsLinkUp', 'bool', [], is_const=True, is_virtual=True) + ## point-to-point-net-device.h: void ns3::PointToPointNetDevice::SetLinkChangeCallback(ns3::Callback callback) [member function] + cls.add_method('SetLinkChangeCallback', 'void', [param('ns3::Callback< void, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty >', 'callback')], is_virtual=True) + ## point-to-point-net-device.h: bool ns3::PointToPointNetDevice::IsBroadcast() const [member function] + cls.add_method('IsBroadcast', 'bool', [], is_const=True, is_virtual=True) + ## point-to-point-net-device.h: ns3::Address ns3::PointToPointNetDevice::GetBroadcast() const [member function] + cls.add_method('GetBroadcast', 'ns3::Address', [], is_const=True, is_virtual=True) + ## point-to-point-net-device.h: bool ns3::PointToPointNetDevice::IsMulticast() const [member function] + cls.add_method('IsMulticast', 'bool', [], is_const=True, is_virtual=True) + ## point-to-point-net-device.h: ns3::Address ns3::PointToPointNetDevice::GetMulticast() const [member function] + cls.add_method('GetMulticast', 'ns3::Address', [], is_const=True, is_virtual=True) + ## point-to-point-net-device.h: ns3::Address ns3::PointToPointNetDevice::MakeMulticastAddress(ns3::Ipv4Address multicastGroup) const [member function] + cls.add_method('MakeMulticastAddress', 'ns3::Address', [param('ns3::Ipv4Address', 'multicastGroup')], is_const=True, is_virtual=True) + ## point-to-point-net-device.h: bool ns3::PointToPointNetDevice::IsPointToPoint() const [member function] + cls.add_method('IsPointToPoint', 'bool', [], is_const=True, is_virtual=True) + ## point-to-point-net-device.h: bool ns3::PointToPointNetDevice::Send(ns3::Ptr packet, ns3::Address const & dest, uint16_t protocolNumber) [member function] + cls.add_method('Send', 'bool', [param('ns3::Ptr< ns3::Packet >', 'packet'), param('ns3::Address&', 'dest', is_const=True), param('uint16_t', 'protocolNumber')], is_virtual=True) + ## point-to-point-net-device.h: ns3::Ptr ns3::PointToPointNetDevice::GetNode() const [member function] + cls.add_method('GetNode', 'ns3::Ptr< ns3::Node >', [], is_const=True, is_virtual=True) + ## point-to-point-net-device.h: void ns3::PointToPointNetDevice::SetNode(ns3::Ptr node) [member function] + cls.add_method('SetNode', 'void', [param('ns3::Ptr< ns3::Node >', 'node')], is_virtual=True) + ## point-to-point-net-device.h: bool ns3::PointToPointNetDevice::NeedsArp() const [member function] + cls.add_method('NeedsArp', 'bool', [], is_const=True, is_virtual=True) + ## point-to-point-net-device.h: void ns3::PointToPointNetDevice::SetReceiveCallback(ns3::Callback, ns3::Ptr, unsigned short, ns3::Address const&, ns3::empty, ns3::empty> cb) [member function] + cls.add_method('SetReceiveCallback', 'void', [param('ns3::Callback< bool, ns3::Ptr< ns3::NetDevice >, ns3::Ptr< ns3::Packet >, unsigned short, ns3::Address const&, ns3::empty, ns3::empty >', 'cb')], is_virtual=True) + ## point-to-point-net-device.h: void ns3::PointToPointNetDevice::DoDispose() [member function] + cls.add_method('DoDispose', 'void', [], visibility='private', is_virtual=True) + return + +def register_functions(root_module): + module = root_module + register_functions_ns3_internal(module.get_submodule('internal'), root_module) + register_functions_ns3_TimeStepPrecision(module.get_submodule('TimeStepPrecision'), root_module) + register_functions_ns3_Config(module.get_submodule('Config'), root_module) + register_functions_ns3_olsr(module.get_submodule('olsr'), root_module) + return + +def register_functions_ns3_internal(module, root_module): + return + +def register_functions_ns3_TimeStepPrecision(module, root_module): + return + +def register_functions_ns3_Config(module, root_module): + return + +def register_functions_ns3_olsr(module, root_module): + return + diff --git a/bindings/python/ns3_module_simulator.py b/bindings/python/ns3_module_simulator.py new file mode 100644 index 000000000..c06e3b783 --- /dev/null +++ b/bindings/python/ns3_module_simulator.py @@ -0,0 +1,456 @@ +from pybindgen import Module, FileCodeSink, write_preamble, param, retval + +def register_types(module): + root_module = module.get_root() + + ## timer.h: ns3::Timer [class] + module.add_class('Timer') + ## timer.h: ns3::Timer::DestroyPolicy [enumeration] + module.add_enum('DestroyPolicy', ['CANCEL_ON_DESTROY', 'REMOVE_ON_DESTROY', 'CHECK_ON_DESTROY'], outer_class=root_module['ns3::Timer']) + ## timer.h: ns3::Timer::State [enumeration] + module.add_enum('State', ['RUNNING', 'EXPIRED', 'SUSPENDED'], outer_class=root_module['ns3::Timer']) + ## timer-impl.h: ns3::TimerImpl [class] + module.add_class('TimerImpl', allow_subclassing=True) + ## nstime.h: ns3::TimeUnit<1> [class] + module.add_class('Time') + ## nstime.h: ns3::TimeUnit<0> [class] + module.add_class('Scalar') + ## watchdog.h: ns3::Watchdog [class] + module.add_class('Watchdog') + ## simulator.h: ns3::Simulator [class] + module.add_class('Simulator', is_singleton=True) + ## event-id.h: ns3::EventId [class] + module.add_class('EventId') + ## event-impl.h: ns3::EventImpl [class] + module.add_class('EventImpl', allow_subclassing=True) + ## high-precision-128.h: ns3::HighPrecision [class] + module.add_class('HighPrecision') + ## nstime.h: ns3::TimeChecker [class] + module.add_class('TimeChecker', parent=root_module['ns3::AttributeChecker']) + ## scheduler.h: ns3::Scheduler [class] + module.add_class('Scheduler', allow_subclassing=True, parent=root_module['ns3::Object']) + ## scheduler.h: ns3::Scheduler::EventKey [struct] + module.add_class('EventKey', outer_class=root_module['ns3::Scheduler']) + ## nstime.h: ns3::TimeValue [class] + module.add_class('TimeValue', allow_subclassing=True, parent=root_module['ns3::AttributeValue']) + ## heap-scheduler.h: ns3::HeapScheduler [class] + module.add_class('HeapScheduler', allow_subclassing=True, parent=root_module['ns3::Scheduler']) + ## list-scheduler.h: ns3::ListScheduler [class] + module.add_class('ListScheduler', allow_subclassing=True, parent=root_module['ns3::Scheduler']) + ## map-scheduler.h: ns3::MapScheduler [class] + module.add_class('MapScheduler', allow_subclassing=True, parent=root_module['ns3::Scheduler']) + + ## Register a nested module for the namespace internal + + nested_module = module.add_cpp_namespace('internal') + register_types_ns3_internal(nested_module) + + + ## Register a nested module for the namespace TimeStepPrecision + + nested_module = module.add_cpp_namespace('TimeStepPrecision') + register_types_ns3_TimeStepPrecision(nested_module) + + + ## Register a nested module for the namespace Config + + nested_module = module.add_cpp_namespace('Config') + register_types_ns3_Config(nested_module) + + + ## Register a nested module for the namespace olsr + + nested_module = module.add_cpp_namespace('olsr') + register_types_ns3_olsr(nested_module) + + +def register_types_ns3_internal(module): + root_module = module.get_root() + + +def register_types_ns3_TimeStepPrecision(module): + root_module = module.get_root() + + ## nstime.h: ns3::TimeStepPrecision::precision_t [enumeration] + module.add_enum('precision_t', ['S', 'MS', 'US', 'NS', 'PS', 'FS']) + +def register_types_ns3_Config(module): + root_module = module.get_root() + + +def register_types_ns3_olsr(module): + root_module = module.get_root() + + +def register_methods(root_module): + register_Ns3Timer_methods(root_module, root_module['ns3::Timer']) + register_Ns3TimerImpl_methods(root_module, root_module['ns3::TimerImpl']) + register_Ns3Time_methods(root_module, root_module['ns3::Time']) + register_Ns3Scalar_methods(root_module, root_module['ns3::Scalar']) + register_Ns3Watchdog_methods(root_module, root_module['ns3::Watchdog']) + register_Ns3Simulator_methods(root_module, root_module['ns3::Simulator']) + register_Ns3EventId_methods(root_module, root_module['ns3::EventId']) + register_Ns3EventImpl_methods(root_module, root_module['ns3::EventImpl']) + register_Ns3HighPrecision_methods(root_module, root_module['ns3::HighPrecision']) + register_Ns3TimeChecker_methods(root_module, root_module['ns3::TimeChecker']) + register_Ns3Scheduler_methods(root_module, root_module['ns3::Scheduler']) + register_Ns3SchedulerEventKey_methods(root_module, root_module['ns3::Scheduler::EventKey']) + register_Ns3TimeValue_methods(root_module, root_module['ns3::TimeValue']) + register_Ns3HeapScheduler_methods(root_module, root_module['ns3::HeapScheduler']) + register_Ns3ListScheduler_methods(root_module, root_module['ns3::ListScheduler']) + register_Ns3MapScheduler_methods(root_module, root_module['ns3::MapScheduler']) + return + +def register_Ns3Timer_methods(root_module, cls): + ## timer.h: ns3::Timer::Timer() [constructor] + cls.add_constructor([], visibility='public') + ## timer.h: ns3::Timer::Timer(ns3::Timer::DestroyPolicy destroyPolicy) [constructor] + cls.add_constructor([param('ns3::Timer::DestroyPolicy', 'destroyPolicy')], visibility='public') + ## timer.h: void ns3::Timer::SetDelay(ns3::Time const & delay) [member function] + cls.add_method('SetDelay', 'void', [param('ns3::Time&', 'delay', is_const=True)]) + ## timer.h: ns3::Time ns3::Timer::GetDelay() const [member function] + cls.add_method('GetDelay', 'ns3::Time', [], is_const=True) + ## timer.h: ns3::Time ns3::Timer::GetDelayLeft() const [member function] + cls.add_method('GetDelayLeft', 'ns3::Time', [], is_const=True) + ## timer.h: void ns3::Timer::Cancel() [member function] + cls.add_method('Cancel', 'void', []) + ## timer.h: void ns3::Timer::Remove() [member function] + cls.add_method('Remove', 'void', []) + ## timer.h: bool ns3::Timer::IsExpired() const [member function] + cls.add_method('IsExpired', 'bool', [], is_const=True) + ## timer.h: bool ns3::Timer::IsRunning() const [member function] + cls.add_method('IsRunning', 'bool', [], is_const=True) + ## timer.h: bool ns3::Timer::IsSuspended() const [member function] + cls.add_method('IsSuspended', 'bool', [], is_const=True) + ## timer.h: ns3::Timer::State ns3::Timer::GetState() const [member function] + cls.add_method('GetState', 'ns3::Timer::State', [], is_const=True) + ## timer.h: void ns3::Timer::Schedule() [member function] + cls.add_method('Schedule', 'void', []) + ## timer.h: void ns3::Timer::Schedule(ns3::Time delay) [member function] + cls.add_method('Schedule', 'void', [param('ns3::Time', 'delay')]) + ## timer.h: void ns3::Timer::Suspend() [member function] + cls.add_method('Suspend', 'void', []) + ## timer.h: void ns3::Timer::Resume() [member function] + cls.add_method('Resume', 'void', []) + return + +def register_Ns3TimerImpl_methods(root_module, cls): + ## timer-impl.h: ns3::EventId ns3::TimerImpl::Schedule(ns3::Time const & delay) [member function] + cls.add_method('Schedule', 'ns3::EventId', [param('ns3::Time&', 'delay', is_const=True)], is_pure_virtual=True, is_virtual=True) + ## timer-impl.h: void ns3::TimerImpl::Invoke() [member function] + cls.add_method('Invoke', 'void', [], is_pure_virtual=True, is_virtual=True) + cls.add_constructor([]) + return + +def register_Ns3Time_methods(root_module, cls): + ## nstime.h: ns3::TimeUnit<1>::TimeUnit(std::string const & s) [constructor] + cls.add_constructor([param('std::string&', 's', is_const=True)], visibility='public') + ## nstime.h: ns3::TimeUnit<1>::TimeUnit() [constructor] + cls.add_constructor([], visibility='public') + ## nstime.h: ns3::TimeUnit<1>::TimeUnit(ns3::TimeUnit<1> const & o) [copy constructor] + cls.add_constructor([param('ns3::Time&', 'o', is_const=True)], visibility='public') + ## nstime.h: ns3::TimeUnit<1>::TimeUnit(ns3::HighPrecision data) [constructor] + cls.add_constructor([param('ns3::HighPrecision', 'data')], visibility='public') + ## nstime.h: int64_t ns3::TimeUnit<1>::GetFemtoSeconds() const [member function] + cls.add_method('GetFemtoSeconds', 'int64_t', [], is_const=True) + ## nstime.h: ns3::HighPrecision const & ns3::TimeUnit<1>::GetHighPrecision() const [member function] + cls.add_method('GetHighPrecision', retval('ns3::HighPrecision&', is_const=True), [], is_const=True) + ## nstime.h: int64_t ns3::TimeUnit<1>::GetMicroSeconds() const [member function] + cls.add_method('GetMicroSeconds', 'int64_t', [], is_const=True) + ## nstime.h: int64_t ns3::TimeUnit<1>::GetMilliSeconds() const [member function] + cls.add_method('GetMilliSeconds', 'int64_t', [], is_const=True) + ## nstime.h: int64_t ns3::TimeUnit<1>::GetNanoSeconds() const [member function] + cls.add_method('GetNanoSeconds', 'int64_t', [], is_const=True) + ## nstime.h: int64_t ns3::TimeUnit<1>::GetPicoSeconds() const [member function] + cls.add_method('GetPicoSeconds', 'int64_t', [], is_const=True) + ## nstime.h: double ns3::TimeUnit<1>::GetSeconds() const [member function] + cls.add_method('GetSeconds', 'double', [], is_const=True) + ## nstime.h: int64_t ns3::TimeUnit<1>::GetTimeStep() const [member function] + cls.add_method('GetTimeStep', 'int64_t', [], is_const=True) + ## nstime.h: bool ns3::TimeUnit<1>::IsNegative() const [member function] + cls.add_method('IsNegative', 'bool', [], is_const=True) + ## nstime.h: bool ns3::TimeUnit<1>::IsPositive() const [member function] + cls.add_method('IsPositive', 'bool', [], is_const=True) + ## nstime.h: bool ns3::TimeUnit<1>::IsStrictlyNegative() const [member function] + cls.add_method('IsStrictlyNegative', 'bool', [], is_const=True) + ## nstime.h: bool ns3::TimeUnit<1>::IsStrictlyPositive() const [member function] + cls.add_method('IsStrictlyPositive', 'bool', [], is_const=True) + ## nstime.h: bool ns3::TimeUnit<1>::IsZero() const [member function] + cls.add_method('IsZero', 'bool', [], is_const=True) + ## nstime.h: ns3::HighPrecision * ns3::TimeUnit<1>::PeekHighPrecision() [member function] + cls.add_method('PeekHighPrecision', 'ns3::HighPrecision *', []) + ## nstime.h: static uint64_t ns3::TimeUnit<1>::UnitsToTimestep(uint64_t unitValue, uint64_t unitFactor) [member function] + cls.add_method('UnitsToTimestep', 'uint64_t', [param('uint64_t', 'unitValue'), param('uint64_t', 'unitFactor')], is_static=True) + cls.add_output_stream_operator() + return + +def register_Ns3Scalar_methods(root_module, cls): + ## nstime.h: ns3::TimeUnit<0>::TimeUnit(double scalar) [constructor] + cls.add_constructor([param('double', 'scalar')], visibility='public') + ## nstime.h: ns3::TimeUnit<0>::TimeUnit() [constructor] + cls.add_constructor([], visibility='public') + ## nstime.h: ns3::TimeUnit<0>::TimeUnit(ns3::TimeUnit<0> const & o) [copy constructor] + cls.add_constructor([param('ns3::Scalar&', 'o', is_const=True)], visibility='public') + ## nstime.h: ns3::TimeUnit<0>::TimeUnit(ns3::HighPrecision data) [constructor] + cls.add_constructor([param('ns3::HighPrecision', 'data')], visibility='public') + ## nstime.h: double ns3::TimeUnit<0>::GetDouble() const [member function] + cls.add_method('GetDouble', 'double', [], is_const=True) + ## nstime.h: ns3::HighPrecision const & ns3::TimeUnit<0>::GetHighPrecision() const [member function] + cls.add_method('GetHighPrecision', retval('ns3::HighPrecision&', is_const=True), [], is_const=True) + ## nstime.h: bool ns3::TimeUnit<0>::IsNegative() const [member function] + cls.add_method('IsNegative', 'bool', [], is_const=True) + ## nstime.h: bool ns3::TimeUnit<0>::IsPositive() const [member function] + cls.add_method('IsPositive', 'bool', [], is_const=True) + ## nstime.h: bool ns3::TimeUnit<0>::IsStrictlyNegative() const [member function] + cls.add_method('IsStrictlyNegative', 'bool', [], is_const=True) + ## nstime.h: bool ns3::TimeUnit<0>::IsStrictlyPositive() const [member function] + cls.add_method('IsStrictlyPositive', 'bool', [], is_const=True) + ## nstime.h: bool ns3::TimeUnit<0>::IsZero() const [member function] + cls.add_method('IsZero', 'bool', [], is_const=True) + ## nstime.h: ns3::HighPrecision * ns3::TimeUnit<0>::PeekHighPrecision() [member function] + cls.add_method('PeekHighPrecision', 'ns3::HighPrecision *', []) + return + +def register_Ns3Watchdog_methods(root_module, cls): + ## watchdog.h: ns3::Watchdog::Watchdog() [constructor] + cls.add_constructor([], visibility='public') + ## watchdog.h: void ns3::Watchdog::Ping(ns3::Time delay) [member function] + cls.add_method('Ping', 'void', [param('ns3::Time', 'delay')]) + return + +def register_Ns3Simulator_methods(root_module, cls): + ## simulator.h: static void ns3::Simulator::SetScheduler(ns3::Ptr scheduler) [member function] + cls.add_method('SetScheduler', 'void', [param('ns3::Ptr< ns3::Scheduler >', 'scheduler')], is_static=True) + ## simulator.h: static void ns3::Simulator::EnableLogTo(char const * filename) [member function] + cls.add_method('EnableLogTo', 'void', [param('char *', 'filename', transfer_ownership=False, is_const=True)], is_static=True) + ## simulator.h: static void ns3::Simulator::Destroy() [member function] + cls.add_method('Destroy', 'void', [], is_static=True) + ## simulator.h: static bool ns3::Simulator::IsFinished() [member function] + cls.add_method('IsFinished', 'bool', [], is_static=True) + ## simulator.h: static ns3::Time ns3::Simulator::Next() [member function] + cls.add_method('Next', 'ns3::Time', [], is_static=True) + ## simulator.h: static void ns3::Simulator::Run() [member function] + cls.add_method('Run', 'void', [], is_static=True) + ## simulator.h: static void ns3::Simulator::Stop() [member function] + cls.add_method('Stop', 'void', [], is_static=True) + ## simulator.h: static void ns3::Simulator::Stop(ns3::Time const & time) [member function] + cls.add_method('Stop', 'void', [param('ns3::Time&', 'time', is_const=True)], is_static=True) + ## simulator.h: static void ns3::Simulator::Remove(ns3::EventId const & id) [member function] + cls.add_method('Remove', 'void', [param('ns3::EventId&', 'id', is_const=True)], is_static=True) + ## simulator.h: static void ns3::Simulator::Cancel(ns3::EventId const & id) [member function] + cls.add_method('Cancel', 'void', [param('ns3::EventId&', 'id', is_const=True)], is_static=True) + ## simulator.h: static bool ns3::Simulator::IsExpired(ns3::EventId const & id) [member function] + cls.add_method('IsExpired', 'bool', [param('ns3::EventId&', 'id', is_const=True)], is_static=True) + ## simulator.h: static ns3::Time ns3::Simulator::Now() [member function] + cls.add_method('Now', 'ns3::Time', [], is_static=True) + ## simulator.h: static ns3::Time ns3::Simulator::GetDelayLeft(ns3::EventId const & id) [member function] + cls.add_method('GetDelayLeft', 'ns3::Time', [param('ns3::EventId&', 'id', is_const=True)], is_static=True) + ## simulator.h: static ns3::Time ns3::Simulator::GetMaximumSimulationTime() [member function] + cls.add_method('GetMaximumSimulationTime', 'ns3::Time', [], is_static=True) + return + +def register_Ns3EventId_methods(root_module, cls): + ## event-id.h: ns3::EventId::EventId(ns3::EventId const & arg0) [copy constructor] + cls.add_constructor([param('ns3::EventId&', 'arg0', is_const=True)], visibility='public') + ## event-id.h: ns3::EventId::EventId() [constructor] + cls.add_constructor([], visibility='public') + ## event-id.h: ns3::EventId::EventId(ns3::Ptr const & impl, uint64_t ts, uint32_t uid) [constructor] + cls.add_constructor([param('ns3::Ptr< ns3::EventImpl >&', 'impl', is_const=True), param('uint64_t', 'ts'), param('uint32_t', 'uid')], visibility='public') + ## event-id.h: void ns3::EventId::Cancel() [member function] + cls.add_method('Cancel', 'void', []) + ## event-id.h: bool ns3::EventId::IsExpired() const [member function] + cls.add_method('IsExpired', 'bool', [], is_const=True) + ## event-id.h: bool ns3::EventId::IsRunning() const [member function] + cls.add_method('IsRunning', 'bool', [], is_const=True) + ## event-id.h: ns3::EventImpl * ns3::EventId::PeekEventImpl() const [member function] + cls.add_method('PeekEventImpl', 'ns3::EventImpl *', [], is_const=True) + ## event-id.h: uint64_t ns3::EventId::GetTs() const [member function] + cls.add_method('GetTs', 'uint64_t', [], is_const=True) + ## event-id.h: uint32_t ns3::EventId::GetUid() const [member function] + cls.add_method('GetUid', 'uint32_t', [], is_const=True) + return + +def register_Ns3EventImpl_methods(root_module, cls): + ## event-impl.h: ns3::EventImpl::EventImpl() [constructor] + cls.add_constructor([], visibility='public') + ## event-impl.h: void ns3::EventImpl::Ref() const [member function] + cls.add_method('Ref', 'void', [], is_const=True) + ## event-impl.h: void ns3::EventImpl::Unref() const [member function] + cls.add_method('Unref', 'void', [], is_const=True) + ## event-impl.h: void ns3::EventImpl::Invoke() [member function] + cls.add_method('Invoke', 'void', []) + ## event-impl.h: void ns3::EventImpl::Cancel() [member function] + cls.add_method('Cancel', 'void', []) + ## event-impl.h: bool ns3::EventImpl::IsCancelled() [member function] + cls.add_method('IsCancelled', 'bool', []) + ## event-impl.h: void ns3::EventImpl::Notify() [member function] + cls.add_method('Notify', 'void', [], is_pure_virtual=True, visibility='protected', is_virtual=True) + return + +def register_Ns3HighPrecision_methods(root_module, cls): + ## high-precision-128.h: ns3::HighPrecision::HighPrecision(ns3::HighPrecision const & arg0) [copy constructor] + cls.add_constructor([param('ns3::HighPrecision&', 'arg0', is_const=True)], visibility='public') + ## high-precision-128.h: ns3::HighPrecision::HighPrecision() [constructor] + cls.add_constructor([], visibility='public') + ## high-precision-128.h: ns3::HighPrecision::HighPrecision(int64_t value, bool dummy) [constructor] + cls.add_constructor([param('int64_t', 'value'), param('bool', 'dummy')], visibility='public') + ## high-precision-128.h: ns3::HighPrecision::HighPrecision(double value) [constructor] + cls.add_constructor([param('double', 'value')], visibility='public') + ## high-precision-128.h: static void ns3::HighPrecision::PrintStats() [member function] + cls.add_method('PrintStats', 'void', [], is_static=True) + ## high-precision-128.h: int64_t ns3::HighPrecision::GetInteger() const [member function] + cls.add_method('GetInteger', 'int64_t', [], is_const=True) + ## high-precision-128.h: double ns3::HighPrecision::GetDouble() const [member function] + cls.add_method('GetDouble', 'double', [], is_const=True) + ## high-precision-128.h: bool ns3::HighPrecision::Add(ns3::HighPrecision const & o) [member function] + cls.add_method('Add', 'bool', [param('ns3::HighPrecision&', 'o', is_const=True)]) + ## high-precision-128.h: bool ns3::HighPrecision::Sub(ns3::HighPrecision const & o) [member function] + cls.add_method('Sub', 'bool', [param('ns3::HighPrecision&', 'o', is_const=True)]) + ## high-precision-128.h: bool ns3::HighPrecision::Mul(ns3::HighPrecision const & o) [member function] + cls.add_method('Mul', 'bool', [param('ns3::HighPrecision&', 'o', is_const=True)]) + ## high-precision-128.h: bool ns3::HighPrecision::Div(ns3::HighPrecision const & o) [member function] + cls.add_method('Div', 'bool', [param('ns3::HighPrecision&', 'o', is_const=True)]) + ## high-precision-128.h: int ns3::HighPrecision::Compare(ns3::HighPrecision const & o) const [member function] + cls.add_method('Compare', 'int', [param('ns3::HighPrecision&', 'o', is_const=True)], is_const=True) + ## high-precision-128.h: static ns3::HighPrecision ns3::HighPrecision::Zero() [member function] + cls.add_method('Zero', 'ns3::HighPrecision', [], is_static=True) + return + +def register_Ns3TimeChecker_methods(root_module, cls): + cls.add_constructor([]) + return + +def register_Ns3Scheduler_methods(root_module, cls): + ## scheduler.h: static ns3::TypeId ns3::Scheduler::GetTypeId() [member function] + cls.add_method('GetTypeId', 'ns3::TypeId', [], is_static=True) + ## scheduler.h: void ns3::Scheduler::Insert(ns3::EventId const & id) [member function] + cls.add_method('Insert', 'void', [param('ns3::EventId&', 'id', is_const=True)], is_pure_virtual=True, is_virtual=True) + ## scheduler.h: bool ns3::Scheduler::IsEmpty() const [member function] + cls.add_method('IsEmpty', 'bool', [], is_pure_virtual=True, is_const=True, is_virtual=True) + ## scheduler.h: ns3::EventId ns3::Scheduler::PeekNext() const [member function] + cls.add_method('PeekNext', 'ns3::EventId', [], is_pure_virtual=True, is_const=True, is_virtual=True) + ## scheduler.h: ns3::EventId ns3::Scheduler::RemoveNext() [member function] + cls.add_method('RemoveNext', 'ns3::EventId', [], is_pure_virtual=True, is_virtual=True) + ## scheduler.h: bool ns3::Scheduler::Remove(ns3::EventId const & id) [member function] + cls.add_method('Remove', 'bool', [param('ns3::EventId&', 'id', is_const=True)], is_pure_virtual=True, is_virtual=True) + cls.add_constructor([]) + return + +def register_Ns3SchedulerEventKey_methods(root_module, cls): + ## scheduler.h: ns3::Scheduler::EventKey::m_ts [variable] + cls.add_instance_attribute('m_ts', 'uint64_t', is_const=False) + ## scheduler.h: ns3::Scheduler::EventKey::m_uid [variable] + cls.add_instance_attribute('m_uid', 'uint32_t', is_const=False) + cls.add_constructor([]) + return + +def register_Ns3TimeValue_methods(root_module, cls): + ## nstime.h: ns3::TimeValue::TimeValue() [constructor] + cls.add_constructor([], visibility='public') + ## nstime.h: ns3::TimeValue::TimeValue(ns3::Time const & value) [constructor] + cls.add_constructor([param('ns3::Time&', 'value', is_const=True)], visibility='public') + ## nstime.h: void ns3::TimeValue::Set(ns3::Time const & value) [member function] + cls.add_method('Set', 'void', [param('ns3::Time&', 'value', is_const=True)]) + ## nstime.h: ns3::Time ns3::TimeValue::Get() const [member function] + cls.add_method('Get', 'ns3::Time', [], is_const=True) + ## nstime.h: ns3::Ptr ns3::TimeValue::Copy() const [member function] + cls.add_method('Copy', 'ns3::Ptr< ns3::AttributeValue >', [], is_const=True, is_virtual=True) + ## nstime.h: std::string ns3::TimeValue::SerializeToString(ns3::Ptr checker) const [member function] + cls.add_method('SerializeToString', 'std::string', [param('ns3::Ptr< ns3::AttributeChecker const >', 'checker')], is_const=True, is_virtual=True) + ## nstime.h: bool ns3::TimeValue::DeserializeFromString(std::string value, ns3::Ptr checker) [member function] + cls.add_method('DeserializeFromString', 'bool', [param('std::string', 'value'), param('ns3::Ptr< ns3::AttributeChecker const >', 'checker')], is_virtual=True) + return + +def register_Ns3HeapScheduler_methods(root_module, cls): + ## heap-scheduler.h: ns3::HeapScheduler::HeapScheduler() [constructor] + cls.add_constructor([], visibility='public') + ## heap-scheduler.h: void ns3::HeapScheduler::Insert(ns3::EventId const & id) [member function] + cls.add_method('Insert', 'void', [param('ns3::EventId&', 'id', is_const=True)], is_virtual=True) + ## heap-scheduler.h: bool ns3::HeapScheduler::IsEmpty() const [member function] + cls.add_method('IsEmpty', 'bool', [], is_const=True, is_virtual=True) + ## heap-scheduler.h: ns3::EventId ns3::HeapScheduler::PeekNext() const [member function] + cls.add_method('PeekNext', 'ns3::EventId', [], is_const=True, is_virtual=True) + ## heap-scheduler.h: ns3::EventId ns3::HeapScheduler::RemoveNext() [member function] + cls.add_method('RemoveNext', 'ns3::EventId', [], is_virtual=True) + ## heap-scheduler.h: bool ns3::HeapScheduler::Remove(ns3::EventId const & ev) [member function] + cls.add_method('Remove', 'bool', [param('ns3::EventId&', 'ev', is_const=True)], is_virtual=True) + return + +def register_Ns3ListScheduler_methods(root_module, cls): + ## list-scheduler.h: ns3::ListScheduler::ListScheduler() [constructor] + cls.add_constructor([], visibility='public') + ## list-scheduler.h: void ns3::ListScheduler::Insert(ns3::EventId const & id) [member function] + cls.add_method('Insert', 'void', [param('ns3::EventId&', 'id', is_const=True)], is_virtual=True) + ## list-scheduler.h: bool ns3::ListScheduler::IsEmpty() const [member function] + cls.add_method('IsEmpty', 'bool', [], is_const=True, is_virtual=True) + ## list-scheduler.h: ns3::EventId ns3::ListScheduler::PeekNext() const [member function] + cls.add_method('PeekNext', 'ns3::EventId', [], is_const=True, is_virtual=True) + ## list-scheduler.h: ns3::EventId ns3::ListScheduler::RemoveNext() [member function] + cls.add_method('RemoveNext', 'ns3::EventId', [], is_virtual=True) + ## list-scheduler.h: bool ns3::ListScheduler::Remove(ns3::EventId const & ev) [member function] + cls.add_method('Remove', 'bool', [param('ns3::EventId&', 'ev', is_const=True)], is_virtual=True) + return + +def register_Ns3MapScheduler_methods(root_module, cls): + ## map-scheduler.h: ns3::MapScheduler::MapScheduler() [constructor] + cls.add_constructor([], visibility='public') + ## map-scheduler.h: void ns3::MapScheduler::Insert(ns3::EventId const & id) [member function] + cls.add_method('Insert', 'void', [param('ns3::EventId&', 'id', is_const=True)], is_virtual=True) + ## map-scheduler.h: bool ns3::MapScheduler::IsEmpty() const [member function] + cls.add_method('IsEmpty', 'bool', [], is_const=True, is_virtual=True) + ## map-scheduler.h: ns3::EventId ns3::MapScheduler::PeekNext() const [member function] + cls.add_method('PeekNext', 'ns3::EventId', [], is_const=True, is_virtual=True) + ## map-scheduler.h: ns3::EventId ns3::MapScheduler::RemoveNext() [member function] + cls.add_method('RemoveNext', 'ns3::EventId', [], is_virtual=True) + ## map-scheduler.h: bool ns3::MapScheduler::Remove(ns3::EventId const & ev) [member function] + cls.add_method('Remove', 'bool', [param('ns3::EventId&', 'ev', is_const=True)], is_virtual=True) + return + +def register_functions(root_module): + module = root_module + ## high-precision.h: extern ns3::HighPrecision ns3::Max(ns3::HighPrecision const & a, ns3::HighPrecision const & b) [free function] + module.add_function('Max', 'ns3::HighPrecision', [param('ns3::HighPrecision&', 'a', is_const=True), param('ns3::HighPrecision&', 'b', is_const=True)]) + ## nstime.h: extern ns3::Time ns3::FemtoSeconds(uint64_t fs) [free function] + module.add_function('FemtoSeconds', 'ns3::Time', [param('uint64_t', 'fs')]) + ## nstime.h: extern ns3::Time ns3::MicroSeconds(uint64_t us) [free function] + module.add_function('MicroSeconds', 'ns3::Time', [param('uint64_t', 'us')]) + ## simulator.h: extern ns3::Time ns3::Now() [free function] + module.add_function('Now', 'ns3::Time', []) + ## nstime.h: extern ns3::Time ns3::MilliSeconds(uint64_t ms) [free function] + module.add_function('MilliSeconds', 'ns3::Time', [param('uint64_t', 'ms')]) + ## nstime.h: extern ns3::Time ns3::NanoSeconds(uint64_t ns) [free function] + module.add_function('NanoSeconds', 'ns3::Time', [param('uint64_t', 'ns')]) + ## high-precision.h: extern ns3::HighPrecision ns3::Abs(ns3::HighPrecision const & value) [free function] + module.add_function('Abs', 'ns3::HighPrecision', [param('ns3::HighPrecision&', 'value', is_const=True)]) + ## nstime.h: extern ns3::Ptr ns3::MakeTimeChecker() [free function] + module.add_function('MakeTimeChecker', 'ns3::Ptr< ns3::AttributeChecker const >', []) + ## nstime.h: extern ns3::Time ns3::Seconds(double seconds) [free function] + module.add_function('Seconds', 'ns3::Time', [param('double', 'seconds')]) + ## nstime.h: extern ns3::Time ns3::PicoSeconds(uint64_t ps) [free function] + module.add_function('PicoSeconds', 'ns3::Time', [param('uint64_t', 'ps')]) + ## high-precision.h: extern ns3::HighPrecision ns3::Min(ns3::HighPrecision const & a, ns3::HighPrecision const & b) [free function] + module.add_function('Min', 'ns3::HighPrecision', [param('ns3::HighPrecision&', 'a', is_const=True), param('ns3::HighPrecision&', 'b', is_const=True)]) + ## nstime.h: extern ns3::Time ns3::TimeStep(uint64_t ts) [free function] + module.add_function('TimeStep', 'ns3::Time', [param('uint64_t', 'ts')]) + register_functions_ns3_internal(module.get_submodule('internal'), root_module) + register_functions_ns3_TimeStepPrecision(module.get_submodule('TimeStepPrecision'), root_module) + register_functions_ns3_Config(module.get_submodule('Config'), root_module) + register_functions_ns3_olsr(module.get_submodule('olsr'), root_module) + return + +def register_functions_ns3_internal(module, root_module): + return + +def register_functions_ns3_TimeStepPrecision(module, root_module): + ## nstime.h: extern void ns3::TimeStepPrecision::Set(ns3::TimeStepPrecision::precision_t precision) [free function] + module.add_function('Set', 'void', [param('ns3::TimeStepPrecision::precision_t', 'precision')]) + ## nstime.h: extern ns3::TimeStepPrecision::precision_t ns3::TimeStepPrecision::Get() [free function] + module.add_function('Get', 'ns3::TimeStepPrecision::precision_t', []) + return + +def register_functions_ns3_Config(module, root_module): + return + +def register_functions_ns3_olsr(module, root_module): + return + diff --git a/bindings/python/ns3_module_udp_echo.py b/bindings/python/ns3_module_udp_echo.py new file mode 100644 index 000000000..d7b9b7aae --- /dev/null +++ b/bindings/python/ns3_module_udp_echo.py @@ -0,0 +1,103 @@ +from pybindgen import Module, FileCodeSink, write_preamble, param, retval + +def register_types(module): + root_module = module.get_root() + + ## udp-echo-client.h: ns3::UdpEchoClient [class] + module.add_class('UdpEchoClient', allow_subclassing=True, parent=root_module['ns3::Application']) + ## udp-echo-server.h: ns3::UdpEchoServer [class] + module.add_class('UdpEchoServer', allow_subclassing=True, parent=root_module['ns3::Application']) + + ## Register a nested module for the namespace internal + + nested_module = module.add_cpp_namespace('internal') + register_types_ns3_internal(nested_module) + + + ## Register a nested module for the namespace TimeStepPrecision + + nested_module = module.add_cpp_namespace('TimeStepPrecision') + register_types_ns3_TimeStepPrecision(nested_module) + + + ## Register a nested module for the namespace Config + + nested_module = module.add_cpp_namespace('Config') + register_types_ns3_Config(nested_module) + + + ## Register a nested module for the namespace olsr + + nested_module = module.add_cpp_namespace('olsr') + register_types_ns3_olsr(nested_module) + + +def register_types_ns3_internal(module): + root_module = module.get_root() + + +def register_types_ns3_TimeStepPrecision(module): + root_module = module.get_root() + + +def register_types_ns3_Config(module): + root_module = module.get_root() + + +def register_types_ns3_olsr(module): + root_module = module.get_root() + + +def register_methods(root_module): + register_Ns3UdpEchoClient_methods(root_module, root_module['ns3::UdpEchoClient']) + register_Ns3UdpEchoServer_methods(root_module, root_module['ns3::UdpEchoServer']) + return + +def register_Ns3UdpEchoClient_methods(root_module, cls): + ## udp-echo-client.h: static ns3::TypeId ns3::UdpEchoClient::GetTypeId() [member function] + cls.add_method('GetTypeId', 'ns3::TypeId', [], is_static=True) + ## udp-echo-client.h: ns3::UdpEchoClient::UdpEchoClient() [constructor] + cls.add_constructor([], visibility='public') + ## udp-echo-client.h: void ns3::UdpEchoClient::SetRemote(ns3::Ipv4Address ip, uint16_t port) [member function] + cls.add_method('SetRemote', 'void', [param('ns3::Ipv4Address', 'ip'), param('uint16_t', 'port')]) + ## udp-echo-client.h: void ns3::UdpEchoClient::DoDispose() [member function] + cls.add_method('DoDispose', 'void', [], visibility='protected', is_virtual=True) + ## udp-echo-client.h: void ns3::UdpEchoClient::StartApplication() [member function] + cls.add_method('StartApplication', 'void', [], visibility='private', is_virtual=True) + ## udp-echo-client.h: void ns3::UdpEchoClient::StopApplication() [member function] + cls.add_method('StopApplication', 'void', [], visibility='private', is_virtual=True) + return + +def register_Ns3UdpEchoServer_methods(root_module, cls): + ## udp-echo-server.h: static ns3::TypeId ns3::UdpEchoServer::GetTypeId() [member function] + cls.add_method('GetTypeId', 'ns3::TypeId', [], is_static=True) + ## udp-echo-server.h: ns3::UdpEchoServer::UdpEchoServer() [constructor] + cls.add_constructor([], visibility='public') + ## udp-echo-server.h: void ns3::UdpEchoServer::DoDispose() [member function] + cls.add_method('DoDispose', 'void', [], visibility='protected', is_virtual=True) + ## udp-echo-server.h: void ns3::UdpEchoServer::StartApplication() [member function] + cls.add_method('StartApplication', 'void', [], visibility='private', is_virtual=True) + ## udp-echo-server.h: void ns3::UdpEchoServer::StopApplication() [member function] + cls.add_method('StopApplication', 'void', [], visibility='private', is_virtual=True) + return + +def register_functions(root_module): + module = root_module + register_functions_ns3_internal(module.get_submodule('internal'), root_module) + register_functions_ns3_TimeStepPrecision(module.get_submodule('TimeStepPrecision'), root_module) + register_functions_ns3_Config(module.get_submodule('Config'), root_module) + register_functions_ns3_olsr(module.get_submodule('olsr'), root_module) + return + +def register_functions_ns3_internal(module, root_module): + return + +def register_functions_ns3_TimeStepPrecision(module, root_module): + return + +def register_functions_ns3_Config(module, root_module): + return + +def register_functions_ns3_olsr(module, root_module): + return + diff --git a/bindings/python/ns3_module_wifi.py b/bindings/python/ns3_module_wifi.py new file mode 100644 index 000000000..5809ba692 --- /dev/null +++ b/bindings/python/ns3_module_wifi.py @@ -0,0 +1,1225 @@ +from pybindgen import Module, FileCodeSink, write_preamble, param, retval + +def register_types(module): + root_module = module.get_root() + + ## wifi-preamble.h: ns3::WifiPreamble [enumeration] + module.add_enum('WifiPreamble', ['WIFI_PREAMBLE_LONG', 'WIFI_PREAMBLE_SHORT']) + ## wifi-phy-standard.h: ns3::WifiPhyStandard [enumeration] + module.add_enum('WifiPhyStandard', ['WIFI_PHY_STANDARD_80211a', 'WIFI_PHY_STANDARD_holland']) + ## wifi-remote-station-manager.h: ns3::WifiRemoteStation [class] + module.add_class('WifiRemoteStation', allow_subclassing=True) + ## wifi-phy.h: ns3::WifiPhyListener [class] + module.add_class('WifiPhyListener', allow_subclassing=True) + ## rraa-wifi-manager.h: ns3::ThresholdsItem [struct] + module.add_class('ThresholdsItem') + ## supported-rates.h: ns3::SupportedRates [class] + module.add_class('SupportedRates') + ## ideal-wifi-manager.h: ns3::IdealWifiRemoteStation [class] + module.add_class('IdealWifiRemoteStation', allow_subclassing=True, parent=root_module['ns3::WifiRemoteStation']) + ## wifi-mode.h: ns3::WifiModeChecker [class] + module.add_class('WifiModeChecker', parent=root_module['ns3::AttributeChecker']) + ## wifi-mode.h: ns3::WifiModeFactory [class] + module.add_class('WifiModeFactory') + ## onoe-wifi-manager.h: ns3::OnoeWifiRemoteStation [class] + module.add_class('OnoeWifiRemoteStation', allow_subclassing=True, parent=root_module['ns3::WifiRemoteStation']) + ## rraa-wifi-manager.h: ns3::RraaWifiRemoteStation [class] + module.add_class('RraaWifiRemoteStation', allow_subclassing=True, parent=root_module['ns3::WifiRemoteStation']) + ## ssid.h: ns3::Ssid [class] + module.add_class('Ssid') + ## wifi-mode.h: ns3::WifiMode [class] + module.add_class('WifiMode') + ## wifi-mode.h: ns3::WifiMode::ModulationType [enumeration] + module.add_enum('ModulationType', ['BPSK', 'QAM'], outer_class=root_module['ns3::WifiMode']) + ## ssid.h: ns3::SsidValue [class] + module.add_class('SsidValue', allow_subclassing=True, parent=root_module['ns3::AttributeValue']) + ## ssid.h: ns3::SsidChecker [class] + module.add_class('SsidChecker', parent=root_module['ns3::AttributeChecker']) + ## constant-rate-wifi-manager.h: ns3::ConstantRateWifiRemoteStation [class] + module.add_class('ConstantRateWifiRemoteStation', allow_subclassing=True, parent=root_module['ns3::WifiRemoteStation']) + ## propagation-loss-model.h: ns3::PropagationLossModel [class] + module.add_class('PropagationLossModel', allow_subclassing=True, parent=root_module['ns3::Object']) + ## arf-wifi-manager.h: ns3::ArfWifiRemoteStation [class] + module.add_class('ArfWifiRemoteStation', allow_subclassing=True, parent=root_module['ns3::WifiRemoteStation']) + ## wifi-mac.h: ns3::WifiMac [class] + module.add_class('WifiMac', allow_subclassing=True, parent=root_module['ns3::Object']) + ## nqap-wifi-mac.h: ns3::NqapWifiMac [class] + module.add_class('NqapWifiMac', allow_subclassing=True, parent=root_module['ns3::WifiMac']) + ## amrr-wifi-manager.h: ns3::AmrrWifiRemoteStation [class] + module.add_class('AmrrWifiRemoteStation', allow_subclassing=True, parent=root_module['ns3::WifiRemoteStation']) + ## composite-propagation-loss-model.h: ns3::CompositePropagationLossModel [class] + module.add_class('CompositePropagationLossModel', allow_subclassing=True, parent=root_module['ns3::PropagationLossModel']) + ## propagation-loss-model.h: ns3::FriisPropagationLossModel [class] + module.add_class('FriisPropagationLossModel', allow_subclassing=True, parent=root_module['ns3::PropagationLossModel']) + ## wifi-remote-station-manager.h: ns3::WifiRemoteStationManager [class] + module.add_class('WifiRemoteStationManager', allow_subclassing=True, parent=root_module['ns3::Object']) + ## wifi-mode.h: ns3::WifiModeValue [class] + module.add_class('WifiModeValue', allow_subclassing=True, parent=root_module['ns3::AttributeValue']) + ## onoe-wifi-manager.h: ns3::OnoeWifiManager [class] + module.add_class('OnoeWifiManager', allow_subclassing=True, parent=root_module['ns3::WifiRemoteStationManager']) + ## wifi-phy.h: ns3::WifiPhy [class] + module.add_class('WifiPhy', allow_subclassing=True, parent=root_module['ns3::Object']) + ## wifi-phy.h: ns3::WifiPhy::State [enumeration] + module.add_enum('State', ['SYNC', 'TX', 'CCA_BUSY', 'IDLE'], outer_class=root_module['ns3::WifiPhy']) + ## wifi-channel.h: ns3::WifiChannel [class] + module.add_class('WifiChannel', allow_subclassing=True, parent=root_module['ns3::Channel']) + ## propagation-loss-model.h: ns3::LogDistancePropagationLossModel [class] + module.add_class('LogDistancePropagationLossModel', allow_subclassing=True, parent=root_module['ns3::PropagationLossModel']) + ## constant-rate-wifi-manager.h: ns3::ConstantRateWifiManager [class] + module.add_class('ConstantRateWifiManager', allow_subclassing=True, parent=root_module['ns3::WifiRemoteStationManager']) + ## aarf-wifi-manager.h: ns3::AarfWifiRemoteStation [class] + module.add_class('AarfWifiRemoteStation', allow_subclassing=True, parent=root_module['ns3::ArfWifiRemoteStation']) + ## propagation-delay-model.h: ns3::PropagationDelayModel [class] + module.add_class('PropagationDelayModel', allow_subclassing=True, parent=root_module['ns3::Object']) + ## adhoc-wifi-mac.h: ns3::AdhocWifiMac [class] + module.add_class('AdhocWifiMac', allow_subclassing=True, parent=root_module['ns3::WifiMac']) + ## jakes-propagation-loss-model.h: ns3::JakesPropagationLossModel [class] + module.add_class('JakesPropagationLossModel', allow_subclassing=True, parent=root_module['ns3::PropagationLossModel']) + ## propagation-delay-model.h: ns3::ConstantSpeedPropagationDelayModel [class] + module.add_class('ConstantSpeedPropagationDelayModel', allow_subclassing=True, parent=root_module['ns3::PropagationDelayModel']) + ## wifi-net-device.h: ns3::WifiNetDevice [class] + module.add_class('WifiNetDevice', allow_subclassing=True, parent=root_module['ns3::NetDevice']) + ## nqsta-wifi-mac.h: ns3::NqstaWifiMac [class] + module.add_class('NqstaWifiMac', allow_subclassing=True, parent=root_module['ns3::WifiMac']) + ## propagation-loss-model.h: ns3::RandomPropagationLossModel [class] + module.add_class('RandomPropagationLossModel', allow_subclassing=True, parent=root_module['ns3::PropagationLossModel']) + ## propagation-delay-model.h: ns3::RandomPropagationDelayModel [class] + module.add_class('RandomPropagationDelayModel', allow_subclassing=True, parent=root_module['ns3::PropagationDelayModel']) + ## amrr-wifi-manager.h: ns3::AmrrWifiManager [class] + module.add_class('AmrrWifiManager', allow_subclassing=True, parent=root_module['ns3::WifiRemoteStationManager']) + ## rraa-wifi-manager.h: ns3::RraaWifiManager [class] + module.add_class('RraaWifiManager', allow_subclassing=True, parent=root_module['ns3::WifiRemoteStationManager']) + ## ideal-wifi-manager.h: ns3::IdealWifiManager [class] + module.add_class('IdealWifiManager', allow_subclassing=True, parent=root_module['ns3::WifiRemoteStationManager']) + ## arf-wifi-manager.h: ns3::ArfWifiManager [class] + module.add_class('ArfWifiManager', allow_subclassing=True, parent=root_module['ns3::WifiRemoteStationManager']) + ## aarf-wifi-manager.h: ns3::AarfWifiManager [class] + module.add_class('AarfWifiManager', allow_subclassing=True, parent=root_module['ns3::ArfWifiManager']) + + ## Register a nested module for the namespace internal + + nested_module = module.add_cpp_namespace('internal') + register_types_ns3_internal(nested_module) + + + ## Register a nested module for the namespace TimeStepPrecision + + nested_module = module.add_cpp_namespace('TimeStepPrecision') + register_types_ns3_TimeStepPrecision(nested_module) + + + ## Register a nested module for the namespace Config + + nested_module = module.add_cpp_namespace('Config') + register_types_ns3_Config(nested_module) + + + ## Register a nested module for the namespace olsr + + nested_module = module.add_cpp_namespace('olsr') + register_types_ns3_olsr(nested_module) + + +def register_types_ns3_internal(module): + root_module = module.get_root() + + +def register_types_ns3_TimeStepPrecision(module): + root_module = module.get_root() + + +def register_types_ns3_Config(module): + root_module = module.get_root() + + +def register_types_ns3_olsr(module): + root_module = module.get_root() + + +def register_methods(root_module): + register_Ns3WifiRemoteStation_methods(root_module, root_module['ns3::WifiRemoteStation']) + register_Ns3WifiPhyListener_methods(root_module, root_module['ns3::WifiPhyListener']) + register_Ns3ThresholdsItem_methods(root_module, root_module['ns3::ThresholdsItem']) + register_Ns3SupportedRates_methods(root_module, root_module['ns3::SupportedRates']) + register_Ns3IdealWifiRemoteStation_methods(root_module, root_module['ns3::IdealWifiRemoteStation']) + register_Ns3WifiModeChecker_methods(root_module, root_module['ns3::WifiModeChecker']) + register_Ns3WifiModeFactory_methods(root_module, root_module['ns3::WifiModeFactory']) + register_Ns3OnoeWifiRemoteStation_methods(root_module, root_module['ns3::OnoeWifiRemoteStation']) + register_Ns3RraaWifiRemoteStation_methods(root_module, root_module['ns3::RraaWifiRemoteStation']) + register_Ns3Ssid_methods(root_module, root_module['ns3::Ssid']) + register_Ns3WifiMode_methods(root_module, root_module['ns3::WifiMode']) + register_Ns3SsidValue_methods(root_module, root_module['ns3::SsidValue']) + register_Ns3SsidChecker_methods(root_module, root_module['ns3::SsidChecker']) + register_Ns3ConstantRateWifiRemoteStation_methods(root_module, root_module['ns3::ConstantRateWifiRemoteStation']) + register_Ns3PropagationLossModel_methods(root_module, root_module['ns3::PropagationLossModel']) + register_Ns3ArfWifiRemoteStation_methods(root_module, root_module['ns3::ArfWifiRemoteStation']) + register_Ns3WifiMac_methods(root_module, root_module['ns3::WifiMac']) + register_Ns3NqapWifiMac_methods(root_module, root_module['ns3::NqapWifiMac']) + register_Ns3AmrrWifiRemoteStation_methods(root_module, root_module['ns3::AmrrWifiRemoteStation']) + register_Ns3CompositePropagationLossModel_methods(root_module, root_module['ns3::CompositePropagationLossModel']) + register_Ns3FriisPropagationLossModel_methods(root_module, root_module['ns3::FriisPropagationLossModel']) + register_Ns3WifiRemoteStationManager_methods(root_module, root_module['ns3::WifiRemoteStationManager']) + register_Ns3WifiModeValue_methods(root_module, root_module['ns3::WifiModeValue']) + register_Ns3OnoeWifiManager_methods(root_module, root_module['ns3::OnoeWifiManager']) + register_Ns3WifiPhy_methods(root_module, root_module['ns3::WifiPhy']) + register_Ns3WifiChannel_methods(root_module, root_module['ns3::WifiChannel']) + register_Ns3LogDistancePropagationLossModel_methods(root_module, root_module['ns3::LogDistancePropagationLossModel']) + register_Ns3ConstantRateWifiManager_methods(root_module, root_module['ns3::ConstantRateWifiManager']) + register_Ns3AarfWifiRemoteStation_methods(root_module, root_module['ns3::AarfWifiRemoteStation']) + register_Ns3PropagationDelayModel_methods(root_module, root_module['ns3::PropagationDelayModel']) + register_Ns3AdhocWifiMac_methods(root_module, root_module['ns3::AdhocWifiMac']) + register_Ns3JakesPropagationLossModel_methods(root_module, root_module['ns3::JakesPropagationLossModel']) + register_Ns3ConstantSpeedPropagationDelayModel_methods(root_module, root_module['ns3::ConstantSpeedPropagationDelayModel']) + register_Ns3WifiNetDevice_methods(root_module, root_module['ns3::WifiNetDevice']) + register_Ns3NqstaWifiMac_methods(root_module, root_module['ns3::NqstaWifiMac']) + register_Ns3RandomPropagationLossModel_methods(root_module, root_module['ns3::RandomPropagationLossModel']) + register_Ns3RandomPropagationDelayModel_methods(root_module, root_module['ns3::RandomPropagationDelayModel']) + register_Ns3AmrrWifiManager_methods(root_module, root_module['ns3::AmrrWifiManager']) + register_Ns3RraaWifiManager_methods(root_module, root_module['ns3::RraaWifiManager']) + register_Ns3IdealWifiManager_methods(root_module, root_module['ns3::IdealWifiManager']) + register_Ns3ArfWifiManager_methods(root_module, root_module['ns3::ArfWifiManager']) + register_Ns3AarfWifiManager_methods(root_module, root_module['ns3::AarfWifiManager']) + return + +def register_Ns3WifiRemoteStation_methods(root_module, cls): + ## wifi-remote-station-manager.h: static ns3::TypeId ns3::WifiRemoteStation::GetTypeId() [member function] + cls.add_method('GetTypeId', 'ns3::TypeId', [], is_static=True) + ## wifi-remote-station-manager.h: ns3::WifiRemoteStation::WifiRemoteStation() [constructor] + cls.add_constructor([], visibility='public') + ## wifi-remote-station-manager.h: void ns3::WifiRemoteStation::Reset() [member function] + cls.add_method('Reset', 'void', []) + ## wifi-remote-station-manager.h: void ns3::WifiRemoteStation::AddSupportedMode(ns3::WifiMode mode) [member function] + cls.add_method('AddSupportedMode', 'void', [param('ns3::WifiMode', 'mode')]) + ## wifi-remote-station-manager.h: bool ns3::WifiRemoteStation::IsBrandNew() const [member function] + cls.add_method('IsBrandNew', 'bool', [], is_const=True) + ## wifi-remote-station-manager.h: bool ns3::WifiRemoteStation::IsAssociated() const [member function] + cls.add_method('IsAssociated', 'bool', [], is_const=True) + ## wifi-remote-station-manager.h: bool ns3::WifiRemoteStation::IsWaitAssocTxOk() const [member function] + cls.add_method('IsWaitAssocTxOk', 'bool', [], is_const=True) + ## wifi-remote-station-manager.h: void ns3::WifiRemoteStation::RecordWaitAssocTxOk() [member function] + cls.add_method('RecordWaitAssocTxOk', 'void', []) + ## wifi-remote-station-manager.h: void ns3::WifiRemoteStation::RecordGotAssocTxOk() [member function] + cls.add_method('RecordGotAssocTxOk', 'void', []) + ## wifi-remote-station-manager.h: void ns3::WifiRemoteStation::RecordGotAssocTxFailed() [member function] + cls.add_method('RecordGotAssocTxFailed', 'void', []) + ## wifi-remote-station-manager.h: void ns3::WifiRemoteStation::RecordDisassociated() [member function] + cls.add_method('RecordDisassociated', 'void', []) + ## wifi-remote-station-manager.h: void ns3::WifiRemoteStation::PrepareForQueue(ns3::Ptr packet, uint32_t fullPacketSize) [member function] + cls.add_method('PrepareForQueue', 'void', [param('ns3::Ptr< const ns3::Packet >', 'packet'), param('uint32_t', 'fullPacketSize')]) + ## wifi-remote-station-manager.h: ns3::WifiMode ns3::WifiRemoteStation::GetDataMode(ns3::Ptr packet, uint32_t fullPacketSize) [member function] + cls.add_method('GetDataMode', 'ns3::WifiMode', [param('ns3::Ptr< const ns3::Packet >', 'packet'), param('uint32_t', 'fullPacketSize')]) + ## wifi-remote-station-manager.h: ns3::WifiMode ns3::WifiRemoteStation::GetRtsMode(ns3::Ptr packet) [member function] + cls.add_method('GetRtsMode', 'ns3::WifiMode', [param('ns3::Ptr< const ns3::Packet >', 'packet')]) + ## wifi-remote-station-manager.h: void ns3::WifiRemoteStation::ReportRtsFailed() [member function] + cls.add_method('ReportRtsFailed', 'void', []) + ## wifi-remote-station-manager.h: void ns3::WifiRemoteStation::ReportDataFailed() [member function] + cls.add_method('ReportDataFailed', 'void', []) + ## wifi-remote-station-manager.h: void ns3::WifiRemoteStation::ReportRtsOk(double ctsSnr, ns3::WifiMode ctsMode, double rtsSnr) [member function] + cls.add_method('ReportRtsOk', 'void', [param('double', 'ctsSnr'), param('ns3::WifiMode', 'ctsMode'), param('double', 'rtsSnr')]) + ## wifi-remote-station-manager.h: void ns3::WifiRemoteStation::ReportDataOk(double ackSnr, ns3::WifiMode ackMode, double dataSnr) [member function] + cls.add_method('ReportDataOk', 'void', [param('double', 'ackSnr'), param('ns3::WifiMode', 'ackMode'), param('double', 'dataSnr')]) + ## wifi-remote-station-manager.h: void ns3::WifiRemoteStation::ReportFinalRtsFailed() [member function] + cls.add_method('ReportFinalRtsFailed', 'void', []) + ## wifi-remote-station-manager.h: void ns3::WifiRemoteStation::ReportFinalDataFailed() [member function] + cls.add_method('ReportFinalDataFailed', 'void', []) + ## wifi-remote-station-manager.h: void ns3::WifiRemoteStation::ReportRxOk(double rxSnr, ns3::WifiMode txMode) [member function] + cls.add_method('ReportRxOk', 'void', [param('double', 'rxSnr'), param('ns3::WifiMode', 'txMode')]) + ## wifi-remote-station-manager.h: bool ns3::WifiRemoteStation::NeedRts(ns3::Ptr packet) [member function] + cls.add_method('NeedRts', 'bool', [param('ns3::Ptr< const ns3::Packet >', 'packet')], is_virtual=True) + ## wifi-remote-station-manager.h: bool ns3::WifiRemoteStation::NeedRtsRetransmission(ns3::Ptr packet) [member function] + cls.add_method('NeedRtsRetransmission', 'bool', [param('ns3::Ptr< const ns3::Packet >', 'packet')], is_virtual=True) + ## wifi-remote-station-manager.h: bool ns3::WifiRemoteStation::NeedDataRetransmission(ns3::Ptr packet) [member function] + cls.add_method('NeedDataRetransmission', 'bool', [param('ns3::Ptr< const ns3::Packet >', 'packet')], is_virtual=True) + ## wifi-remote-station-manager.h: bool ns3::WifiRemoteStation::NeedFragmentation(ns3::Ptr packet) [member function] + cls.add_method('NeedFragmentation', 'bool', [param('ns3::Ptr< const ns3::Packet >', 'packet')], is_virtual=True) + ## wifi-remote-station-manager.h: uint32_t ns3::WifiRemoteStation::GetNFragments(ns3::Ptr packet) [member function] + cls.add_method('GetNFragments', 'uint32_t', [param('ns3::Ptr< const ns3::Packet >', 'packet')], is_virtual=True) + ## wifi-remote-station-manager.h: uint32_t ns3::WifiRemoteStation::GetFragmentSize(ns3::Ptr packet, uint32_t fragmentNumber) [member function] + cls.add_method('GetFragmentSize', 'uint32_t', [param('ns3::Ptr< const ns3::Packet >', 'packet'), param('uint32_t', 'fragmentNumber')], is_virtual=True) + ## wifi-remote-station-manager.h: bool ns3::WifiRemoteStation::IsLastFragment(ns3::Ptr packet, uint32_t fragmentNumber) [member function] + cls.add_method('IsLastFragment', 'bool', [param('ns3::Ptr< const ns3::Packet >', 'packet'), param('uint32_t', 'fragmentNumber')], is_virtual=True) + ## wifi-remote-station-manager.h: ns3::WifiMode ns3::WifiRemoteStation::GetCtsMode(ns3::WifiMode rtsMode) [member function] + cls.add_method('GetCtsMode', 'ns3::WifiMode', [param('ns3::WifiMode', 'rtsMode')]) + ## wifi-remote-station-manager.h: ns3::WifiMode ns3::WifiRemoteStation::GetAckMode(ns3::WifiMode dataMode) [member function] + cls.add_method('GetAckMode', 'ns3::WifiMode', [param('ns3::WifiMode', 'dataMode')]) + ## wifi-remote-station-manager.h: void ns3::WifiRemoteStation::DoReportRtsFailed() [member function] + cls.add_method('DoReportRtsFailed', 'void', [], is_pure_virtual=True, visibility='protected', is_virtual=True) + ## wifi-remote-station-manager.h: void ns3::WifiRemoteStation::DoReportDataFailed() [member function] + cls.add_method('DoReportDataFailed', 'void', [], is_pure_virtual=True, visibility='protected', is_virtual=True) + ## wifi-remote-station-manager.h: void ns3::WifiRemoteStation::DoReportRtsOk(double ctsSnr, ns3::WifiMode ctsMode, double rtsSnr) [member function] + cls.add_method('DoReportRtsOk', 'void', [param('double', 'ctsSnr'), param('ns3::WifiMode', 'ctsMode'), param('double', 'rtsSnr')], is_pure_virtual=True, visibility='protected', is_virtual=True) + ## wifi-remote-station-manager.h: void ns3::WifiRemoteStation::DoReportDataOk(double ackSnr, ns3::WifiMode ackMode, double dataSnr) [member function] + cls.add_method('DoReportDataOk', 'void', [param('double', 'ackSnr'), param('ns3::WifiMode', 'ackMode'), param('double', 'dataSnr')], is_pure_virtual=True, visibility='protected', is_virtual=True) + ## wifi-remote-station-manager.h: void ns3::WifiRemoteStation::DoReportFinalRtsFailed() [member function] + cls.add_method('DoReportFinalRtsFailed', 'void', [], is_pure_virtual=True, visibility='protected', is_virtual=True) + ## wifi-remote-station-manager.h: void ns3::WifiRemoteStation::DoReportFinalDataFailed() [member function] + cls.add_method('DoReportFinalDataFailed', 'void', [], is_pure_virtual=True, visibility='protected', is_virtual=True) + ## wifi-remote-station-manager.h: void ns3::WifiRemoteStation::DoReportRxOk(double rxSnr, ns3::WifiMode txMode) [member function] + cls.add_method('DoReportRxOk', 'void', [param('double', 'rxSnr'), param('ns3::WifiMode', 'txMode')], is_pure_virtual=True, visibility='protected', is_virtual=True) + ## wifi-remote-station-manager.h: uint32_t ns3::WifiRemoteStation::GetNSupportedModes() const [member function] + cls.add_method('GetNSupportedModes', 'uint32_t', [], is_const=True, visibility='protected') + ## wifi-remote-station-manager.h: ns3::WifiMode ns3::WifiRemoteStation::GetSupportedMode(uint32_t i) const [member function] + cls.add_method('GetSupportedMode', 'ns3::WifiMode', [param('uint32_t', 'i')], is_const=True, visibility='protected') + ## wifi-remote-station-manager.h: ns3::Ptr ns3::WifiRemoteStation::GetManager() const [member function] + cls.add_method('GetManager', 'ns3::Ptr< ns3::WifiRemoteStationManager >', [], is_pure_virtual=True, is_const=True, visibility='private', is_virtual=True) + ## wifi-remote-station-manager.h: ns3::WifiMode ns3::WifiRemoteStation::DoGetDataMode(uint32_t size) [member function] + cls.add_method('DoGetDataMode', 'ns3::WifiMode', [param('uint32_t', 'size')], is_pure_virtual=True, visibility='private', is_virtual=True) + ## wifi-remote-station-manager.h: ns3::WifiMode ns3::WifiRemoteStation::DoGetRtsMode() [member function] + cls.add_method('DoGetRtsMode', 'ns3::WifiMode', [], is_pure_virtual=True, visibility='private', is_virtual=True) + return + +def register_Ns3WifiPhyListener_methods(root_module, cls): + ## wifi-phy.h: void ns3::WifiPhyListener::NotifyRxStart(ns3::Time duration) [member function] + cls.add_method('NotifyRxStart', 'void', [param('ns3::Time', 'duration')], is_pure_virtual=True, is_virtual=True) + ## wifi-phy.h: void ns3::WifiPhyListener::NotifyRxEndOk() [member function] + cls.add_method('NotifyRxEndOk', 'void', [], is_pure_virtual=True, is_virtual=True) + ## wifi-phy.h: void ns3::WifiPhyListener::NotifyRxEndError() [member function] + cls.add_method('NotifyRxEndError', 'void', [], is_pure_virtual=True, is_virtual=True) + ## wifi-phy.h: void ns3::WifiPhyListener::NotifyTxStart(ns3::Time duration) [member function] + cls.add_method('NotifyTxStart', 'void', [param('ns3::Time', 'duration')], is_pure_virtual=True, is_virtual=True) + ## wifi-phy.h: void ns3::WifiPhyListener::NotifyCcaBusyStart(ns3::Time duration) [member function] + cls.add_method('NotifyCcaBusyStart', 'void', [param('ns3::Time', 'duration')], is_pure_virtual=True, is_virtual=True) + cls.add_constructor([]) + return + +def register_Ns3ThresholdsItem_methods(root_module, cls): + ## rraa-wifi-manager.h: ns3::ThresholdsItem::datarate [variable] + cls.add_instance_attribute('datarate', 'uint32_t', is_const=False) + ## rraa-wifi-manager.h: ns3::ThresholdsItem::pori [variable] + cls.add_instance_attribute('pori', 'double', is_const=False) + ## rraa-wifi-manager.h: ns3::ThresholdsItem::pmtl [variable] + cls.add_instance_attribute('pmtl', 'double', is_const=False) + ## rraa-wifi-manager.h: ns3::ThresholdsItem::ewnd [variable] + cls.add_instance_attribute('ewnd', 'uint32_t', is_const=False) + cls.add_constructor([]) + return + +def register_Ns3SupportedRates_methods(root_module, cls): + ## supported-rates.h: ns3::SupportedRates::SupportedRates(ns3::SupportedRates const & arg0) [copy constructor] + cls.add_constructor([param('ns3::SupportedRates&', 'arg0', is_const=True)], visibility='public') + ## supported-rates.h: ns3::SupportedRates::SupportedRates() [constructor] + cls.add_constructor([], visibility='public') + ## supported-rates.h: void ns3::SupportedRates::AddSupportedRate(uint32_t bs) [member function] + cls.add_method('AddSupportedRate', 'void', [param('uint32_t', 'bs')]) + ## supported-rates.h: ns3::Buffer::Iterator ns3::SupportedRates::Deserialize(ns3::Buffer::Iterator start) [member function] + cls.add_method('Deserialize', 'ns3::Buffer::Iterator', [param('ns3::Buffer::Iterator', 'start')]) + ## supported-rates.h: uint8_t ns3::SupportedRates::GetNRates() const [member function] + cls.add_method('GetNRates', 'uint8_t', [], is_const=True) + ## supported-rates.h: uint32_t ns3::SupportedRates::GetRate(uint8_t i) const [member function] + cls.add_method('GetRate', 'uint32_t', [param('uint8_t', 'i')], is_const=True) + ## supported-rates.h: uint32_t ns3::SupportedRates::GetSerializedSize() const [member function] + cls.add_method('GetSerializedSize', 'uint32_t', [], is_const=True) + ## supported-rates.h: bool ns3::SupportedRates::IsBasicRate(uint32_t bs) const [member function] + cls.add_method('IsBasicRate', 'bool', [param('uint32_t', 'bs')], is_const=True) + ## supported-rates.h: bool ns3::SupportedRates::IsSupportedRate(uint32_t bs) const [member function] + cls.add_method('IsSupportedRate', 'bool', [param('uint32_t', 'bs')], is_const=True) + ## supported-rates.h: ns3::Buffer::Iterator ns3::SupportedRates::Serialize(ns3::Buffer::Iterator start) const [member function] + cls.add_method('Serialize', 'ns3::Buffer::Iterator', [param('ns3::Buffer::Iterator', 'start')], is_const=True) + ## supported-rates.h: void ns3::SupportedRates::SetBasicRate(uint32_t bs) [member function] + cls.add_method('SetBasicRate', 'void', [param('uint32_t', 'bs')]) + cls.add_output_stream_operator() + return + +def register_Ns3IdealWifiRemoteStation_methods(root_module, cls): + ## ideal-wifi-manager.h: ns3::IdealWifiRemoteStation::IdealWifiRemoteStation(ns3::Ptr stations) [constructor] + cls.add_constructor([param('ns3::Ptr< ns3::IdealWifiManager >', 'stations')], visibility='public') + ## ideal-wifi-manager.h: void ns3::IdealWifiRemoteStation::DoReportRxOk(double rxSnr, ns3::WifiMode txMode) [member function] + cls.add_method('DoReportRxOk', 'void', [param('double', 'rxSnr'), param('ns3::WifiMode', 'txMode')], visibility='protected', is_virtual=True) + ## ideal-wifi-manager.h: void ns3::IdealWifiRemoteStation::DoReportRtsFailed() [member function] + cls.add_method('DoReportRtsFailed', 'void', [], visibility='protected', is_virtual=True) + ## ideal-wifi-manager.h: void ns3::IdealWifiRemoteStation::DoReportDataFailed() [member function] + cls.add_method('DoReportDataFailed', 'void', [], visibility='protected', is_virtual=True) + ## ideal-wifi-manager.h: void ns3::IdealWifiRemoteStation::DoReportRtsOk(double ctsSnr, ns3::WifiMode ctsMode, double rtsSnr) [member function] + cls.add_method('DoReportRtsOk', 'void', [param('double', 'ctsSnr'), param('ns3::WifiMode', 'ctsMode'), param('double', 'rtsSnr')], visibility='protected', is_virtual=True) + ## ideal-wifi-manager.h: void ns3::IdealWifiRemoteStation::DoReportDataOk(double ackSnr, ns3::WifiMode ackMode, double dataSnr) [member function] + cls.add_method('DoReportDataOk', 'void', [param('double', 'ackSnr'), param('ns3::WifiMode', 'ackMode'), param('double', 'dataSnr')], visibility='protected', is_virtual=True) + ## ideal-wifi-manager.h: void ns3::IdealWifiRemoteStation::DoReportFinalRtsFailed() [member function] + cls.add_method('DoReportFinalRtsFailed', 'void', [], visibility='protected', is_virtual=True) + ## ideal-wifi-manager.h: void ns3::IdealWifiRemoteStation::DoReportFinalDataFailed() [member function] + cls.add_method('DoReportFinalDataFailed', 'void', [], visibility='protected', is_virtual=True) + ## ideal-wifi-manager.h: ns3::Ptr ns3::IdealWifiRemoteStation::GetManager() const [member function] + cls.add_method('GetManager', 'ns3::Ptr< ns3::WifiRemoteStationManager >', [], is_const=True, visibility='private', is_virtual=True) + ## ideal-wifi-manager.h: ns3::WifiMode ns3::IdealWifiRemoteStation::DoGetDataMode(uint32_t size) [member function] + cls.add_method('DoGetDataMode', 'ns3::WifiMode', [param('uint32_t', 'size')], visibility='private', is_virtual=True) + ## ideal-wifi-manager.h: ns3::WifiMode ns3::IdealWifiRemoteStation::DoGetRtsMode() [member function] + cls.add_method('DoGetRtsMode', 'ns3::WifiMode', [], visibility='private', is_virtual=True) + return + +def register_Ns3WifiModeChecker_methods(root_module, cls): + cls.add_constructor([]) + return + +def register_Ns3WifiModeFactory_methods(root_module, cls): + ## wifi-mode.h: static ns3::WifiMode ns3::WifiModeFactory::CreateBpsk(std::string uniqueName, bool isMandatory, uint32_t bandwidth, uint32_t dataRate, uint32_t phyRate) [member function] + cls.add_method('CreateBpsk', 'ns3::WifiMode', [param('std::string', 'uniqueName'), param('bool', 'isMandatory'), param('uint32_t', 'bandwidth'), param('uint32_t', 'dataRate'), param('uint32_t', 'phyRate')], is_static=True) + ## wifi-mode.h: static ns3::WifiMode ns3::WifiModeFactory::CreateQam(std::string uniqueName, bool isMandatory, uint32_t bandwidth, uint32_t dataRate, uint32_t phyRate, uint8_t constellationSize) [member function] + cls.add_method('CreateQam', 'ns3::WifiMode', [param('std::string', 'uniqueName'), param('bool', 'isMandatory'), param('uint32_t', 'bandwidth'), param('uint32_t', 'dataRate'), param('uint32_t', 'phyRate'), param('uint8_t', 'constellationSize')], is_static=True) + return + +def register_Ns3OnoeWifiRemoteStation_methods(root_module, cls): + ## onoe-wifi-manager.h: ns3::OnoeWifiRemoteStation::OnoeWifiRemoteStation(ns3::Ptr stations) [constructor] + cls.add_constructor([param('ns3::Ptr< ns3::OnoeWifiManager >', 'stations')], visibility='public') + ## onoe-wifi-manager.h: void ns3::OnoeWifiRemoteStation::DoReportRxOk(double rxSnr, ns3::WifiMode txMode) [member function] + cls.add_method('DoReportRxOk', 'void', [param('double', 'rxSnr'), param('ns3::WifiMode', 'txMode')], visibility='protected', is_virtual=True) + ## onoe-wifi-manager.h: void ns3::OnoeWifiRemoteStation::DoReportRtsFailed() [member function] + cls.add_method('DoReportRtsFailed', 'void', [], visibility='protected', is_virtual=True) + ## onoe-wifi-manager.h: void ns3::OnoeWifiRemoteStation::DoReportDataFailed() [member function] + cls.add_method('DoReportDataFailed', 'void', [], visibility='protected', is_virtual=True) + ## onoe-wifi-manager.h: void ns3::OnoeWifiRemoteStation::DoReportRtsOk(double ctsSnr, ns3::WifiMode ctsMode, double rtsSnr) [member function] + cls.add_method('DoReportRtsOk', 'void', [param('double', 'ctsSnr'), param('ns3::WifiMode', 'ctsMode'), param('double', 'rtsSnr')], visibility='protected', is_virtual=True) + ## onoe-wifi-manager.h: void ns3::OnoeWifiRemoteStation::DoReportDataOk(double ackSnr, ns3::WifiMode ackMode, double dataSnr) [member function] + cls.add_method('DoReportDataOk', 'void', [param('double', 'ackSnr'), param('ns3::WifiMode', 'ackMode'), param('double', 'dataSnr')], visibility='protected', is_virtual=True) + ## onoe-wifi-manager.h: void ns3::OnoeWifiRemoteStation::DoReportFinalRtsFailed() [member function] + cls.add_method('DoReportFinalRtsFailed', 'void', [], visibility='protected', is_virtual=True) + ## onoe-wifi-manager.h: void ns3::OnoeWifiRemoteStation::DoReportFinalDataFailed() [member function] + cls.add_method('DoReportFinalDataFailed', 'void', [], visibility='protected', is_virtual=True) + ## onoe-wifi-manager.h: ns3::Ptr ns3::OnoeWifiRemoteStation::GetManager() const [member function] + cls.add_method('GetManager', 'ns3::Ptr< ns3::WifiRemoteStationManager >', [], is_const=True, visibility='private', is_virtual=True) + ## onoe-wifi-manager.h: ns3::WifiMode ns3::OnoeWifiRemoteStation::DoGetDataMode(uint32_t size) [member function] + cls.add_method('DoGetDataMode', 'ns3::WifiMode', [param('uint32_t', 'size')], visibility='private', is_virtual=True) + ## onoe-wifi-manager.h: ns3::WifiMode ns3::OnoeWifiRemoteStation::DoGetRtsMode() [member function] + cls.add_method('DoGetRtsMode', 'ns3::WifiMode', [], visibility='private', is_virtual=True) + return + +def register_Ns3RraaWifiRemoteStation_methods(root_module, cls): + ## rraa-wifi-manager.h: ns3::RraaWifiRemoteStation::RraaWifiRemoteStation(ns3::Ptr stations) [constructor] + cls.add_constructor([param('ns3::Ptr< ns3::RraaWifiManager >', 'stations')], visibility='public') + ## rraa-wifi-manager.h: bool ns3::RraaWifiRemoteStation::NeedRts(ns3::Ptr packet) [member function] + cls.add_method('NeedRts', 'bool', [param('ns3::Ptr< const ns3::Packet >', 'packet')], is_virtual=True) + ## rraa-wifi-manager.h: void ns3::RraaWifiRemoteStation::DoReportRxOk(double rxSnr, ns3::WifiMode txMode) [member function] + cls.add_method('DoReportRxOk', 'void', [param('double', 'rxSnr'), param('ns3::WifiMode', 'txMode')], visibility='protected', is_virtual=True) + ## rraa-wifi-manager.h: void ns3::RraaWifiRemoteStation::DoReportRtsFailed() [member function] + cls.add_method('DoReportRtsFailed', 'void', [], visibility='protected', is_virtual=True) + ## rraa-wifi-manager.h: void ns3::RraaWifiRemoteStation::DoReportDataFailed() [member function] + cls.add_method('DoReportDataFailed', 'void', [], visibility='protected', is_virtual=True) + ## rraa-wifi-manager.h: void ns3::RraaWifiRemoteStation::DoReportRtsOk(double ctsSnr, ns3::WifiMode ctsMode, double rtsSnr) [member function] + cls.add_method('DoReportRtsOk', 'void', [param('double', 'ctsSnr'), param('ns3::WifiMode', 'ctsMode'), param('double', 'rtsSnr')], visibility='protected', is_virtual=True) + ## rraa-wifi-manager.h: void ns3::RraaWifiRemoteStation::DoReportDataOk(double ackSnr, ns3::WifiMode ackMode, double dataSnr) [member function] + cls.add_method('DoReportDataOk', 'void', [param('double', 'ackSnr'), param('ns3::WifiMode', 'ackMode'), param('double', 'dataSnr')], visibility='protected', is_virtual=True) + ## rraa-wifi-manager.h: void ns3::RraaWifiRemoteStation::DoReportFinalRtsFailed() [member function] + cls.add_method('DoReportFinalRtsFailed', 'void', [], visibility='protected', is_virtual=True) + ## rraa-wifi-manager.h: void ns3::RraaWifiRemoteStation::DoReportFinalDataFailed() [member function] + cls.add_method('DoReportFinalDataFailed', 'void', [], visibility='protected', is_virtual=True) + ## rraa-wifi-manager.h: ns3::Ptr ns3::RraaWifiRemoteStation::GetManager() const [member function] + cls.add_method('GetManager', 'ns3::Ptr< ns3::WifiRemoteStationManager >', [], is_const=True, visibility='private', is_virtual=True) + ## rraa-wifi-manager.h: ns3::WifiMode ns3::RraaWifiRemoteStation::DoGetDataMode(uint32_t size) [member function] + cls.add_method('DoGetDataMode', 'ns3::WifiMode', [param('uint32_t', 'size')], visibility='private', is_virtual=True) + ## rraa-wifi-manager.h: ns3::WifiMode ns3::RraaWifiRemoteStation::DoGetRtsMode() [member function] + cls.add_method('DoGetRtsMode', 'ns3::WifiMode', [], visibility='private', is_virtual=True) + return + +def register_Ns3Ssid_methods(root_module, cls): + ## ssid.h: ns3::Ssid::Ssid(ns3::Ssid const & arg0) [copy constructor] + cls.add_constructor([param('ns3::Ssid&', 'arg0', is_const=True)], visibility='public') + ## ssid.h: ns3::Ssid::Ssid() [constructor] + cls.add_constructor([], visibility='public') + ## ssid.h: ns3::Ssid::Ssid(char const * ssid) [constructor] + cls.add_constructor([param('char *', 'ssid', transfer_ownership=False, is_const=True)], visibility='public') + ## ssid.h: ns3::Ssid::Ssid(char const * ssid, uint8_t length) [constructor] + cls.add_constructor([param('char *', 'ssid', transfer_ownership=False, is_const=True), param('uint8_t', 'length')], visibility='public') + ## ssid.h: ns3::Buffer::Iterator ns3::Ssid::Deserialize(ns3::Buffer::Iterator i) [member function] + cls.add_method('Deserialize', 'ns3::Buffer::Iterator', [param('ns3::Buffer::Iterator', 'i')]) + ## ssid.h: uint32_t ns3::Ssid::GetLength() const [member function] + cls.add_method('GetLength', 'uint32_t', [], is_const=True) + ## ssid.h: uint32_t ns3::Ssid::GetSerializedSize() const [member function] + cls.add_method('GetSerializedSize', 'uint32_t', [], is_const=True) + ## ssid.h: bool ns3::Ssid::IsBroadcast() const [member function] + cls.add_method('IsBroadcast', 'bool', [], is_const=True) + ## ssid.h: bool ns3::Ssid::IsEqual(ns3::Ssid const & o) const [member function] + cls.add_method('IsEqual', 'bool', [param('ns3::Ssid&', 'o', is_const=True)], is_const=True) + ## ssid.h: char * ns3::Ssid::PeekString() const [member function] + cls.add_method('PeekString', 'char *', [], is_const=True) + ## ssid.h: ns3::Buffer::Iterator ns3::Ssid::Serialize(ns3::Buffer::Iterator i) const [member function] + cls.add_method('Serialize', 'ns3::Buffer::Iterator', [param('ns3::Buffer::Iterator', 'i')], is_const=True) + cls.add_output_stream_operator() + return + +def register_Ns3WifiMode_methods(root_module, cls): + ## wifi-mode.h: ns3::WifiMode::WifiMode(ns3::WifiMode const & arg0) [copy constructor] + cls.add_constructor([param('ns3::WifiMode&', 'arg0', is_const=True)], visibility='public') + ## wifi-mode.h: ns3::WifiMode::WifiMode() [constructor] + cls.add_constructor([], visibility='public') + ## wifi-mode.h: uint32_t ns3::WifiMode::GetBandwidth() const [member function] + cls.add_method('GetBandwidth', 'uint32_t', [], is_const=True) + ## wifi-mode.h: uint8_t ns3::WifiMode::GetConstellationSize() const [member function] + cls.add_method('GetConstellationSize', 'uint8_t', [], is_const=True) + ## wifi-mode.h: uint32_t ns3::WifiMode::GetDataRate() const [member function] + cls.add_method('GetDataRate', 'uint32_t', [], is_const=True) + ## wifi-mode.h: ns3::WifiMode::ModulationType ns3::WifiMode::GetModulationType() const [member function] + cls.add_method('GetModulationType', 'ns3::WifiMode::ModulationType', [], is_const=True) + ## wifi-mode.h: uint32_t ns3::WifiMode::GetPhyRate() const [member function] + cls.add_method('GetPhyRate', 'uint32_t', [], is_const=True) + ## wifi-mode.h: uint32_t ns3::WifiMode::GetUid() const [member function] + cls.add_method('GetUid', 'uint32_t', [], is_const=True) + ## wifi-mode.h: std::string ns3::WifiMode::GetUniqueName() const [member function] + cls.add_method('GetUniqueName', 'std::string', [], is_const=True) + ## wifi-mode.h: bool ns3::WifiMode::IsMandatory() const [member function] + cls.add_method('IsMandatory', 'bool', [], is_const=True) + ## wifi-mode.h: bool ns3::WifiMode::IsModulationBpsk() const [member function] + cls.add_method('IsModulationBpsk', 'bool', [], is_const=True) + ## wifi-mode.h: bool ns3::WifiMode::IsModulationQam() const [member function] + cls.add_method('IsModulationQam', 'bool', [], is_const=True) + cls.add_output_stream_operator() + return + +def register_Ns3SsidValue_methods(root_module, cls): + ## ssid.h: ns3::SsidValue::SsidValue() [constructor] + cls.add_constructor([], visibility='public') + ## ssid.h: ns3::SsidValue::SsidValue(ns3::Ssid const & value) [constructor] + cls.add_constructor([param('ns3::Ssid&', 'value', is_const=True)], visibility='public') + ## ssid.h: void ns3::SsidValue::Set(ns3::Ssid const & value) [member function] + cls.add_method('Set', 'void', [param('ns3::Ssid&', 'value', is_const=True)]) + ## ssid.h: ns3::Ssid ns3::SsidValue::Get() const [member function] + cls.add_method('Get', 'ns3::Ssid', [], is_const=True) + ## ssid.h: ns3::Ptr ns3::SsidValue::Copy() const [member function] + cls.add_method('Copy', 'ns3::Ptr< ns3::AttributeValue >', [], is_const=True, is_virtual=True) + ## ssid.h: std::string ns3::SsidValue::SerializeToString(ns3::Ptr checker) const [member function] + cls.add_method('SerializeToString', 'std::string', [param('ns3::Ptr< ns3::AttributeChecker const >', 'checker')], is_const=True, is_virtual=True) + ## ssid.h: bool ns3::SsidValue::DeserializeFromString(std::string value, ns3::Ptr checker) [member function] + cls.add_method('DeserializeFromString', 'bool', [param('std::string', 'value'), param('ns3::Ptr< ns3::AttributeChecker const >', 'checker')], is_virtual=True) + return + +def register_Ns3SsidChecker_methods(root_module, cls): + cls.add_constructor([]) + return + +def register_Ns3ConstantRateWifiRemoteStation_methods(root_module, cls): + ## constant-rate-wifi-manager.h: ns3::ConstantRateWifiRemoteStation::ConstantRateWifiRemoteStation(ns3::Ptr stations) [constructor] + cls.add_constructor([param('ns3::Ptr< ns3::ConstantRateWifiManager >', 'stations')], visibility='public') + ## constant-rate-wifi-manager.h: void ns3::ConstantRateWifiRemoteStation::DoReportRxOk(double rxSnr, ns3::WifiMode txMode) [member function] + cls.add_method('DoReportRxOk', 'void', [param('double', 'rxSnr'), param('ns3::WifiMode', 'txMode')], visibility='protected', is_virtual=True) + ## constant-rate-wifi-manager.h: void ns3::ConstantRateWifiRemoteStation::DoReportRtsFailed() [member function] + cls.add_method('DoReportRtsFailed', 'void', [], visibility='protected', is_virtual=True) + ## constant-rate-wifi-manager.h: void ns3::ConstantRateWifiRemoteStation::DoReportDataFailed() [member function] + cls.add_method('DoReportDataFailed', 'void', [], visibility='protected', is_virtual=True) + ## constant-rate-wifi-manager.h: void ns3::ConstantRateWifiRemoteStation::DoReportRtsOk(double ctsSnr, ns3::WifiMode ctsMode, double rtsSnr) [member function] + cls.add_method('DoReportRtsOk', 'void', [param('double', 'ctsSnr'), param('ns3::WifiMode', 'ctsMode'), param('double', 'rtsSnr')], visibility='protected', is_virtual=True) + ## constant-rate-wifi-manager.h: void ns3::ConstantRateWifiRemoteStation::DoReportDataOk(double ackSnr, ns3::WifiMode ackMode, double dataSnr) [member function] + cls.add_method('DoReportDataOk', 'void', [param('double', 'ackSnr'), param('ns3::WifiMode', 'ackMode'), param('double', 'dataSnr')], visibility='protected', is_virtual=True) + ## constant-rate-wifi-manager.h: void ns3::ConstantRateWifiRemoteStation::DoReportFinalRtsFailed() [member function] + cls.add_method('DoReportFinalRtsFailed', 'void', [], visibility='protected', is_virtual=True) + ## constant-rate-wifi-manager.h: void ns3::ConstantRateWifiRemoteStation::DoReportFinalDataFailed() [member function] + cls.add_method('DoReportFinalDataFailed', 'void', [], visibility='protected', is_virtual=True) + ## constant-rate-wifi-manager.h: ns3::Ptr ns3::ConstantRateWifiRemoteStation::GetManager() const [member function] + cls.add_method('GetManager', 'ns3::Ptr< ns3::WifiRemoteStationManager >', [], is_const=True, visibility='private', is_virtual=True) + ## constant-rate-wifi-manager.h: ns3::WifiMode ns3::ConstantRateWifiRemoteStation::DoGetDataMode(uint32_t size) [member function] + cls.add_method('DoGetDataMode', 'ns3::WifiMode', [param('uint32_t', 'size')], visibility='private', is_virtual=True) + ## constant-rate-wifi-manager.h: ns3::WifiMode ns3::ConstantRateWifiRemoteStation::DoGetRtsMode() [member function] + cls.add_method('DoGetRtsMode', 'ns3::WifiMode', [], visibility='private', is_virtual=True) + return + +def register_Ns3PropagationLossModel_methods(root_module, cls): + ## propagation-loss-model.h: static ns3::TypeId ns3::PropagationLossModel::GetTypeId() [member function] + cls.add_method('GetTypeId', 'ns3::TypeId', [], is_static=True) + ## propagation-loss-model.h: double ns3::PropagationLossModel::GetLoss(ns3::Ptr a, ns3::Ptr b) const [member function] + cls.add_method('GetLoss', 'double', [param('ns3::Ptr< ns3::MobilityModel >', 'a'), param('ns3::Ptr< ns3::MobilityModel >', 'b')], is_pure_virtual=True, is_const=True, is_virtual=True) + cls.add_constructor([]) + return + +def register_Ns3ArfWifiRemoteStation_methods(root_module, cls): + ## arf-wifi-manager.h: ns3::ArfWifiRemoteStation::ArfWifiRemoteStation(ns3::Ptr stations, int minTimerTimeout, int minSuccessThreshold) [constructor] + cls.add_constructor([param('ns3::Ptr< ns3::ArfWifiManager >', 'stations'), param('int', 'minTimerTimeout'), param('int', 'minSuccessThreshold')], visibility='public') + ## arf-wifi-manager.h: void ns3::ArfWifiRemoteStation::DoReportRxOk(double rxSnr, ns3::WifiMode txMode) [member function] + cls.add_method('DoReportRxOk', 'void', [param('double', 'rxSnr'), param('ns3::WifiMode', 'txMode')], visibility='protected', is_virtual=True) + ## arf-wifi-manager.h: void ns3::ArfWifiRemoteStation::DoReportRtsFailed() [member function] + cls.add_method('DoReportRtsFailed', 'void', [], visibility='protected', is_virtual=True) + ## arf-wifi-manager.h: void ns3::ArfWifiRemoteStation::DoReportDataFailed() [member function] + cls.add_method('DoReportDataFailed', 'void', [], visibility='protected', is_virtual=True) + ## arf-wifi-manager.h: void ns3::ArfWifiRemoteStation::DoReportRtsOk(double ctsSnr, ns3::WifiMode ctsMode, double rtsSnr) [member function] + cls.add_method('DoReportRtsOk', 'void', [param('double', 'ctsSnr'), param('ns3::WifiMode', 'ctsMode'), param('double', 'rtsSnr')], visibility='protected', is_virtual=True) + ## arf-wifi-manager.h: void ns3::ArfWifiRemoteStation::DoReportDataOk(double ackSnr, ns3::WifiMode ackMode, double dataSnr) [member function] + cls.add_method('DoReportDataOk', 'void', [param('double', 'ackSnr'), param('ns3::WifiMode', 'ackMode'), param('double', 'dataSnr')], visibility='protected', is_virtual=True) + ## arf-wifi-manager.h: void ns3::ArfWifiRemoteStation::DoReportFinalRtsFailed() [member function] + cls.add_method('DoReportFinalRtsFailed', 'void', [], visibility='protected', is_virtual=True) + ## arf-wifi-manager.h: void ns3::ArfWifiRemoteStation::DoReportFinalDataFailed() [member function] + cls.add_method('DoReportFinalDataFailed', 'void', [], visibility='protected', is_virtual=True) + ## arf-wifi-manager.h: uint32_t ns3::ArfWifiRemoteStation::GetMinTimerTimeout() [member function] + cls.add_method('GetMinTimerTimeout', 'uint32_t', [], visibility='protected') + ## arf-wifi-manager.h: uint32_t ns3::ArfWifiRemoteStation::GetMinSuccessThreshold() [member function] + cls.add_method('GetMinSuccessThreshold', 'uint32_t', [], visibility='protected') + ## arf-wifi-manager.h: uint32_t ns3::ArfWifiRemoteStation::GetTimerTimeout() [member function] + cls.add_method('GetTimerTimeout', 'uint32_t', [], visibility='protected') + ## arf-wifi-manager.h: uint32_t ns3::ArfWifiRemoteStation::GetSuccessThreshold() [member function] + cls.add_method('GetSuccessThreshold', 'uint32_t', [], visibility='protected') + ## arf-wifi-manager.h: void ns3::ArfWifiRemoteStation::SetTimerTimeout(uint32_t timerTimeout) [member function] + cls.add_method('SetTimerTimeout', 'void', [param('uint32_t', 'timerTimeout')], visibility='protected') + ## arf-wifi-manager.h: void ns3::ArfWifiRemoteStation::SetSuccessThreshold(uint32_t successThreshold) [member function] + cls.add_method('SetSuccessThreshold', 'void', [param('uint32_t', 'successThreshold')], visibility='protected') + ## arf-wifi-manager.h: ns3::Ptr ns3::ArfWifiRemoteStation::GetManager() const [member function] + cls.add_method('GetManager', 'ns3::Ptr< ns3::WifiRemoteStationManager >', [], is_const=True, visibility='private', is_virtual=True) + ## arf-wifi-manager.h: ns3::WifiMode ns3::ArfWifiRemoteStation::DoGetDataMode(uint32_t size) [member function] + cls.add_method('DoGetDataMode', 'ns3::WifiMode', [param('uint32_t', 'size')], visibility='private', is_virtual=True) + ## arf-wifi-manager.h: ns3::WifiMode ns3::ArfWifiRemoteStation::DoGetRtsMode() [member function] + cls.add_method('DoGetRtsMode', 'ns3::WifiMode', [], visibility='private', is_virtual=True) + ## arf-wifi-manager.h: void ns3::ArfWifiRemoteStation::ReportRecoveryFailure() [member function] + cls.add_method('ReportRecoveryFailure', 'void', [], visibility='private', is_virtual=True) + ## arf-wifi-manager.h: void ns3::ArfWifiRemoteStation::ReportFailure() [member function] + cls.add_method('ReportFailure', 'void', [], visibility='private', is_virtual=True) + return + +def register_Ns3WifiMac_methods(root_module, cls): + ## wifi-mac.h: static ns3::TypeId ns3::WifiMac::GetTypeId() [member function] + cls.add_method('GetTypeId', 'ns3::TypeId', [], is_static=True) + ## wifi-mac.h: void ns3::WifiMac::SetSlot(ns3::Time slotTime) [member function] + cls.add_method('SetSlot', 'void', [param('ns3::Time', 'slotTime')], is_pure_virtual=True, is_virtual=True) + ## wifi-mac.h: void ns3::WifiMac::SetSifs(ns3::Time sifs) [member function] + cls.add_method('SetSifs', 'void', [param('ns3::Time', 'sifs')], is_pure_virtual=True, is_virtual=True) + ## wifi-mac.h: void ns3::WifiMac::SetEifsNoDifs(ns3::Time eifsNoDifs) [member function] + cls.add_method('SetEifsNoDifs', 'void', [param('ns3::Time', 'eifsNoDifs')], is_pure_virtual=True, is_virtual=True) + ## wifi-mac.h: void ns3::WifiMac::SetPifs(ns3::Time pifs) [member function] + cls.add_method('SetPifs', 'void', [param('ns3::Time', 'pifs')]) + ## wifi-mac.h: void ns3::WifiMac::SetCtsTimeout(ns3::Time ctsTimeout) [member function] + cls.add_method('SetCtsTimeout', 'void', [param('ns3::Time', 'ctsTimeout')]) + ## wifi-mac.h: void ns3::WifiMac::SetAckTimeout(ns3::Time ackTimeout) [member function] + cls.add_method('SetAckTimeout', 'void', [param('ns3::Time', 'ackTimeout')]) + ## wifi-mac.h: void ns3::WifiMac::SetMaxPropagationDelay(ns3::Time delay) [member function] + cls.add_method('SetMaxPropagationDelay', 'void', [param('ns3::Time', 'delay')]) + ## wifi-mac.h: ns3::Time ns3::WifiMac::GetPifs() const [member function] + cls.add_method('GetPifs', 'ns3::Time', [], is_const=True) + ## wifi-mac.h: ns3::Time ns3::WifiMac::GetSifs() const [member function] + cls.add_method('GetSifs', 'ns3::Time', [], is_pure_virtual=True, is_const=True, is_virtual=True) + ## wifi-mac.h: ns3::Time ns3::WifiMac::GetSlot() const [member function] + cls.add_method('GetSlot', 'ns3::Time', [], is_pure_virtual=True, is_const=True, is_virtual=True) + ## wifi-mac.h: ns3::Time ns3::WifiMac::GetEifsNoDifs() const [member function] + cls.add_method('GetEifsNoDifs', 'ns3::Time', [], is_pure_virtual=True, is_const=True, is_virtual=True) + ## wifi-mac.h: ns3::Time ns3::WifiMac::GetCtsTimeout() const [member function] + cls.add_method('GetCtsTimeout', 'ns3::Time', [], is_const=True) + ## wifi-mac.h: ns3::Time ns3::WifiMac::GetAckTimeout() const [member function] + cls.add_method('GetAckTimeout', 'ns3::Time', [], is_const=True) + ## wifi-mac.h: ns3::Time ns3::WifiMac::GetMsduLifetime() const [member function] + cls.add_method('GetMsduLifetime', 'ns3::Time', [], is_const=True) + ## wifi-mac.h: ns3::Time ns3::WifiMac::GetMaxPropagationDelay() const [member function] + cls.add_method('GetMaxPropagationDelay', 'ns3::Time', [], is_const=True) + ## wifi-mac.h: uint32_t ns3::WifiMac::GetMaxMsduSize() const [member function] + cls.add_method('GetMaxMsduSize', 'uint32_t', [], is_const=True) + ## wifi-mac.h: ns3::Mac48Address ns3::WifiMac::GetAddress() const [member function] + cls.add_method('GetAddress', 'ns3::Mac48Address', [], is_pure_virtual=True, is_const=True, is_virtual=True) + ## wifi-mac.h: ns3::Ssid ns3::WifiMac::GetSsid() const [member function] + cls.add_method('GetSsid', 'ns3::Ssid', [], is_pure_virtual=True, is_const=True, is_virtual=True) + ## wifi-mac.h: ns3::Mac48Address ns3::WifiMac::GetBssid() const [member function] + cls.add_method('GetBssid', 'ns3::Mac48Address', [], is_pure_virtual=True, is_const=True, is_virtual=True) + ## wifi-mac.h: void ns3::WifiMac::SetAddress(ns3::Mac48Address address) [member function] + cls.add_method('SetAddress', 'void', [param('ns3::Mac48Address', 'address')], is_pure_virtual=True, is_virtual=True) + ## wifi-mac.h: void ns3::WifiMac::SetSsid(ns3::Ssid ssid) [member function] + cls.add_method('SetSsid', 'void', [param('ns3::Ssid', 'ssid')], is_pure_virtual=True, is_virtual=True) + ## wifi-mac.h: void ns3::WifiMac::Enqueue(ns3::Ptr packet, ns3::Mac48Address to) [member function] + cls.add_method('Enqueue', 'void', [param('ns3::Ptr< const ns3::Packet >', 'packet'), param('ns3::Mac48Address', 'to')], is_pure_virtual=True, visibility='private', is_virtual=True) + ## wifi-mac.h: void ns3::WifiMac::SetWifiPhy(ns3::Ptr phy) [member function] + cls.add_method('SetWifiPhy', 'void', [param('ns3::Ptr< ns3::WifiPhy >', 'phy')], is_pure_virtual=True, visibility='private', is_virtual=True) + ## wifi-mac.h: void ns3::WifiMac::SetWifiRemoteStationManager(ns3::Ptr stationManager) [member function] + cls.add_method('SetWifiRemoteStationManager', 'void', [param('ns3::Ptr< ns3::WifiRemoteStationManager >', 'stationManager')], is_pure_virtual=True, visibility='private', is_virtual=True) + ## wifi-mac.h: void ns3::WifiMac::SetForwardUpCallback(ns3::Callback, ns3::Mac48Address const&, ns3::empty, ns3::empty, ns3::empty, ns3::empty> upCallback) [member function] + cls.add_method('SetForwardUpCallback', 'void', [param('ns3::Callback< void, ns3::Ptr< ns3::Packet >, ns3::Mac48Address const&, ns3::empty, ns3::empty, ns3::empty, ns3::empty >', 'upCallback')], is_pure_virtual=True, visibility='private', is_virtual=True) + ## wifi-mac.h: void ns3::WifiMac::SetLinkUpCallback(ns3::Callback linkUp) [member function] + cls.add_method('SetLinkUpCallback', 'void', [param('ns3::Callback< void, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty >', 'linkUp')], is_pure_virtual=True, visibility='private', is_virtual=True) + ## wifi-mac.h: void ns3::WifiMac::SetLinkDownCallback(ns3::Callback linkDown) [member function] + cls.add_method('SetLinkDownCallback', 'void', [param('ns3::Callback< void, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty >', 'linkDown')], is_pure_virtual=True, visibility='private', is_virtual=True) + cls.add_constructor([]) + return + +def register_Ns3NqapWifiMac_methods(root_module, cls): + ## nqap-wifi-mac.h: static ns3::TypeId ns3::NqapWifiMac::GetTypeId() [member function] + cls.add_method('GetTypeId', 'ns3::TypeId', [], is_static=True) + ## nqap-wifi-mac.h: ns3::NqapWifiMac::NqapWifiMac() [constructor] + cls.add_constructor([], visibility='public') + ## nqap-wifi-mac.h: void ns3::NqapWifiMac::SetSlot(ns3::Time slotTime) [member function] + cls.add_method('SetSlot', 'void', [param('ns3::Time', 'slotTime')], is_virtual=True) + ## nqap-wifi-mac.h: void ns3::NqapWifiMac::SetSifs(ns3::Time sifs) [member function] + cls.add_method('SetSifs', 'void', [param('ns3::Time', 'sifs')], is_virtual=True) + ## nqap-wifi-mac.h: void ns3::NqapWifiMac::SetEifsNoDifs(ns3::Time eifsNoDifs) [member function] + cls.add_method('SetEifsNoDifs', 'void', [param('ns3::Time', 'eifsNoDifs')], is_virtual=True) + ## nqap-wifi-mac.h: ns3::Time ns3::NqapWifiMac::GetSlot() const [member function] + cls.add_method('GetSlot', 'ns3::Time', [], is_const=True, is_virtual=True) + ## nqap-wifi-mac.h: ns3::Time ns3::NqapWifiMac::GetSifs() const [member function] + cls.add_method('GetSifs', 'ns3::Time', [], is_const=True, is_virtual=True) + ## nqap-wifi-mac.h: ns3::Time ns3::NqapWifiMac::GetEifsNoDifs() const [member function] + cls.add_method('GetEifsNoDifs', 'ns3::Time', [], is_const=True, is_virtual=True) + ## nqap-wifi-mac.h: void ns3::NqapWifiMac::SetWifiPhy(ns3::Ptr phy) [member function] + cls.add_method('SetWifiPhy', 'void', [param('ns3::Ptr< ns3::WifiPhy >', 'phy')], is_virtual=True) + ## nqap-wifi-mac.h: void ns3::NqapWifiMac::SetWifiRemoteStationManager(ns3::Ptr stationManager) [member function] + cls.add_method('SetWifiRemoteStationManager', 'void', [param('ns3::Ptr< ns3::WifiRemoteStationManager >', 'stationManager')], is_virtual=True) + ## nqap-wifi-mac.h: void ns3::NqapWifiMac::Enqueue(ns3::Ptr packet, ns3::Mac48Address to) [member function] + cls.add_method('Enqueue', 'void', [param('ns3::Ptr< const ns3::Packet >', 'packet'), param('ns3::Mac48Address', 'to')], is_virtual=True) + ## nqap-wifi-mac.h: void ns3::NqapWifiMac::SetForwardUpCallback(ns3::Callback, ns3::Mac48Address const&, ns3::empty, ns3::empty, ns3::empty, ns3::empty> upCallback) [member function] + cls.add_method('SetForwardUpCallback', 'void', [param('ns3::Callback< void, ns3::Ptr< ns3::Packet >, ns3::Mac48Address const&, ns3::empty, ns3::empty, ns3::empty, ns3::empty >', 'upCallback')], is_virtual=True) + ## nqap-wifi-mac.h: void ns3::NqapWifiMac::SetLinkUpCallback(ns3::Callback linkUp) [member function] + cls.add_method('SetLinkUpCallback', 'void', [param('ns3::Callback< void, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty >', 'linkUp')], is_virtual=True) + ## nqap-wifi-mac.h: void ns3::NqapWifiMac::SetLinkDownCallback(ns3::Callback linkDown) [member function] + cls.add_method('SetLinkDownCallback', 'void', [param('ns3::Callback< void, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty >', 'linkDown')], is_virtual=True) + ## nqap-wifi-mac.h: ns3::Mac48Address ns3::NqapWifiMac::GetAddress() const [member function] + cls.add_method('GetAddress', 'ns3::Mac48Address', [], is_const=True, is_virtual=True) + ## nqap-wifi-mac.h: ns3::Ssid ns3::NqapWifiMac::GetSsid() const [member function] + cls.add_method('GetSsid', 'ns3::Ssid', [], is_const=True, is_virtual=True) + ## nqap-wifi-mac.h: ns3::Mac48Address ns3::NqapWifiMac::GetBssid() const [member function] + cls.add_method('GetBssid', 'ns3::Mac48Address', [], is_const=True, is_virtual=True) + ## nqap-wifi-mac.h: void ns3::NqapWifiMac::SetAddress(ns3::Mac48Address address) [member function] + cls.add_method('SetAddress', 'void', [param('ns3::Mac48Address', 'address')], is_virtual=True) + ## nqap-wifi-mac.h: void ns3::NqapWifiMac::SetSsid(ns3::Ssid ssid) [member function] + cls.add_method('SetSsid', 'void', [param('ns3::Ssid', 'ssid')], is_virtual=True) + ## nqap-wifi-mac.h: void ns3::NqapWifiMac::SetBeaconInterval(ns3::Time interval) [member function] + cls.add_method('SetBeaconInterval', 'void', [param('ns3::Time', 'interval')]) + ## nqap-wifi-mac.h: void ns3::NqapWifiMac::StartBeaconing() [member function] + cls.add_method('StartBeaconing', 'void', []) + ## nqap-wifi-mac.h: void ns3::NqapWifiMac::DoDispose() [member function] + cls.add_method('DoDispose', 'void', [], visibility='private', is_virtual=True) + return + +def register_Ns3AmrrWifiRemoteStation_methods(root_module, cls): + ## amrr-wifi-manager.h: ns3::AmrrWifiRemoteStation::AmrrWifiRemoteStation(ns3::Ptr stations) [constructor] + cls.add_constructor([param('ns3::Ptr< ns3::AmrrWifiManager >', 'stations')], visibility='public') + ## amrr-wifi-manager.h: void ns3::AmrrWifiRemoteStation::DoReportRxOk(double rxSnr, ns3::WifiMode txMode) [member function] + cls.add_method('DoReportRxOk', 'void', [param('double', 'rxSnr'), param('ns3::WifiMode', 'txMode')], visibility='protected', is_virtual=True) + ## amrr-wifi-manager.h: void ns3::AmrrWifiRemoteStation::DoReportRtsFailed() [member function] + cls.add_method('DoReportRtsFailed', 'void', [], visibility='protected', is_virtual=True) + ## amrr-wifi-manager.h: void ns3::AmrrWifiRemoteStation::DoReportDataFailed() [member function] + cls.add_method('DoReportDataFailed', 'void', [], visibility='protected', is_virtual=True) + ## amrr-wifi-manager.h: void ns3::AmrrWifiRemoteStation::DoReportRtsOk(double ctsSnr, ns3::WifiMode ctsMode, double rtsSnr) [member function] + cls.add_method('DoReportRtsOk', 'void', [param('double', 'ctsSnr'), param('ns3::WifiMode', 'ctsMode'), param('double', 'rtsSnr')], visibility='protected', is_virtual=True) + ## amrr-wifi-manager.h: void ns3::AmrrWifiRemoteStation::DoReportDataOk(double ackSnr, ns3::WifiMode ackMode, double dataSnr) [member function] + cls.add_method('DoReportDataOk', 'void', [param('double', 'ackSnr'), param('ns3::WifiMode', 'ackMode'), param('double', 'dataSnr')], visibility='protected', is_virtual=True) + ## amrr-wifi-manager.h: void ns3::AmrrWifiRemoteStation::DoReportFinalRtsFailed() [member function] + cls.add_method('DoReportFinalRtsFailed', 'void', [], visibility='protected', is_virtual=True) + ## amrr-wifi-manager.h: void ns3::AmrrWifiRemoteStation::DoReportFinalDataFailed() [member function] + cls.add_method('DoReportFinalDataFailed', 'void', [], visibility='protected', is_virtual=True) + ## amrr-wifi-manager.h: ns3::Ptr ns3::AmrrWifiRemoteStation::GetManager() const [member function] + cls.add_method('GetManager', 'ns3::Ptr< ns3::WifiRemoteStationManager >', [], is_const=True, visibility='private', is_virtual=True) + ## amrr-wifi-manager.h: ns3::WifiMode ns3::AmrrWifiRemoteStation::DoGetDataMode(uint32_t size) [member function] + cls.add_method('DoGetDataMode', 'ns3::WifiMode', [param('uint32_t', 'size')], visibility='private', is_virtual=True) + ## amrr-wifi-manager.h: ns3::WifiMode ns3::AmrrWifiRemoteStation::DoGetRtsMode() [member function] + cls.add_method('DoGetRtsMode', 'ns3::WifiMode', [], visibility='private', is_virtual=True) + return + +def register_Ns3CompositePropagationLossModel_methods(root_module, cls): + ## composite-propagation-loss-model.h: static ns3::TypeId ns3::CompositePropagationLossModel::GetTypeId() [member function] + cls.add_method('GetTypeId', 'ns3::TypeId', [], is_static=True) + ## composite-propagation-loss-model.h: ns3::CompositePropagationLossModel::CompositePropagationLossModel() [constructor] + cls.add_constructor([], visibility='public') + ## composite-propagation-loss-model.h: double ns3::CompositePropagationLossModel::GetLoss(ns3::Ptr a, ns3::Ptr b) const [member function] + cls.add_method('GetLoss', 'double', [param('ns3::Ptr< ns3::MobilityModel >', 'a'), param('ns3::Ptr< ns3::MobilityModel >', 'b')], is_const=True, is_virtual=True) + ## composite-propagation-loss-model.h: void ns3::CompositePropagationLossModel::AddPropagationLossModel(ns3::Ptr pl) [member function] + cls.add_method('AddPropagationLossModel', 'void', [param('ns3::Ptr< ns3::PropagationLossModel >', 'pl')]) + ## composite-propagation-loss-model.h: void ns3::CompositePropagationLossModel::AddDefaults() [member function] + cls.add_method('AddDefaults', 'void', [], visibility='protected', is_virtual=True) + return + +def register_Ns3FriisPropagationLossModel_methods(root_module, cls): + ## propagation-loss-model.h: static ns3::TypeId ns3::FriisPropagationLossModel::GetTypeId() [member function] + cls.add_method('GetTypeId', 'ns3::TypeId', [], is_static=True) + ## propagation-loss-model.h: ns3::FriisPropagationLossModel::FriisPropagationLossModel() [constructor] + cls.add_constructor([], visibility='public') + ## propagation-loss-model.h: void ns3::FriisPropagationLossModel::SetLambda(double frequency, double speed) [member function] + cls.add_method('SetLambda', 'void', [param('double', 'frequency'), param('double', 'speed')]) + ## propagation-loss-model.h: void ns3::FriisPropagationLossModel::SetLambda(double lambda) [member function] + cls.add_method('SetLambda', 'void', [param('double', 'lambda')]) + ## propagation-loss-model.h: void ns3::FriisPropagationLossModel::SetSystemLoss(double systemLoss) [member function] + cls.add_method('SetSystemLoss', 'void', [param('double', 'systemLoss')]) + ## propagation-loss-model.h: double ns3::FriisPropagationLossModel::GetLambda() const [member function] + cls.add_method('GetLambda', 'double', [], is_const=True) + ## propagation-loss-model.h: double ns3::FriisPropagationLossModel::GetSystemLoss() const [member function] + cls.add_method('GetSystemLoss', 'double', [], is_const=True) + ## propagation-loss-model.h: double ns3::FriisPropagationLossModel::GetLoss(ns3::Ptr a, ns3::Ptr b) const [member function] + cls.add_method('GetLoss', 'double', [param('ns3::Ptr< ns3::MobilityModel >', 'a'), param('ns3::Ptr< ns3::MobilityModel >', 'b')], is_const=True, is_virtual=True) + return + +def register_Ns3WifiRemoteStationManager_methods(root_module, cls): + ## wifi-remote-station-manager.h: static ns3::TypeId ns3::WifiRemoteStationManager::GetTypeId() [member function] + cls.add_method('GetTypeId', 'ns3::TypeId', [], is_static=True) + ## wifi-remote-station-manager.h: ns3::WifiRemoteStationManager::WifiRemoteStationManager() [constructor] + cls.add_constructor([], visibility='public') + ## wifi-remote-station-manager.h: void ns3::WifiRemoteStationManager::SetupPhy(ns3::Ptr phy) [member function] + cls.add_method('SetupPhy', 'void', [param('ns3::Ptr< ns3::WifiPhy >', 'phy')], is_virtual=True) + ## wifi-remote-station-manager.h: uint32_t ns3::WifiRemoteStationManager::GetMaxSsrc() const [member function] + cls.add_method('GetMaxSsrc', 'uint32_t', [], is_const=True) + ## wifi-remote-station-manager.h: uint32_t ns3::WifiRemoteStationManager::GetMaxSlrc() const [member function] + cls.add_method('GetMaxSlrc', 'uint32_t', [], is_const=True) + ## wifi-remote-station-manager.h: uint32_t ns3::WifiRemoteStationManager::GetRtsCtsThreshold() const [member function] + cls.add_method('GetRtsCtsThreshold', 'uint32_t', [], is_const=True) + ## wifi-remote-station-manager.h: uint32_t ns3::WifiRemoteStationManager::GetFragmentationThreshold() const [member function] + cls.add_method('GetFragmentationThreshold', 'uint32_t', [], is_const=True) + ## wifi-remote-station-manager.h: void ns3::WifiRemoteStationManager::SetMaxSsrc(uint32_t maxSsrc) [member function] + cls.add_method('SetMaxSsrc', 'void', [param('uint32_t', 'maxSsrc')]) + ## wifi-remote-station-manager.h: void ns3::WifiRemoteStationManager::SetMaxSlrc(uint32_t maxSlrc) [member function] + cls.add_method('SetMaxSlrc', 'void', [param('uint32_t', 'maxSlrc')]) + ## wifi-remote-station-manager.h: void ns3::WifiRemoteStationManager::SetRtsCtsThreshold(uint32_t threshold) [member function] + cls.add_method('SetRtsCtsThreshold', 'void', [param('uint32_t', 'threshold')]) + ## wifi-remote-station-manager.h: void ns3::WifiRemoteStationManager::SetFragmentationThreshold(uint32_t threshold) [member function] + cls.add_method('SetFragmentationThreshold', 'void', [param('uint32_t', 'threshold')]) + ## wifi-remote-station-manager.h: void ns3::WifiRemoteStationManager::Reset() [member function] + cls.add_method('Reset', 'void', []) + ## wifi-remote-station-manager.h: void ns3::WifiRemoteStationManager::AddBasicMode(ns3::WifiMode mode) [member function] + cls.add_method('AddBasicMode', 'void', [param('ns3::WifiMode', 'mode')]) + ## wifi-remote-station-manager.h: ns3::WifiMode ns3::WifiRemoteStationManager::GetDefaultMode() const [member function] + cls.add_method('GetDefaultMode', 'ns3::WifiMode', [], is_const=True) + ## wifi-remote-station-manager.h: uint32_t ns3::WifiRemoteStationManager::GetNBasicModes() const [member function] + cls.add_method('GetNBasicModes', 'uint32_t', [], is_const=True) + ## wifi-remote-station-manager.h: ns3::WifiMode ns3::WifiRemoteStationManager::GetBasicMode(uint32_t i) const [member function] + cls.add_method('GetBasicMode', 'ns3::WifiMode', [param('uint32_t', 'i')], is_const=True) + ## wifi-remote-station-manager.h: __gnu_cxx::__normal_iterator > > ns3::WifiRemoteStationManager::BeginBasicModes() const [member function] + cls.add_method('BeginBasicModes', '__gnu_cxx::__normal_iterator< const ns3::WifiMode*, std::vector< ns3::WifiMode, std::allocator< ns3::WifiMode > > >', [], is_const=True) + ## wifi-remote-station-manager.h: __gnu_cxx::__normal_iterator > > ns3::WifiRemoteStationManager::EndBasicModes() const [member function] + cls.add_method('EndBasicModes', '__gnu_cxx::__normal_iterator< const ns3::WifiMode*, std::vector< ns3::WifiMode, std::allocator< ns3::WifiMode > > >', [], is_const=True) + ## wifi-remote-station-manager.h: bool ns3::WifiRemoteStationManager::IsLowLatency() const [member function] + cls.add_method('IsLowLatency', 'bool', [], is_const=True) + ## wifi-remote-station-manager.h: ns3::WifiRemoteStation * ns3::WifiRemoteStationManager::Lookup(ns3::Mac48Address address) [member function] + cls.add_method('Lookup', 'ns3::WifiRemoteStation *', [param('ns3::Mac48Address', 'address')]) + ## wifi-remote-station-manager.h: ns3::WifiRemoteStation * ns3::WifiRemoteStationManager::LookupNonUnicast() [member function] + cls.add_method('LookupNonUnicast', 'ns3::WifiRemoteStation *', []) + ## wifi-remote-station-manager.h: void ns3::WifiRemoteStationManager::DoDispose() [member function] + cls.add_method('DoDispose', 'void', [], visibility='protected', is_virtual=True) + ## wifi-remote-station-manager.h: ns3::WifiRemoteStation * ns3::WifiRemoteStationManager::CreateStation() [member function] + cls.add_method('CreateStation', 'ns3::WifiRemoteStation *', [], is_pure_virtual=True, visibility='private', is_virtual=True) + return + +def register_Ns3WifiModeValue_methods(root_module, cls): + ## wifi-mode.h: ns3::WifiModeValue::WifiModeValue() [constructor] + cls.add_constructor([], visibility='public') + ## wifi-mode.h: ns3::WifiModeValue::WifiModeValue(ns3::WifiMode const & value) [constructor] + cls.add_constructor([param('ns3::WifiMode&', 'value', is_const=True)], visibility='public') + ## wifi-mode.h: void ns3::WifiModeValue::Set(ns3::WifiMode const & value) [member function] + cls.add_method('Set', 'void', [param('ns3::WifiMode&', 'value', is_const=True)]) + ## wifi-mode.h: ns3::WifiMode ns3::WifiModeValue::Get() const [member function] + cls.add_method('Get', 'ns3::WifiMode', [], is_const=True) + ## wifi-mode.h: ns3::Ptr ns3::WifiModeValue::Copy() const [member function] + cls.add_method('Copy', 'ns3::Ptr< ns3::AttributeValue >', [], is_const=True, is_virtual=True) + ## wifi-mode.h: std::string ns3::WifiModeValue::SerializeToString(ns3::Ptr checker) const [member function] + cls.add_method('SerializeToString', 'std::string', [param('ns3::Ptr< ns3::AttributeChecker const >', 'checker')], is_const=True, is_virtual=True) + ## wifi-mode.h: bool ns3::WifiModeValue::DeserializeFromString(std::string value, ns3::Ptr checker) [member function] + cls.add_method('DeserializeFromString', 'bool', [param('std::string', 'value'), param('ns3::Ptr< ns3::AttributeChecker const >', 'checker')], is_virtual=True) + return + +def register_Ns3OnoeWifiManager_methods(root_module, cls): + ## onoe-wifi-manager.h: static ns3::TypeId ns3::OnoeWifiManager::GetTypeId() [member function] + cls.add_method('GetTypeId', 'ns3::TypeId', [], is_static=True) + ## onoe-wifi-manager.h: ns3::OnoeWifiManager::OnoeWifiManager() [constructor] + cls.add_constructor([], visibility='public') + ## onoe-wifi-manager.h: ns3::WifiRemoteStation * ns3::OnoeWifiManager::CreateStation() [member function] + cls.add_method('CreateStation', 'ns3::WifiRemoteStation *', [], visibility='private', is_virtual=True) + return + +def register_Ns3WifiPhy_methods(root_module, cls): + ## wifi-phy.h: static ns3::TypeId ns3::WifiPhy::GetTypeId() [member function] + cls.add_method('GetTypeId', 'ns3::TypeId', [], is_static=True) + ## wifi-phy.h: ns3::WifiPhy::WifiPhy() [constructor] + cls.add_constructor([], visibility='public') + ## wifi-phy.h: void ns3::WifiPhy::SetStandard(ns3::WifiPhyStandard standard) [member function] + cls.add_method('SetStandard', 'void', [param('ns3::WifiPhyStandard', 'standard')]) + ## wifi-phy.h: void ns3::WifiPhy::SetRxNoise(double ratio) [member function] + cls.add_method('SetRxNoise', 'void', [param('double', 'ratio')]) + ## wifi-phy.h: void ns3::WifiPhy::SetTxPowerStart(double start) [member function] + cls.add_method('SetTxPowerStart', 'void', [param('double', 'start')]) + ## wifi-phy.h: void ns3::WifiPhy::SetTxPowerEnd(double end) [member function] + cls.add_method('SetTxPowerEnd', 'void', [param('double', 'end')]) + ## wifi-phy.h: void ns3::WifiPhy::SetNTxPower(uint32_t n) [member function] + cls.add_method('SetNTxPower', 'void', [param('uint32_t', 'n')]) + ## wifi-phy.h: void ns3::WifiPhy::SetTxGain(double gain) [member function] + cls.add_method('SetTxGain', 'void', [param('double', 'gain')]) + ## wifi-phy.h: void ns3::WifiPhy::SetRxGain(double gain) [member function] + cls.add_method('SetRxGain', 'void', [param('double', 'gain')]) + ## wifi-phy.h: void ns3::WifiPhy::SetEdThreshold(double threshold) [member function] + cls.add_method('SetEdThreshold', 'void', [param('double', 'threshold')]) + ## wifi-phy.h: double ns3::WifiPhy::GetRxNoise() const [member function] + cls.add_method('GetRxNoise', 'double', [], is_const=True) + ## wifi-phy.h: double ns3::WifiPhy::GetTxPowerStart() const [member function] + cls.add_method('GetTxPowerStart', 'double', [], is_const=True) + ## wifi-phy.h: double ns3::WifiPhy::GetTxPowerEnd() const [member function] + cls.add_method('GetTxPowerEnd', 'double', [], is_const=True) + ## wifi-phy.h: uint32_t ns3::WifiPhy::GetNTxPower() const [member function] + cls.add_method('GetNTxPower', 'uint32_t', [], is_const=True) + ## wifi-phy.h: double ns3::WifiPhy::GetTxGain() const [member function] + cls.add_method('GetTxGain', 'double', [], is_const=True) + ## wifi-phy.h: double ns3::WifiPhy::GetRxGain() const [member function] + cls.add_method('GetRxGain', 'double', [], is_const=True) + ## wifi-phy.h: double ns3::WifiPhy::GetEdThreshold() const [member function] + cls.add_method('GetEdThreshold', 'double', [], is_const=True) + ## wifi-phy.h: void ns3::WifiPhy::SetChannel(ns3::Ptr channel) [member function] + cls.add_method('SetChannel', 'void', [param('ns3::Ptr< ns3::WifiChannel >', 'channel')]) + ## wifi-phy.h: void ns3::WifiPhy::SetReceiveOkCallback(ns3::Callback, double, ns3::WifiMode, ns3::WifiPreamble, ns3::empty, ns3::empty> callback) [member function] + cls.add_method('SetReceiveOkCallback', 'void', [param('ns3::Callback< void, ns3::Ptr< ns3::Packet >, double, ns3::WifiMode, ns3::WifiPreamble, ns3::empty, ns3::empty >', 'callback')]) + ## wifi-phy.h: void ns3::WifiPhy::SetReceiveErrorCallback(ns3::Callback, double, ns3::empty, ns3::empty, ns3::empty, ns3::empty> callback) [member function] + cls.add_method('SetReceiveErrorCallback', 'void', [param('ns3::Callback< void, ns3::Ptr< ns3::Packet >, double, ns3::empty, ns3::empty, ns3::empty, ns3::empty >', 'callback')]) + ## wifi-phy.h: void ns3::WifiPhy::SendPacket(ns3::Ptr packet, ns3::WifiMode mode, ns3::WifiPreamble preamble, uint8_t txPowerLevel) [member function] + cls.add_method('SendPacket', 'void', [param('ns3::Ptr< const ns3::Packet >', 'packet'), param('ns3::WifiMode', 'mode'), param('ns3::WifiPreamble', 'preamble'), param('uint8_t', 'txPowerLevel')]) + ## wifi-phy.h: void ns3::WifiPhy::RegisterListener(ns3::WifiPhyListener * listener) [member function] + cls.add_method('RegisterListener', 'void', [param('ns3::WifiPhyListener *', 'listener')]) + ## wifi-phy.h: bool ns3::WifiPhy::IsStateCcaBusy() [member function] + cls.add_method('IsStateCcaBusy', 'bool', []) + ## wifi-phy.h: bool ns3::WifiPhy::IsStateIdle() [member function] + cls.add_method('IsStateIdle', 'bool', []) + ## wifi-phy.h: bool ns3::WifiPhy::IsStateBusy() [member function] + cls.add_method('IsStateBusy', 'bool', []) + ## wifi-phy.h: bool ns3::WifiPhy::IsStateSync() [member function] + cls.add_method('IsStateSync', 'bool', []) + ## wifi-phy.h: bool ns3::WifiPhy::IsStateTx() [member function] + cls.add_method('IsStateTx', 'bool', []) + ## wifi-phy.h: ns3::Time ns3::WifiPhy::GetStateDuration() [member function] + cls.add_method('GetStateDuration', 'ns3::Time', []) + ## wifi-phy.h: ns3::Time ns3::WifiPhy::GetDelayUntilIdle() [member function] + cls.add_method('GetDelayUntilIdle', 'ns3::Time', []) + ## wifi-phy.h: ns3::Time ns3::WifiPhy::GetLastRxStartTime() const [member function] + cls.add_method('GetLastRxStartTime', 'ns3::Time', [], is_const=True) + ## wifi-phy.h: ns3::Time ns3::WifiPhy::CalculateTxDuration(uint32_t size, ns3::WifiMode payloadMode, ns3::WifiPreamble preamble) const [member function] + cls.add_method('CalculateTxDuration', 'ns3::Time', [param('uint32_t', 'size'), param('ns3::WifiMode', 'payloadMode'), param('ns3::WifiPreamble', 'preamble')], is_const=True) + ## wifi-phy.h: uint32_t ns3::WifiPhy::GetNModes() const [member function] + cls.add_method('GetNModes', 'uint32_t', [], is_const=True) + ## wifi-phy.h: ns3::WifiMode ns3::WifiPhy::GetMode(uint32_t mode) const [member function] + cls.add_method('GetMode', 'ns3::WifiMode', [param('uint32_t', 'mode')], is_const=True) + ## wifi-phy.h: double ns3::WifiPhy::CalculateSnr(ns3::WifiMode txMode, double ber) const [member function] + cls.add_method('CalculateSnr', 'double', [param('ns3::WifiMode', 'txMode'), param('double', 'ber')], is_const=True) + ## wifi-phy.h: void ns3::WifiPhy::StartReceivePacket(ns3::Ptr packet, double rxPowerDbm, ns3::WifiMode mode, ns3::WifiPreamble preamble) [member function] + cls.add_method('StartReceivePacket', 'void', [param('ns3::Ptr< ns3::Packet >', 'packet'), param('double', 'rxPowerDbm'), param('ns3::WifiMode', 'mode'), param('ns3::WifiPreamble', 'preamble')]) + ## wifi-phy.h: ns3::Ptr ns3::WifiPhy::GetChannel() const [member function] + cls.add_method('GetChannel', 'ns3::Ptr< ns3::WifiChannel >', [], is_const=True) + ## wifi-phy.h: void ns3::WifiPhy::DoDispose() [member function] + cls.add_method('DoDispose', 'void', [], visibility='private', is_virtual=True) + return + +def register_Ns3WifiChannel_methods(root_module, cls): + ## wifi-channel.h: static ns3::TypeId ns3::WifiChannel::GetTypeId() [member function] + cls.add_method('GetTypeId', 'ns3::TypeId', [], is_static=True) + ## wifi-channel.h: ns3::WifiChannel::WifiChannel() [constructor] + cls.add_constructor([], visibility='public') + ## wifi-channel.h: uint32_t ns3::WifiChannel::GetNDevices() const [member function] + cls.add_method('GetNDevices', 'uint32_t', [], is_const=True, is_virtual=True) + ## wifi-channel.h: ns3::Ptr ns3::WifiChannel::GetDevice(uint32_t i) const [member function] + cls.add_method('GetDevice', 'ns3::Ptr< ns3::NetDevice >', [param('uint32_t', 'i')], is_const=True, is_virtual=True) + ## wifi-channel.h: void ns3::WifiChannel::SetPropagationLossModel(ns3::Ptr loss) [member function] + cls.add_method('SetPropagationLossModel', 'void', [param('ns3::Ptr< ns3::PropagationLossModel >', 'loss')]) + ## wifi-channel.h: void ns3::WifiChannel::SetPropagationDelayModel(ns3::Ptr delay) [member function] + cls.add_method('SetPropagationDelayModel', 'void', [param('ns3::Ptr< ns3::PropagationDelayModel >', 'delay')]) + ## wifi-channel.h: void ns3::WifiChannel::Add(ns3::Ptr device, ns3::Ptr phy) [member function] + cls.add_method('Add', 'void', [param('ns3::Ptr< ns3::NetDevice >', 'device'), param('ns3::Ptr< ns3::WifiPhy >', 'phy')]) + ## wifi-channel.h: void ns3::WifiChannel::Send(ns3::Ptr sender, ns3::Ptr packet, double txPowerDbm, ns3::WifiMode wifiMode, ns3::WifiPreamble preamble) const [member function] + cls.add_method('Send', 'void', [param('ns3::Ptr< ns3::WifiPhy >', 'sender'), param('ns3::Ptr< const ns3::Packet >', 'packet'), param('double', 'txPowerDbm'), param('ns3::WifiMode', 'wifiMode'), param('ns3::WifiPreamble', 'preamble')], is_const=True) + return + +def register_Ns3LogDistancePropagationLossModel_methods(root_module, cls): + ## propagation-loss-model.h: static ns3::TypeId ns3::LogDistancePropagationLossModel::GetTypeId() [member function] + cls.add_method('GetTypeId', 'ns3::TypeId', [], is_static=True) + ## propagation-loss-model.h: ns3::LogDistancePropagationLossModel::LogDistancePropagationLossModel() [constructor] + cls.add_constructor([], visibility='public') + ## propagation-loss-model.h: void ns3::LogDistancePropagationLossModel::SetPathLossExponent(double n) [member function] + cls.add_method('SetPathLossExponent', 'void', [param('double', 'n')]) + ## propagation-loss-model.h: double ns3::LogDistancePropagationLossModel::GetPathLossExponent() const [member function] + cls.add_method('GetPathLossExponent', 'double', [], is_const=True) + ## propagation-loss-model.h: void ns3::LogDistancePropagationLossModel::SetReferenceModel(ns3::Ptr model) [member function] + cls.add_method('SetReferenceModel', 'void', [param('ns3::Ptr< ns3::PropagationLossModel >', 'model')]) + ## propagation-loss-model.h: void ns3::LogDistancePropagationLossModel::SetReferenceDistance(double referenceDistance) [member function] + cls.add_method('SetReferenceDistance', 'void', [param('double', 'referenceDistance')]) + ## propagation-loss-model.h: double ns3::LogDistancePropagationLossModel::GetLoss(ns3::Ptr a, ns3::Ptr b) const [member function] + cls.add_method('GetLoss', 'double', [param('ns3::Ptr< ns3::MobilityModel >', 'a'), param('ns3::Ptr< ns3::MobilityModel >', 'b')], is_const=True, is_virtual=True) + return + +def register_Ns3ConstantRateWifiManager_methods(root_module, cls): + ## constant-rate-wifi-manager.h: static ns3::TypeId ns3::ConstantRateWifiManager::GetTypeId() [member function] + cls.add_method('GetTypeId', 'ns3::TypeId', [], is_static=True) + ## constant-rate-wifi-manager.h: ns3::ConstantRateWifiManager::ConstantRateWifiManager() [constructor] + cls.add_constructor([], visibility='public') + ## constant-rate-wifi-manager.h: ns3::WifiMode ns3::ConstantRateWifiManager::GetDataMode() const [member function] + cls.add_method('GetDataMode', 'ns3::WifiMode', [], is_const=True) + ## constant-rate-wifi-manager.h: ns3::WifiMode ns3::ConstantRateWifiManager::GetCtlMode() const [member function] + cls.add_method('GetCtlMode', 'ns3::WifiMode', [], is_const=True) + ## constant-rate-wifi-manager.h: ns3::WifiRemoteStation * ns3::ConstantRateWifiManager::CreateStation() [member function] + cls.add_method('CreateStation', 'ns3::WifiRemoteStation *', [], visibility='private', is_virtual=True) + return + +def register_Ns3AarfWifiRemoteStation_methods(root_module, cls): + ## aarf-wifi-manager.h: ns3::AarfWifiRemoteStation::AarfWifiRemoteStation(ns3::Ptr stations, uint32_t minTimerThreshold, uint32_t minSuccessThreshold, double successK, uint32_t maxSuccessThreshold, double timerK) [constructor] + cls.add_constructor([param('ns3::Ptr< ns3::AarfWifiManager >', 'stations'), param('uint32_t', 'minTimerThreshold'), param('uint32_t', 'minSuccessThreshold'), param('double', 'successK'), param('uint32_t', 'maxSuccessThreshold'), param('double', 'timerK')], visibility='public') + ## aarf-wifi-manager.h: void ns3::AarfWifiRemoteStation::ReportRecoveryFailure() [member function] + cls.add_method('ReportRecoveryFailure', 'void', [], visibility='private', is_virtual=True) + ## aarf-wifi-manager.h: void ns3::AarfWifiRemoteStation::ReportFailure() [member function] + cls.add_method('ReportFailure', 'void', [], visibility='private', is_virtual=True) + return + +def register_Ns3PropagationDelayModel_methods(root_module, cls): + ## propagation-delay-model.h: static ns3::TypeId ns3::PropagationDelayModel::GetTypeId() [member function] + cls.add_method('GetTypeId', 'ns3::TypeId', [], is_static=True) + ## propagation-delay-model.h: ns3::Time ns3::PropagationDelayModel::GetDelay(ns3::Ptr a, ns3::Ptr b) const [member function] + cls.add_method('GetDelay', 'ns3::Time', [param('ns3::Ptr< ns3::MobilityModel >', 'a'), param('ns3::Ptr< ns3::MobilityModel >', 'b')], is_pure_virtual=True, is_const=True, is_virtual=True) + cls.add_constructor([]) + return + +def register_Ns3AdhocWifiMac_methods(root_module, cls): + ## adhoc-wifi-mac.h: static ns3::TypeId ns3::AdhocWifiMac::GetTypeId() [member function] + cls.add_method('GetTypeId', 'ns3::TypeId', [], is_static=True) + ## adhoc-wifi-mac.h: ns3::AdhocWifiMac::AdhocWifiMac() [constructor] + cls.add_constructor([], visibility='public') + ## adhoc-wifi-mac.h: void ns3::AdhocWifiMac::SetSlot(ns3::Time slotTime) [member function] + cls.add_method('SetSlot', 'void', [param('ns3::Time', 'slotTime')], is_virtual=True) + ## adhoc-wifi-mac.h: void ns3::AdhocWifiMac::SetSifs(ns3::Time sifs) [member function] + cls.add_method('SetSifs', 'void', [param('ns3::Time', 'sifs')], is_virtual=True) + ## adhoc-wifi-mac.h: void ns3::AdhocWifiMac::SetEifsNoDifs(ns3::Time eifsNoDifs) [member function] + cls.add_method('SetEifsNoDifs', 'void', [param('ns3::Time', 'eifsNoDifs')], is_virtual=True) + ## adhoc-wifi-mac.h: ns3::Time ns3::AdhocWifiMac::GetSlot() const [member function] + cls.add_method('GetSlot', 'ns3::Time', [], is_const=True, is_virtual=True) + ## adhoc-wifi-mac.h: ns3::Time ns3::AdhocWifiMac::GetSifs() const [member function] + cls.add_method('GetSifs', 'ns3::Time', [], is_const=True, is_virtual=True) + ## adhoc-wifi-mac.h: ns3::Time ns3::AdhocWifiMac::GetEifsNoDifs() const [member function] + cls.add_method('GetEifsNoDifs', 'ns3::Time', [], is_const=True, is_virtual=True) + ## adhoc-wifi-mac.h: void ns3::AdhocWifiMac::SetWifiPhy(ns3::Ptr phy) [member function] + cls.add_method('SetWifiPhy', 'void', [param('ns3::Ptr< ns3::WifiPhy >', 'phy')], is_virtual=True) + ## adhoc-wifi-mac.h: void ns3::AdhocWifiMac::SetWifiRemoteStationManager(ns3::Ptr stationManager) [member function] + cls.add_method('SetWifiRemoteStationManager', 'void', [param('ns3::Ptr< ns3::WifiRemoteStationManager >', 'stationManager')], is_virtual=True) + ## adhoc-wifi-mac.h: void ns3::AdhocWifiMac::Enqueue(ns3::Ptr packet, ns3::Mac48Address to) [member function] + cls.add_method('Enqueue', 'void', [param('ns3::Ptr< const ns3::Packet >', 'packet'), param('ns3::Mac48Address', 'to')], is_virtual=True) + ## adhoc-wifi-mac.h: void ns3::AdhocWifiMac::SetForwardUpCallback(ns3::Callback, ns3::Mac48Address const&, ns3::empty, ns3::empty, ns3::empty, ns3::empty> upCallback) [member function] + cls.add_method('SetForwardUpCallback', 'void', [param('ns3::Callback< void, ns3::Ptr< ns3::Packet >, ns3::Mac48Address const&, ns3::empty, ns3::empty, ns3::empty, ns3::empty >', 'upCallback')], is_virtual=True) + ## adhoc-wifi-mac.h: void ns3::AdhocWifiMac::SetLinkUpCallback(ns3::Callback linkUp) [member function] + cls.add_method('SetLinkUpCallback', 'void', [param('ns3::Callback< void, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty >', 'linkUp')], is_virtual=True) + ## adhoc-wifi-mac.h: void ns3::AdhocWifiMac::SetLinkDownCallback(ns3::Callback linkDown) [member function] + cls.add_method('SetLinkDownCallback', 'void', [param('ns3::Callback< void, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty >', 'linkDown')], is_virtual=True) + ## adhoc-wifi-mac.h: ns3::Mac48Address ns3::AdhocWifiMac::GetAddress() const [member function] + cls.add_method('GetAddress', 'ns3::Mac48Address', [], is_const=True, is_virtual=True) + ## adhoc-wifi-mac.h: ns3::Ssid ns3::AdhocWifiMac::GetSsid() const [member function] + cls.add_method('GetSsid', 'ns3::Ssid', [], is_const=True, is_virtual=True) + ## adhoc-wifi-mac.h: ns3::Mac48Address ns3::AdhocWifiMac::GetBssid() const [member function] + cls.add_method('GetBssid', 'ns3::Mac48Address', [], is_const=True, is_virtual=True) + ## adhoc-wifi-mac.h: void ns3::AdhocWifiMac::SetAddress(ns3::Mac48Address address) [member function] + cls.add_method('SetAddress', 'void', [param('ns3::Mac48Address', 'address')], is_virtual=True) + ## adhoc-wifi-mac.h: void ns3::AdhocWifiMac::SetSsid(ns3::Ssid ssid) [member function] + cls.add_method('SetSsid', 'void', [param('ns3::Ssid', 'ssid')], is_virtual=True) + ## adhoc-wifi-mac.h: void ns3::AdhocWifiMac::DoDispose() [member function] + cls.add_method('DoDispose', 'void', [], visibility='private', is_virtual=True) + return + +def register_Ns3JakesPropagationLossModel_methods(root_module, cls): + ## jakes-propagation-loss-model.h: static ns3::TypeId ns3::JakesPropagationLossModel::GetTypeId() [member function] + cls.add_method('GetTypeId', 'ns3::TypeId', [], is_static=True) + ## jakes-propagation-loss-model.h: ns3::JakesPropagationLossModel::JakesPropagationLossModel() [constructor] + cls.add_constructor([], visibility='public') + ## jakes-propagation-loss-model.h: double ns3::JakesPropagationLossModel::GetLoss(ns3::Ptr a, ns3::Ptr b) const [member function] + cls.add_method('GetLoss', 'double', [param('ns3::Ptr< ns3::MobilityModel >', 'a'), param('ns3::Ptr< ns3::MobilityModel >', 'b')], is_const=True, is_virtual=True) + ## jakes-propagation-loss-model.h: void ns3::JakesPropagationLossModel::SetNRays(uint8_t nRays) [member function] + cls.add_method('SetNRays', 'void', [param('uint8_t', 'nRays')]) + ## jakes-propagation-loss-model.h: void ns3::JakesPropagationLossModel::SetNOscillators(uint8_t nOscillators) [member function] + cls.add_method('SetNOscillators', 'void', [param('uint8_t', 'nOscillators')]) + return + +def register_Ns3ConstantSpeedPropagationDelayModel_methods(root_module, cls): + ## propagation-delay-model.h: static ns3::TypeId ns3::ConstantSpeedPropagationDelayModel::GetTypeId() [member function] + cls.add_method('GetTypeId', 'ns3::TypeId', [], is_static=True) + ## propagation-delay-model.h: ns3::ConstantSpeedPropagationDelayModel::ConstantSpeedPropagationDelayModel() [constructor] + cls.add_constructor([], visibility='public') + ## propagation-delay-model.h: ns3::Time ns3::ConstantSpeedPropagationDelayModel::GetDelay(ns3::Ptr a, ns3::Ptr b) const [member function] + cls.add_method('GetDelay', 'ns3::Time', [param('ns3::Ptr< ns3::MobilityModel >', 'a'), param('ns3::Ptr< ns3::MobilityModel >', 'b')], is_const=True, is_virtual=True) + ## propagation-delay-model.h: void ns3::ConstantSpeedPropagationDelayModel::SetSpeed(double speed) [member function] + cls.add_method('SetSpeed', 'void', [param('double', 'speed')]) + ## propagation-delay-model.h: double ns3::ConstantSpeedPropagationDelayModel::GetSpeed() const [member function] + cls.add_method('GetSpeed', 'double', [], is_const=True) + return + +def register_Ns3WifiNetDevice_methods(root_module, cls): + ## wifi-net-device.h: static ns3::TypeId ns3::WifiNetDevice::GetTypeId() [member function] + cls.add_method('GetTypeId', 'ns3::TypeId', [], is_static=True) + ## wifi-net-device.h: ns3::WifiNetDevice::WifiNetDevice() [constructor] + cls.add_constructor([], visibility='public') + ## wifi-net-device.h: void ns3::WifiNetDevice::SetMac(ns3::Ptr mac) [member function] + cls.add_method('SetMac', 'void', [param('ns3::Ptr< ns3::WifiMac >', 'mac')]) + ## wifi-net-device.h: void ns3::WifiNetDevice::SetPhy(ns3::Ptr phy) [member function] + cls.add_method('SetPhy', 'void', [param('ns3::Ptr< ns3::WifiPhy >', 'phy')]) + ## wifi-net-device.h: void ns3::WifiNetDevice::SetRemoteStationManager(ns3::Ptr manager) [member function] + cls.add_method('SetRemoteStationManager', 'void', [param('ns3::Ptr< ns3::WifiRemoteStationManager >', 'manager')]) + ## wifi-net-device.h: void ns3::WifiNetDevice::SetChannel(ns3::Ptr channel) [member function] + cls.add_method('SetChannel', 'void', [param('ns3::Ptr< ns3::WifiChannel >', 'channel')]) + ## wifi-net-device.h: ns3::Ptr ns3::WifiNetDevice::GetMac() const [member function] + cls.add_method('GetMac', 'ns3::Ptr< ns3::WifiMac >', [], is_const=True) + ## wifi-net-device.h: ns3::Ptr ns3::WifiNetDevice::GetPhy() const [member function] + cls.add_method('GetPhy', 'ns3::Ptr< ns3::WifiPhy >', [], is_const=True) + ## wifi-net-device.h: ns3::Ptr ns3::WifiNetDevice::GetRemoteStationManager() const [member function] + cls.add_method('GetRemoteStationManager', 'ns3::Ptr< ns3::WifiRemoteStationManager >', [], is_const=True) + ## wifi-net-device.h: void ns3::WifiNetDevice::SetName(std::string const name) [member function] + cls.add_method('SetName', 'void', [param('std::string', 'name', is_const=True)], is_virtual=True) + ## wifi-net-device.h: std::string ns3::WifiNetDevice::GetName() const [member function] + cls.add_method('GetName', 'std::string', [], is_const=True, is_virtual=True) + ## wifi-net-device.h: void ns3::WifiNetDevice::SetIfIndex(uint32_t const index) [member function] + cls.add_method('SetIfIndex', 'void', [param('uint32_t', 'index', is_const=True)], is_virtual=True) + ## wifi-net-device.h: uint32_t ns3::WifiNetDevice::GetIfIndex() const [member function] + cls.add_method('GetIfIndex', 'uint32_t', [], is_const=True, is_virtual=True) + ## wifi-net-device.h: ns3::Ptr ns3::WifiNetDevice::GetChannel() const [member function] + cls.add_method('GetChannel', 'ns3::Ptr< ns3::Channel >', [], is_const=True, is_virtual=True) + ## wifi-net-device.h: ns3::Address ns3::WifiNetDevice::GetAddress() const [member function] + cls.add_method('GetAddress', 'ns3::Address', [], is_const=True, is_virtual=True) + ## wifi-net-device.h: bool ns3::WifiNetDevice::SetMtu(uint16_t const mtu) [member function] + cls.add_method('SetMtu', 'bool', [param('uint16_t', 'mtu', is_const=True)], is_virtual=True) + ## wifi-net-device.h: uint16_t ns3::WifiNetDevice::GetMtu() const [member function] + cls.add_method('GetMtu', 'uint16_t', [], is_const=True, is_virtual=True) + ## wifi-net-device.h: bool ns3::WifiNetDevice::IsLinkUp() const [member function] + cls.add_method('IsLinkUp', 'bool', [], is_const=True, is_virtual=True) + ## wifi-net-device.h: void ns3::WifiNetDevice::SetLinkChangeCallback(ns3::Callback callback) [member function] + cls.add_method('SetLinkChangeCallback', 'void', [param('ns3::Callback< void, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty >', 'callback')], is_virtual=True) + ## wifi-net-device.h: bool ns3::WifiNetDevice::IsBroadcast() const [member function] + cls.add_method('IsBroadcast', 'bool', [], is_const=True, is_virtual=True) + ## wifi-net-device.h: ns3::Address ns3::WifiNetDevice::GetBroadcast() const [member function] + cls.add_method('GetBroadcast', 'ns3::Address', [], is_const=True, is_virtual=True) + ## wifi-net-device.h: bool ns3::WifiNetDevice::IsMulticast() const [member function] + cls.add_method('IsMulticast', 'bool', [], is_const=True, is_virtual=True) + ## wifi-net-device.h: ns3::Address ns3::WifiNetDevice::GetMulticast() const [member function] + cls.add_method('GetMulticast', 'ns3::Address', [], is_const=True, is_virtual=True) + ## wifi-net-device.h: ns3::Address ns3::WifiNetDevice::MakeMulticastAddress(ns3::Ipv4Address multicastGroup) const [member function] + cls.add_method('MakeMulticastAddress', 'ns3::Address', [param('ns3::Ipv4Address', 'multicastGroup')], is_const=True, is_virtual=True) + ## wifi-net-device.h: bool ns3::WifiNetDevice::IsPointToPoint() const [member function] + cls.add_method('IsPointToPoint', 'bool', [], is_const=True, is_virtual=True) + ## wifi-net-device.h: bool ns3::WifiNetDevice::Send(ns3::Ptr packet, ns3::Address const & dest, uint16_t protocolNumber) [member function] + cls.add_method('Send', 'bool', [param('ns3::Ptr< ns3::Packet >', 'packet'), param('ns3::Address&', 'dest', is_const=True), param('uint16_t', 'protocolNumber')], is_virtual=True) + ## wifi-net-device.h: ns3::Ptr ns3::WifiNetDevice::GetNode() const [member function] + cls.add_method('GetNode', 'ns3::Ptr< ns3::Node >', [], is_const=True, is_virtual=True) + ## wifi-net-device.h: void ns3::WifiNetDevice::SetNode(ns3::Ptr node) [member function] + cls.add_method('SetNode', 'void', [param('ns3::Ptr< ns3::Node >', 'node')], is_virtual=True) + ## wifi-net-device.h: bool ns3::WifiNetDevice::NeedsArp() const [member function] + cls.add_method('NeedsArp', 'bool', [], is_const=True, is_virtual=True) + ## wifi-net-device.h: void ns3::WifiNetDevice::SetReceiveCallback(ns3::Callback, ns3::Ptr, unsigned short, ns3::Address const&, ns3::empty, ns3::empty> cb) [member function] + cls.add_method('SetReceiveCallback', 'void', [param('ns3::Callback< bool, ns3::Ptr< ns3::NetDevice >, ns3::Ptr< ns3::Packet >, unsigned short, ns3::Address const&, ns3::empty, ns3::empty >', 'cb')], is_virtual=True) + ## wifi-net-device.h: void ns3::WifiNetDevice::DoDispose() [member function] + cls.add_method('DoDispose', 'void', [], visibility='private', is_virtual=True) + return + +def register_Ns3NqstaWifiMac_methods(root_module, cls): + ## nqsta-wifi-mac.h: static ns3::TypeId ns3::NqstaWifiMac::GetTypeId() [member function] + cls.add_method('GetTypeId', 'ns3::TypeId', [], is_static=True) + ## nqsta-wifi-mac.h: ns3::NqstaWifiMac::NqstaWifiMac() [constructor] + cls.add_constructor([], visibility='public') + ## nqsta-wifi-mac.h: void ns3::NqstaWifiMac::SetSlot(ns3::Time slotTime) [member function] + cls.add_method('SetSlot', 'void', [param('ns3::Time', 'slotTime')], is_virtual=True) + ## nqsta-wifi-mac.h: void ns3::NqstaWifiMac::SetSifs(ns3::Time sifs) [member function] + cls.add_method('SetSifs', 'void', [param('ns3::Time', 'sifs')], is_virtual=True) + ## nqsta-wifi-mac.h: void ns3::NqstaWifiMac::SetEifsNoDifs(ns3::Time eifsNoDifs) [member function] + cls.add_method('SetEifsNoDifs', 'void', [param('ns3::Time', 'eifsNoDifs')], is_virtual=True) + ## nqsta-wifi-mac.h: ns3::Time ns3::NqstaWifiMac::GetSlot() const [member function] + cls.add_method('GetSlot', 'ns3::Time', [], is_const=True, is_virtual=True) + ## nqsta-wifi-mac.h: ns3::Time ns3::NqstaWifiMac::GetSifs() const [member function] + cls.add_method('GetSifs', 'ns3::Time', [], is_const=True, is_virtual=True) + ## nqsta-wifi-mac.h: ns3::Time ns3::NqstaWifiMac::GetEifsNoDifs() const [member function] + cls.add_method('GetEifsNoDifs', 'ns3::Time', [], is_const=True, is_virtual=True) + ## nqsta-wifi-mac.h: void ns3::NqstaWifiMac::SetWifiPhy(ns3::Ptr phy) [member function] + cls.add_method('SetWifiPhy', 'void', [param('ns3::Ptr< ns3::WifiPhy >', 'phy')], is_virtual=True) + ## nqsta-wifi-mac.h: void ns3::NqstaWifiMac::SetWifiRemoteStationManager(ns3::Ptr stationManager) [member function] + cls.add_method('SetWifiRemoteStationManager', 'void', [param('ns3::Ptr< ns3::WifiRemoteStationManager >', 'stationManager')], is_virtual=True) + ## nqsta-wifi-mac.h: void ns3::NqstaWifiMac::Enqueue(ns3::Ptr packet, ns3::Mac48Address to) [member function] + cls.add_method('Enqueue', 'void', [param('ns3::Ptr< const ns3::Packet >', 'packet'), param('ns3::Mac48Address', 'to')], is_virtual=True) + ## nqsta-wifi-mac.h: void ns3::NqstaWifiMac::SetForwardUpCallback(ns3::Callback, ns3::Mac48Address const&, ns3::empty, ns3::empty, ns3::empty, ns3::empty> upCallback) [member function] + cls.add_method('SetForwardUpCallback', 'void', [param('ns3::Callback< void, ns3::Ptr< ns3::Packet >, ns3::Mac48Address const&, ns3::empty, ns3::empty, ns3::empty, ns3::empty >', 'upCallback')], is_virtual=True) + ## nqsta-wifi-mac.h: void ns3::NqstaWifiMac::SetLinkUpCallback(ns3::Callback linkUp) [member function] + cls.add_method('SetLinkUpCallback', 'void', [param('ns3::Callback< void, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty >', 'linkUp')], is_virtual=True) + ## nqsta-wifi-mac.h: void ns3::NqstaWifiMac::SetLinkDownCallback(ns3::Callback linkDown) [member function] + cls.add_method('SetLinkDownCallback', 'void', [param('ns3::Callback< void, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty >', 'linkDown')], is_virtual=True) + ## nqsta-wifi-mac.h: ns3::Mac48Address ns3::NqstaWifiMac::GetAddress() const [member function] + cls.add_method('GetAddress', 'ns3::Mac48Address', [], is_const=True, is_virtual=True) + ## nqsta-wifi-mac.h: ns3::Ssid ns3::NqstaWifiMac::GetSsid() const [member function] + cls.add_method('GetSsid', 'ns3::Ssid', [], is_const=True, is_virtual=True) + ## nqsta-wifi-mac.h: ns3::Mac48Address ns3::NqstaWifiMac::GetBssid() const [member function] + cls.add_method('GetBssid', 'ns3::Mac48Address', [], is_const=True, is_virtual=True) + ## nqsta-wifi-mac.h: void ns3::NqstaWifiMac::SetAddress(ns3::Mac48Address address) [member function] + cls.add_method('SetAddress', 'void', [param('ns3::Mac48Address', 'address')], is_virtual=True) + ## nqsta-wifi-mac.h: void ns3::NqstaWifiMac::SetSsid(ns3::Ssid ssid) [member function] + cls.add_method('SetSsid', 'void', [param('ns3::Ssid', 'ssid')], is_virtual=True) + ## nqsta-wifi-mac.h: void ns3::NqstaWifiMac::SetMaxMissedBeacons(uint32_t missed) [member function] + cls.add_method('SetMaxMissedBeacons', 'void', [param('uint32_t', 'missed')]) + ## nqsta-wifi-mac.h: void ns3::NqstaWifiMac::SetProbeRequestTimeout(ns3::Time timeout) [member function] + cls.add_method('SetProbeRequestTimeout', 'void', [param('ns3::Time', 'timeout')]) + ## nqsta-wifi-mac.h: void ns3::NqstaWifiMac::SetAssocRequestTimeout(ns3::Time timeout) [member function] + cls.add_method('SetAssocRequestTimeout', 'void', [param('ns3::Time', 'timeout')]) + ## nqsta-wifi-mac.h: void ns3::NqstaWifiMac::StartActiveAssociation() [member function] + cls.add_method('StartActiveAssociation', 'void', []) + ## nqsta-wifi-mac.h: void ns3::NqstaWifiMac::DoDispose() [member function] + cls.add_method('DoDispose', 'void', [], visibility='private', is_virtual=True) + return + +def register_Ns3RandomPropagationLossModel_methods(root_module, cls): + ## propagation-loss-model.h: static ns3::TypeId ns3::RandomPropagationLossModel::GetTypeId() [member function] + cls.add_method('GetTypeId', 'ns3::TypeId', [], is_static=True) + ## propagation-loss-model.h: ns3::RandomPropagationLossModel::RandomPropagationLossModel() [constructor] + cls.add_constructor([], visibility='public') + ## propagation-loss-model.h: double ns3::RandomPropagationLossModel::GetLoss(ns3::Ptr a, ns3::Ptr b) const [member function] + cls.add_method('GetLoss', 'double', [param('ns3::Ptr< ns3::MobilityModel >', 'a'), param('ns3::Ptr< ns3::MobilityModel >', 'b')], is_const=True, is_virtual=True) + return + +def register_Ns3RandomPropagationDelayModel_methods(root_module, cls): + ## propagation-delay-model.h: static ns3::TypeId ns3::RandomPropagationDelayModel::GetTypeId() [member function] + cls.add_method('GetTypeId', 'ns3::TypeId', [], is_static=True) + ## propagation-delay-model.h: ns3::RandomPropagationDelayModel::RandomPropagationDelayModel() [constructor] + cls.add_constructor([], visibility='public') + ## propagation-delay-model.h: ns3::Time ns3::RandomPropagationDelayModel::GetDelay(ns3::Ptr a, ns3::Ptr b) const [member function] + cls.add_method('GetDelay', 'ns3::Time', [param('ns3::Ptr< ns3::MobilityModel >', 'a'), param('ns3::Ptr< ns3::MobilityModel >', 'b')], is_const=True, is_virtual=True) + return + +def register_Ns3AmrrWifiManager_methods(root_module, cls): + ## amrr-wifi-manager.h: static ns3::TypeId ns3::AmrrWifiManager::GetTypeId() [member function] + cls.add_method('GetTypeId', 'ns3::TypeId', [], is_static=True) + ## amrr-wifi-manager.h: ns3::AmrrWifiManager::AmrrWifiManager() [constructor] + cls.add_constructor([], visibility='public') + ## amrr-wifi-manager.h: ns3::WifiRemoteStation * ns3::AmrrWifiManager::CreateStation() [member function] + cls.add_method('CreateStation', 'ns3::WifiRemoteStation *', [], visibility='private', is_virtual=True) + return + +def register_Ns3RraaWifiManager_methods(root_module, cls): + ## rraa-wifi-manager.h: static ns3::TypeId ns3::RraaWifiManager::GetTypeId() [member function] + cls.add_method('GetTypeId', 'ns3::TypeId', [], is_static=True) + ## rraa-wifi-manager.h: ns3::RraaWifiManager::RraaWifiManager() [constructor] + cls.add_constructor([], visibility='public') + ## rraa-wifi-manager.h: bool ns3::RraaWifiManager::OnlyBasic() [member function] + cls.add_method('OnlyBasic', 'bool', []) + ## rraa-wifi-manager.h: ns3::Time ns3::RraaWifiManager::GetTimeout() const [member function] + cls.add_method('GetTimeout', 'ns3::Time', [], is_const=True) + ## rraa-wifi-manager.h: ns3::ThresholdsItem ns3::RraaWifiManager::GetThresholds(ns3::WifiMode mode) const [member function] + cls.add_method('GetThresholds', 'ns3::ThresholdsItem', [param('ns3::WifiMode', 'mode')], is_const=True) + ## rraa-wifi-manager.h: ns3::WifiRemoteStation * ns3::RraaWifiManager::CreateStation() [member function] + cls.add_method('CreateStation', 'ns3::WifiRemoteStation *', [], visibility='private', is_virtual=True) + return + +def register_Ns3IdealWifiManager_methods(root_module, cls): + ## ideal-wifi-manager.h: static ns3::TypeId ns3::IdealWifiManager::GetTypeId() [member function] + cls.add_method('GetTypeId', 'ns3::TypeId', [], is_static=True) + ## ideal-wifi-manager.h: ns3::IdealWifiManager::IdealWifiManager() [constructor] + cls.add_constructor([], visibility='public') + ## ideal-wifi-manager.h: void ns3::IdealWifiManager::SetupPhy(ns3::Ptr phy) [member function] + cls.add_method('SetupPhy', 'void', [param('ns3::Ptr< ns3::WifiPhy >', 'phy')], is_virtual=True) + ## ideal-wifi-manager.h: double ns3::IdealWifiManager::GetSnrThreshold(ns3::WifiMode mode) const [member function] + cls.add_method('GetSnrThreshold', 'double', [param('ns3::WifiMode', 'mode')], is_const=True) + ## ideal-wifi-manager.h: void ns3::IdealWifiManager::AddModeSnrThreshold(ns3::WifiMode mode, double ber) [member function] + cls.add_method('AddModeSnrThreshold', 'void', [param('ns3::WifiMode', 'mode'), param('double', 'ber')]) + ## ideal-wifi-manager.h: ns3::WifiRemoteStation * ns3::IdealWifiManager::CreateStation() [member function] + cls.add_method('CreateStation', 'ns3::WifiRemoteStation *', [], visibility='private', is_virtual=True) + return + +def register_Ns3ArfWifiManager_methods(root_module, cls): + ## arf-wifi-manager.h: static ns3::TypeId ns3::ArfWifiManager::GetTypeId() [member function] + cls.add_method('GetTypeId', 'ns3::TypeId', [], is_static=True) + ## arf-wifi-manager.h: ns3::ArfWifiManager::ArfWifiManager() [constructor] + cls.add_constructor([], visibility='public') + ## arf-wifi-manager.h: ns3::WifiRemoteStation * ns3::ArfWifiManager::CreateStation() [member function] + cls.add_method('CreateStation', 'ns3::WifiRemoteStation *', [], visibility='private', is_virtual=True) + return + +def register_Ns3AarfWifiManager_methods(root_module, cls): + ## aarf-wifi-manager.h: static ns3::TypeId ns3::AarfWifiManager::GetTypeId() [member function] + cls.add_method('GetTypeId', 'ns3::TypeId', [], is_static=True) + ## aarf-wifi-manager.h: ns3::AarfWifiManager::AarfWifiManager() [constructor] + cls.add_constructor([], visibility='public') + ## aarf-wifi-manager.h: ns3::WifiRemoteStation * ns3::AarfWifiManager::CreateStation() [member function] + cls.add_method('CreateStation', 'ns3::WifiRemoteStation *', [], visibility='private', is_virtual=True) + return + +def register_functions(root_module): + module = root_module + ## wifi-mode.h: extern ns3::Ptr ns3::MakeWifiModeChecker() [free function] + module.add_function('MakeWifiModeChecker', 'ns3::Ptr< ns3::AttributeChecker const >', []) + ## ssid.h: extern ns3::Ptr ns3::MakeSsidChecker() [free function] + module.add_function('MakeSsidChecker', 'ns3::Ptr< ns3::AttributeChecker const >', []) + register_functions_ns3_internal(module.get_submodule('internal'), root_module) + register_functions_ns3_TimeStepPrecision(module.get_submodule('TimeStepPrecision'), root_module) + register_functions_ns3_Config(module.get_submodule('Config'), root_module) + register_functions_ns3_olsr(module.get_submodule('olsr'), root_module) + return + +def register_functions_ns3_internal(module, root_module): + return + +def register_functions_ns3_TimeStepPrecision(module, root_module): + return + +def register_functions_ns3_Config(module, root_module): + return + +def register_functions_ns3_olsr(module, root_module): + return + diff --git a/bindings/python/ns3module_helpers.cc b/bindings/python/ns3module_helpers.cc new file mode 100644 index 000000000..69e3f7288 --- /dev/null +++ b/bindings/python/ns3module_helpers.cc @@ -0,0 +1,178 @@ +#include "ns3module.h" + + +namespace ns3{ + +void PythonCompleteConstruct (Ptr object, TypeId typeId, const AttributeList &attributes) +{ + object->SetTypeId (typeId); + object->Object::Construct (attributes); +} + +} + + + +class PythonEventImpl : public ns3::EventImpl +{ +private: + PyObject *m_callback; + PyObject *m_args; +public: + PythonEventImpl (PyObject *callback, PyObject *args) + { + m_callback = callback; + Py_INCREF(m_callback); + m_args = args; + Py_INCREF(m_args); + } + virtual ~PythonEventImpl () + { + Py_DECREF(m_callback); + Py_DECREF(m_args); + } + virtual void Notify () + { + PyObject *retval = PyObject_CallObject(m_callback, m_args); + if (retval) { + if (retval != Py_None) { + PyErr_SetString(PyExc_TypeError, "event callback should return None"); + PyErr_Print(); + } + Py_DECREF(retval); + } else { + PyErr_Print(); + } + } +}; + + +PyObject * +_wrap_Simulator_Schedule(PyNs3Simulator *PYBINDGEN_UNUSED(dummy), PyObject *args, PyObject *kwargs, + PyObject **return_exception) +{ + PyObject *exc_type, *traceback; + PyObject *py_time; + PyObject *py_callback; + PyObject *user_args; + ns3::Ptr py_event_impl; + PyNs3EventId *py_EventId; + + if (kwargs && PyObject_Length(kwargs) > 0) { + PyErr_SetString(PyExc_TypeError, "keyword arguments not supported"); + goto error; + } + + if (PyTuple_GET_SIZE(args) < 2) { + PyErr_SetString(PyExc_TypeError, "ns3.Simulator.Schedule needs at least 2 arguments"); + goto error; + } + py_time = PyTuple_GET_ITEM(args, 0); + py_callback = PyTuple_GET_ITEM(args, 1); + + if (!PyObject_IsInstance(py_time, (PyObject*) &PyNs3Time_Type)) { + PyErr_SetString(PyExc_TypeError, "Parameter 1 should be a ns3.Time instance"); + goto error; + } + if (!PyCallable_Check(py_callback)) { + PyErr_SetString(PyExc_TypeError, "Parameter 2 should be callable"); + goto error; + } + user_args = PyTuple_GetSlice(args, 2, PyTuple_GET_SIZE(args)); + py_event_impl = ns3::Create(py_callback, user_args); + Py_DECREF(user_args); + + py_EventId = PyObject_New(PyNs3EventId, &PyNs3EventId_Type); + py_EventId->obj = new ns3::EventId( + ns3::Simulator::Schedule(*((PyNs3Time *) py_time)->obj, py_event_impl)); + return (PyObject *) py_EventId; + +error: + PyErr_Fetch(&exc_type, return_exception, &traceback); + Py_XDECREF(exc_type); + Py_XDECREF(traceback); + return NULL; +} + + +PyObject * +_wrap_Simulator_ScheduleNow(PyNs3Simulator *PYBINDGEN_UNUSED(dummy), PyObject *args, PyObject *kwargs, + PyObject **return_exception) +{ + PyObject *exc_type, *traceback; + PyObject *py_callback; + PyObject *user_args; + ns3::Ptr py_event_impl; + PyNs3EventId *py_EventId; + + if (kwargs && PyObject_Length(kwargs) > 0) { + PyErr_SetString(PyExc_TypeError, "keyword arguments not supported"); + goto error; + } + + if (PyTuple_GET_SIZE(args) < 1) { + PyErr_SetString(PyExc_TypeError, "ns3.Simulator.Schedule needs at least 1 argument"); + goto error; + } + py_callback = PyTuple_GET_ITEM(args, 0); + + if (!PyCallable_Check(py_callback)) { + PyErr_SetString(PyExc_TypeError, "Parameter 2 should be callable"); + goto error; + } + user_args = PyTuple_GetSlice(args, 1, PyTuple_GET_SIZE(args)); + py_event_impl = ns3::Create(py_callback, user_args); + Py_DECREF(user_args); + + py_EventId = PyObject_New(PyNs3EventId, &PyNs3EventId_Type); + py_EventId->obj = new ns3::EventId(ns3::Simulator::ScheduleNow(py_event_impl)); + return (PyObject *) py_EventId; + +error: + PyErr_Fetch(&exc_type, return_exception, &traceback); + Py_XDECREF(exc_type); + Py_XDECREF(traceback); + return NULL; +} + + +PyObject * +_wrap_Simulator_ScheduleDestroy(PyNs3Simulator *PYBINDGEN_UNUSED(dummy), PyObject *args, PyObject *kwargs, + PyObject **return_exception) +{ + PyObject *exc_type, *traceback; + PyObject *py_callback; + PyObject *user_args; + ns3::Ptr py_event_impl; + PyNs3EventId *py_EventId; + + if (kwargs && PyObject_Length(kwargs) > 0) { + PyErr_SetString(PyExc_TypeError, "keyword arguments not supported"); + goto error; + } + + if (PyTuple_GET_SIZE(args) < 1) { + PyErr_SetString(PyExc_TypeError, "ns3.Simulator.Schedule needs at least 1 argument"); + goto error; + } + py_callback = PyTuple_GET_ITEM(args, 0); + + if (!PyCallable_Check(py_callback)) { + PyErr_SetString(PyExc_TypeError, "Parameter 2 should be callable"); + goto error; + } + user_args = PyTuple_GetSlice(args, 1, PyTuple_GET_SIZE(args)); + py_event_impl = ns3::Create(py_callback, user_args); + Py_DECREF(user_args); + + py_EventId = PyObject_New(PyNs3EventId, &PyNs3EventId_Type); + py_EventId->obj = new ns3::EventId(ns3::Simulator::ScheduleDestroy(py_event_impl)); + return (PyObject *) py_EventId; + +error: + PyErr_Fetch(&exc_type, return_exception, &traceback); + Py_XDECREF(exc_type); + Py_XDECREF(traceback); + return NULL; +} + diff --git a/bindings/python/ns3modulegen.py b/bindings/python/ns3modulegen.py new file mode 100644 index 000000000..88dcf6cca --- /dev/null +++ b/bindings/python/ns3modulegen.py @@ -0,0 +1,116 @@ + +LOCAL_MODULES = [ + #'my_extra_api_definitions', + ] + + + +import sys +import os + +from pybindgen import FileCodeSink, write_preamble +from pybindgen.module import MultiSectionFactory +import pybindgen.settings + +from ns3modulegen_generated import (module_init, register_types, register_methods, register_functions) +import ns3modulegen_core_customizations +import callbacks_list + +this_script_dir = os.path.dirname(os.path.abspath(sys.argv[0])) + +class ErrorHandler(pybindgen.settings.ErrorHandler): + def handle_error(self, wrapper, exception, traceback_): + try: + stack = wrapper.stack_where_defined + except AttributeError: + print >> sys.stderr, "??:??: %s / %r" % (wrapper, exception) + else: + stack = list(stack) + stack.reverse() + for (filename, line_number, function_name, text) in stack: + file_dir = os.path.dirname(os.path.abspath(filename)) + if file_dir == this_script_dir: + print >> sys.stderr, "%s:%i: %r" % (os.path.join("..", "bindings", "python", os.path.basename(filename)), + line_number, exception) + break + return True +pybindgen.settings.error_handler = ErrorHandler() + + +class MyMultiSectionFactory(MultiSectionFactory): + + def __init__(self, main_file_name, modules): + super(MyMultiSectionFactory, self).__init__() + self.main_file_name = main_file_name + self.main_sink = FileCodeSink(open(main_file_name, "wt")) + self.header_name = "ns3module.h" + header_file_name = os.path.join(os.path.dirname(self.main_file_name), self.header_name) + self.header_sink = FileCodeSink(open(header_file_name, "wt")) + self.section_sinks = {} + + for module in modules: + section_name = 'ns3_module_%s' % module.replace('-', '_') + file_name = os.path.join(os.path.dirname(self.main_file_name), "%s.cc" % section_name) + sink = FileCodeSink(open(file_name, "wt")) + self.section_sinks[section_name] = sink + + def get_section_code_sink(self, section_name): + return self.section_sinks[section_name] + + def get_main_code_sink(self): + return self.main_sink + + def get_common_header_code_sink(self): + return self.header_sink + + def get_common_header_include(self): + return '"%s"' % self.header_name + + def close(self): + self.header_sink.file.close() + self.main_sink.file.close() + for sink in self.section_sinks.itervalues(): + sink.file.close() + + + +def main(): + out = MyMultiSectionFactory(sys.argv[1], sys.argv[2:]) + root_module = module_init() + root_module.add_include('"ns3/everything.h"') + + register_types(root_module) + + ns3modulegen_core_customizations.Simulator_customizations(root_module) + ns3modulegen_core_customizations.CommandLine_customizations(root_module) + + + for local_module in LOCAL_MODULES: + mod = __import__(local_module) + mod.register_types(root_module) + + ns3modulegen_core_customizations.generate_callback_classes(root_module.after_forward_declarations, + callbacks_list.callback_classes) + + + register_methods(root_module) + + for local_module in LOCAL_MODULES: + mod = __import__(local_module) + mod.register_methods(root_module) + + ns3modulegen_core_customizations.Object_customizations(root_module) + + register_functions(root_module) + + for local_module in LOCAL_MODULES: + mod = __import__(local_module) + mod.register_functions(root_module) + + root_module.generate(out, '_ns3') + + out.close() + +if __name__ == '__main__': + main() + diff --git a/bindings/python/ns3modulegen_core_customizations.py b/bindings/python/ns3modulegen_core_customizations.py new file mode 100644 index 000000000..2a23e48b8 --- /dev/null +++ b/bindings/python/ns3modulegen_core_customizations.py @@ -0,0 +1,495 @@ +import re + +from pybindgen.typehandlers import base as typehandlers +from pybindgen import (ReturnValue, Parameter) +from pybindgen.cppmethod import CustomCppMethodWrapper, CustomCppConstructorWrapper +from pybindgen.typehandlers.codesink import MemoryCodeSink +from pybindgen.typehandlers import ctypeparser +import warnings + +from pybindgen.typehandlers.base import CodeGenerationError + +import sys + +class SmartPointerTransformation(typehandlers.TypeTransformation): + """ + This class provides a "type transformation" that tends to support + NS-3 smart pointers. Parameters such as "Ptr foo" are + transformed into something like Parameter.new("Foo*", "foo", + transfer_ownership=False). Return values such as Ptr are + transformed into ReturnValue.new("Foo*", + caller_owns_return=False). Since the underlying objects have + reference counting, PyBindGen does the right thing. + """ + def __init__(self): + super(SmartPointerTransformation, self).__init__() + self.rx = re.compile(r'(ns3::|::ns3::|)Ptr<([^>]+)>') + + def _get_untransformed_type_traits(self, name): + m = self.rx.match(name) + is_const = False + if m is None: + return None, False + else: + name1 = m.group(2).strip() + if name1.startswith('const '): + name1 = name1[len('const '):] + is_const = True + if name1.endswith(' const'): + name1 = name1[:-len(' const')] + is_const = True + new_name = name1+' *' + + if new_name.startswith('::'): + new_name = new_name[2:] + return new_name, is_const + + def get_untransformed_name(self, name): + new_name, dummy_is_const = self._get_untransformed_type_traits(name) + return new_name + + def create_type_handler(self, type_handler, *args, **kwargs): + if issubclass(type_handler, Parameter): + kwargs['transfer_ownership'] = False + elif issubclass(type_handler, ReturnValue): + kwargs['caller_owns_return'] = False + else: + raise AssertionError + + ## fix the ctype, add ns3:: namespace + orig_ctype, is_const = self._get_untransformed_type_traits(args[0]) + if is_const: + kwargs['is_const'] = True + correct_ctype = 'ns3::Ptr< %s const >' % orig_ctype[:-2] + else: + correct_ctype = 'ns3::Ptr< %s >' % orig_ctype[:-2] + args = tuple([correct_ctype] + list(args[1:])) + + handler = type_handler(*args, **kwargs) + handler.set_tranformation(self, orig_ctype) + return handler + + def untransform(self, type_handler, declarations, code_block, expression): + return 'ns3::PeekPointer (%s)' % (expression,) + + def transform(self, type_handler, declarations, code_block, expression): + assert type_handler.untransformed_ctype[-1] == '*' + return 'ns3::Ptr< %s > (%s)' % (type_handler.untransformed_ctype[:-1], expression) + +## register the type transformation +transf = SmartPointerTransformation() +typehandlers.return_type_matcher.register_transformation(transf) +typehandlers.param_type_matcher.register_transformation(transf) +del transf + + +class ArgvParam(Parameter): + """ + Converts a python list-of-strings argument to a pair of 'int argc, + char *argv[]' arguments to pass into C. + + One Python argument becomes two C function arguments -> it's a miracle! + + Note: this parameter type handler is not registered by any name; + must be used explicitly. + """ + + DIRECTIONS = [Parameter.DIRECTION_IN] + CTYPES = [] + + def convert_c_to_python(self, wrapper): + raise NotImplementedError + + def convert_python_to_c(self, wrapper): + py_name = wrapper.declarations.declare_variable('PyObject*', 'py_' + self.name) + argc_var = wrapper.declarations.declare_variable('int', 'argc') + name = wrapper.declarations.declare_variable('char**', self.name) + idx = wrapper.declarations.declare_variable('Py_ssize_t', 'idx') + wrapper.parse_params.add_parameter('O!', ['&PyList_Type', '&'+py_name], self.name) + + #wrapper.before_call.write_error_check('!PyList_Check(%s)' % py_name) # XXX + + wrapper.before_call.write_code("%s = (char **) malloc(sizeof(char*)*PyList_Size(%s));" + % (name, py_name)) + wrapper.before_call.add_cleanup_code('free(%s);' % name) + wrapper.before_call.write_code(''' +for (%(idx)s = 0; %(idx)s < PyList_Size(%(py_name)s); %(idx)s++) +{ +''' % vars()) + wrapper.before_call.sink.indent() + wrapper.before_call.write_code(''' +PyObject *item = PyList_GET_ITEM(%(py_name)s, %(idx)s); +''' % vars()) + #wrapper.before_call.write_error_check('item == NULL') + wrapper.before_call.write_error_check( + '!PyString_Check(item)', + failure_cleanup=('PyErr_SetString(PyExc_TypeError, ' + '"argument %s must be a list of strings");') % self.name) + wrapper.before_call.write_code( + '%s[%s] = PyString_AsString(item);' % (name, idx)) + wrapper.before_call.sink.unindent() + wrapper.before_call.write_code('}') + wrapper.before_call.write_code('%s = PyList_Size(%s);' % (argc_var, py_name)) + + wrapper.call_params.append(argc_var) + wrapper.call_params.append(name) + + +class CallbackImplProxyMethod(typehandlers.ReverseWrapperBase): + """ + Class that generates a proxy virtual method that calls a similarly named python method. + """ + + def __init__(self, return_value, parameters): + super(CallbackImplProxyMethod, self).__init__(return_value, parameters) + + def generate_python_call(self): + """code to call the python method""" + build_params = self.build_params.get_parameters() + if build_params[0][0] == '"': + build_params[0] = '(char *) ' + build_params[0] + args = self.before_call.declare_variable('PyObject*', 'args') + self.before_call.write_code('%s = Py_BuildValue(%s);' + % (args, ', '.join(build_params))) + self.before_call.add_cleanup_code('Py_DECREF(%s);' % args) + self.before_call.write_code('py_retval = PyObject_CallObject(m_callback, %s);' % args) + self.before_call.write_error_check('py_retval == NULL') + self.before_call.add_cleanup_code('Py_DECREF(py_retval);') + + + + +def generate_callback_classes(out, callbacks): + for callback_impl_num, template_parameters in enumerate(callbacks): + sink = MemoryCodeSink() + cls_name = "ns3::Callback< %s >" % ', '.join(template_parameters) + #print >> sys.stderr, "***** trying to register callback: %r" % cls_name + class_name = "PythonCallbackImpl%i" % callback_impl_num + sink.writeln(''' +class %s : public ns3::CallbackImpl<%s> +{ +public: + PyObject *m_callback; + %s(PyObject *callback) + { + Py_INCREF(callback); + m_callback = callback; + } + virtual ~%s() + { + Py_DECREF(m_callback); + m_callback = NULL; + } + + virtual bool IsEqual(ns3::Ptr other_base) const + { + const %s *other = dynamic_cast (ns3::PeekPointer (other_base)); + if (other != NULL) + return (other->m_callback == m_callback); + else + return false; + } + +''' % (class_name, ', '.join(template_parameters), class_name, class_name, class_name, class_name)) + sink.indent() + callback_return = template_parameters[0] + return_ctype = ctypeparser.parse_type(callback_return) + if ('const' in return_ctype.remove_modifiers()): + kwargs = {'is_const': True} + else: + kwargs = {} + try: + return_type = ReturnValue.new(str(return_ctype), **kwargs) + except (typehandlers.TypeLookupError, typehandlers.TypeConfigurationError), ex: + warnings.warn("***** Unable to register callback; Return value '%s' error (used in %s): %r" + % (callback_return, cls_name, ex), + Warning) + continue + + arguments = [] + ok = True + callback_parameters = [arg for arg in template_parameters[1:] if arg != 'ns3::empty'] + for arg_num, arg_type in enumerate(callback_parameters): + arg_name = 'arg%i' % (arg_num+1) + + param_ctype = ctypeparser.parse_type(arg_type) + if ('const' in param_ctype.remove_modifiers()): + kwargs = {'is_const': True} + else: + kwargs = {} + try: + arguments.append(Parameter.new(str(param_ctype), arg_name, **kwargs)) + except (typehandlers.TypeLookupError, typehandlers.TypeConfigurationError), ex: + warnings.warn("***** Unable to register callback; parameter '%s %s' error (used in %s): %r" + % (arg_type, arg_name, cls_name, ex), + Warning) + ok = False + if not ok: + continue + + wrapper = CallbackImplProxyMethod(return_type, arguments) + wrapper.generate(sink, 'operator()', decl_modifiers=[]) + + sink.unindent() + sink.writeln('};\n') + sink.flush_to(out) + + class PythonCallbackParameter(Parameter): + "Class handlers" + CTYPES = [cls_name] + #print >> sys.stderr, "***** registering callback handler: %r" % ctypeparser.normalize_type_string(cls_name) + DIRECTIONS = [Parameter.DIRECTION_IN] + PYTHON_CALLBACK_IMPL_NAME = class_name + TEMPLATE_ARGS = template_parameters + + def convert_python_to_c(self, wrapper): + "parses python args to get C++ value" + assert isinstance(wrapper, typehandlers.ForwardWrapperBase) + + py_callback = wrapper.declarations.declare_variable('PyObject*', self.name) + wrapper.parse_params.add_parameter('O', ['&'+py_callback], self.name) + wrapper.before_call.write_error_check( + '!PyCallable_Check(%s)' % py_callback, + 'PyErr_SetString(PyExc_TypeError, "parameter \'%s\' must be callbale");' % self.name) + callback_impl = wrapper.declarations.declare_variable( + 'ns3::Ptr<%s>' % self.PYTHON_CALLBACK_IMPL_NAME, + '%s_cb_impl' % self.name) + wrapper.before_call.write_code("%s = ns3::Create<%s> (%s);" + % (callback_impl, self.PYTHON_CALLBACK_IMPL_NAME, py_callback)) + wrapper.call_params.append( + 'ns3::Callback<%s> (%s)' % (', '.join(self.TEMPLATE_ARGS), callback_impl)) + + def convert_c_to_python(self, wrapper): + raise typehandlers.NotSupportedError("Reverse wrappers for ns3::Callback<...> types " + "(python using callbacks defined in C++) not implemented.") + + +# def write_preamble(out): +# pybindgen.write_preamble(out) +# out.writeln("#include \"ns3/everything.h\"") + + + +def Simulator_customizations(module): + Simulator = module['ns3::Simulator'] + + ## Simulator::Schedule(delay, callback, ...user..args...) + Simulator.add_custom_method_wrapper("Schedule", "_wrap_Simulator_Schedule", + flags=["METH_VARARGS", "METH_KEYWORDS", "METH_STATIC"]) + + + ## Simulator::ScheduleNow(callback, ...user..args...) + Simulator.add_custom_method_wrapper("ScheduleNow", "_wrap_Simulator_ScheduleNow", + flags=["METH_VARARGS", "METH_KEYWORDS", "METH_STATIC"]) + + + ## Simulator::ScheduleDestroy(callback, ...user..args...) + Simulator.add_custom_method_wrapper("ScheduleDestroy", "_wrap_Simulator_ScheduleDestroy", + flags=["METH_VARARGS", "METH_KEYWORDS", "METH_STATIC"]) + + +def CommandLine_customizations(module): + CommandLine = module['ns3::CommandLine'] + CommandLine.add_method('Parse', None, [ArgvParam(None, 'argv')], + is_static=False) + + +def Object_customizations(module): + ## --------------------------------------------------------------------- + ## Here we generate custom constructor code for all classes that + ## derive from ns3::Object. The custom constructors are needed in + ## order to support kwargs only and to translate kwargs into ns3 + ## attributes, etc. + ## --------------------------------------------------------------------- + Object = module['ns3::Object'] + + + ## add a GetTypeId method to all generatd helper classes + def helper_class_hook(helper_class): + decl = """ +static ns3::TypeId GetTypeId (void) +{ + static ns3::TypeId tid = ns3::TypeId ("%s") + .SetParent< %s > () + ; + return tid; +}""" % (helper_class.name, helper_class.class_.full_name) + + helper_class.add_custom_method(decl) + helper_class.add_post_generation_code( + "NS_OBJECT_ENSURE_REGISTERED (%s);" % helper_class.name) + Object.add_helper_class_hook(helper_class_hook) + + ## Replace all class constructors with a generic constructor based on CreateObject (AttributeList) + module.header.writeln(''' +namespace ns3 { + +void PythonCompleteConstruct (Ptr object, TypeId typeId, const AttributeList &attributes); + +template +Ptr CreateObjectPython (PyObject *pyobj, const AttributeList &attributes) +{ + Ptr p = Ptr (new T (), false); + p->set_pyobj (pyobj); + PythonCompleteConstruct (p, T::GetTypeId (), attributes); + return p; +} + +} // namespace ns3 + +''') + + for cls in module.classes: + if not cls.is_subclass(Object): + continue + cls.constructors = [] # clear the list of constructors + + ## add our own custom constructor, if possible + try: + construct_name = cls.get_construct_name() + except CodeGenerationError: + construct_name = None + + if construct_name and not cls.helper_class: + construct_code = ''' + ns3::Ptr< %(CONSTRUCT_NAME)s > obj = ns3::CreateObject< %(CONSTRUCT_NAME)s > (attrList); + obj->Ref (); + self->obj = ns3::PeekPointer (obj); +''' % dict (CONSTRUCT_NAME=construct_name) + + elif not construct_name and not cls.helper_class: + continue + + elif not construct_name and cls.helper_class: + construct_code = ''' + if (self->ob_type != &%(PYTYPESTRUCT)s) + { + ns3::Ptr< %(HELPER_CLASS_NAME)s > obj = ns3::CreateObjectPython< %(HELPER_CLASS_NAME)s > ((PyObject *)self, attrList); + obj->Ref (); + self->obj = ns3::PeekPointer (obj); + } else { + PyErr_SetString(PyExc_TypeError, "Class cannot be constructed (unless subclassed)"); + { + PyObject *exc_type, *traceback; + PyErr_Fetch(&exc_type, return_exception, &traceback); + Py_XDECREF(exc_type); + Py_XDECREF(traceback); + } + return -1; + } +''' % dict (CONSTRUCT_NAME=construct_name, HELPER_CLASS_NAME=cls.helper_class.name, + PYTYPESTRUCT=cls.pytypestruct) + + elif construct_name and cls.helper_class: + construct_code = ''' + if (self->ob_type != &%(PYTYPESTRUCT)s) + { + ns3::Ptr< %(HELPER_CLASS_NAME)s > obj = ns3::CreateObjectPython< %(HELPER_CLASS_NAME)s > ((PyObject *)self, attrList); + obj->Ref (); + self->obj = ns3::PeekPointer (obj); + } else { + ns3::Ptr< %(CONSTRUCT_NAME)s > obj = ns3::CreateObject< %(CONSTRUCT_NAME)s > (attrList); + obj->Ref (); + self->obj = ns3::PeekPointer (obj); + } +''' % dict (CONSTRUCT_NAME=construct_name, HELPER_CLASS_NAME=cls.helper_class.name, + PYTYPESTRUCT=cls.pytypestruct) + else: + raise AssertionError + + wrapper_name = "_wrap_create_object_%s" % (cls.full_name.replace(':', '_'),) + constructor = ''' +static int %(WRAPPER_NAME)s (%(PYSTRUCT)s *self, PyObject *args, PyObject *kwargs, PyObject **return_exception) +{ + if (PyTuple_Size(args)) { + PyErr_SetString(PyExc_TypeError, "positional arguments not supported " + "for ns3.Object constructors, only keyword arguments" + " should be used (AttributeName=Value)"); + { + PyObject *exc_type, *traceback; + PyErr_Fetch(&exc_type, return_exception, &traceback); + Py_XDECREF(exc_type); + Py_XDECREF(traceback); + } + return -1; + } + ns3::AttributeList attrList; + if (kwargs && KwargsToAttributeList(kwargs, %(CLASS_NAME)s::GetTypeId(), attrList)) { + { + PyObject *exc_type, *traceback; + PyErr_Fetch(&exc_type, return_exception, &traceback); + Py_XDECREF(exc_type); + Py_XDECREF(traceback); + } + return -1; + } + %(CONSTRUCT_CODE)s + return 0; +} +''' % dict(WRAPPER_NAME=wrapper_name, PYSTRUCT=cls.pystruct, CLASS_NAME=cls.full_name, + CONSTRUCT_CODE=construct_code, PURE_VIRTUALS=cls.have_pure_virtual_methods) + cls.add_constructor(CustomCppConstructorWrapper(wrapper_name, constructor)) + + + # Generate conversion function from PyObject* to AttributeValue +# sink = module.body +# sink.writeln(''' +# Ptr AttributeValueFromPyObject (PyObject *obj) +# { +# // note: needs to check for bool first, because bool is a subclass of int +# if (PyBool_Check(obj)) { +# return Create(PyObject_IsTrue(obj)); +# } else if (PyInt_Check(obj)) { +# return Create(PyInt_AsLong(obj)); +# } else if (PyLong_Check(obj)) { +# return Create(PyLong_AsLongLong(obj)); +# } else if (PyFloat_Check(obj)) { +# return Create(PyFloat_AsDouble(obj)); +# } + +# ''') + + + + ## --------------------------------------------------------------------- + ## -------------- write the KwargsToAttributeList function ------------- + ## --------------------------------------------------------------------- + Attribute = module['ns3::AttributeValue'] + module.after_forward_declarations.writeln( + 'int KwargsToAttributeList(PyObject *kwargs, ns3::TypeId tid, ns3::AttributeList &oAttrList);') + + module.body.writeln( +''' +int KwargsToAttributeList(PyObject *kwargs, ns3::TypeId tid, ns3::AttributeList &oAttrList) +{ + PyObject *key, *value; + Py_ssize_t pos = 0; + + while (PyDict_Next(kwargs, &pos, &key, &value)) { + if (!PyString_Check(key)) { + PyErr_SetString(PyExc_TypeError, "kwargs keys must be strings"); + return -1; + } + if (PyObject_IsInstance(value, (PyObject*) &%s)) { + oAttrList.SetWithTid(tid, PyString_AsString(key), *((%s *) value)->obj);''' \ + % (Attribute.pytypestruct, Attribute.pystruct)) + + for conversion_source in Attribute.get_all_implicit_conversions(): + module.body.writeln(''' + } else if (PyObject_IsInstance(value, (PyObject*) &%s)) { + oAttrList.SetWithTid(tid, PyString_AsString(key), *((%s *) value)->obj);''' \ + % (conversion_source.pytypestruct, conversion_source.pystruct)) + + possible_type_names = ", ".join([cls.name for cls in [Attribute] + Attribute.get_all_implicit_conversions()]) + module.body.writeln(''' + } else { + PyErr_Format(PyExc_TypeError, \"parameter must an instance of one of the types (%s), not %%s\", value->ob_type->tp_name); + return -1; + }''' % (possible_type_names)) + + module.body.writeln( +''' + } + return 0; +} +''') diff --git a/bindings/python/ns3modulegen_generated.py b/bindings/python/ns3modulegen_generated.py new file mode 100644 index 000000000..ad3e8d947 --- /dev/null +++ b/bindings/python/ns3modulegen_generated.py @@ -0,0 +1,642 @@ +from pybindgen import Module, FileCodeSink, write_preamble, param, retval + + +import pybindgen.settings +import warnings + +class ErrorHandler(pybindgen.settings.ErrorHandler): + def handle_error(self, wrapper, exception, traceback_): + warnings.warn("exception %r in wrapper %s" % (exception, wrapper)) + return True +pybindgen.settings.error_handler = ErrorHandler() + + +import sys +import ns3_module_core +import ns3_module_simulator +import ns3_module_mobility +import ns3_module_common +import ns3_module_contrib +import ns3_module_node +import ns3_module_point_to_point +import ns3_module_internet_stack +import ns3_module_wifi +import ns3_module_csma +import ns3_module_packet_sink +import ns3_module_global_routing +import ns3_module_onoff +import ns3_module_olsr +import ns3_module_udp_echo +import ns3_module_helper + +def module_init(): + root_module = Module('ns3', cpp_namespace='::ns3') + return root_module + +def register_types(module): + root_module = module.get_root() + + root_module.begin_section('ns3_module_core') + ns3_module_core.register_types(module) + + try: + import ns3_module_core__local + except ImportError: + pass + else: + ns3_module_core__local.register_types(module) + + root_module.end_section('ns3_module_core') + root_module.begin_section('ns3_module_simulator') + ns3_module_simulator.register_types(module) + + try: + import ns3_module_simulator__local + except ImportError: + pass + else: + ns3_module_simulator__local.register_types(module) + + root_module.end_section('ns3_module_simulator') + root_module.begin_section('ns3_module_mobility') + ns3_module_mobility.register_types(module) + + try: + import ns3_module_mobility__local + except ImportError: + pass + else: + ns3_module_mobility__local.register_types(module) + + root_module.end_section('ns3_module_mobility') + root_module.begin_section('ns3_module_common') + ns3_module_common.register_types(module) + + try: + import ns3_module_common__local + except ImportError: + pass + else: + ns3_module_common__local.register_types(module) + + root_module.end_section('ns3_module_common') + root_module.begin_section('ns3_module_contrib') + ns3_module_contrib.register_types(module) + + try: + import ns3_module_contrib__local + except ImportError: + pass + else: + ns3_module_contrib__local.register_types(module) + + root_module.end_section('ns3_module_contrib') + root_module.begin_section('ns3_module_node') + ns3_module_node.register_types(module) + + try: + import ns3_module_node__local + except ImportError: + pass + else: + ns3_module_node__local.register_types(module) + + root_module.end_section('ns3_module_node') + root_module.begin_section('ns3_module_point_to_point') + ns3_module_point_to_point.register_types(module) + + try: + import ns3_module_point_to_point__local + except ImportError: + pass + else: + ns3_module_point_to_point__local.register_types(module) + + root_module.end_section('ns3_module_point_to_point') + root_module.begin_section('ns3_module_internet_stack') + ns3_module_internet_stack.register_types(module) + + try: + import ns3_module_internet_stack__local + except ImportError: + pass + else: + ns3_module_internet_stack__local.register_types(module) + + root_module.end_section('ns3_module_internet_stack') + root_module.begin_section('ns3_module_wifi') + ns3_module_wifi.register_types(module) + + try: + import ns3_module_wifi__local + except ImportError: + pass + else: + ns3_module_wifi__local.register_types(module) + + root_module.end_section('ns3_module_wifi') + root_module.begin_section('ns3_module_csma') + ns3_module_csma.register_types(module) + + try: + import ns3_module_csma__local + except ImportError: + pass + else: + ns3_module_csma__local.register_types(module) + + root_module.end_section('ns3_module_csma') + root_module.begin_section('ns3_module_packet_sink') + ns3_module_packet_sink.register_types(module) + + try: + import ns3_module_packet_sink__local + except ImportError: + pass + else: + ns3_module_packet_sink__local.register_types(module) + + root_module.end_section('ns3_module_packet_sink') + root_module.begin_section('ns3_module_global_routing') + ns3_module_global_routing.register_types(module) + + try: + import ns3_module_global_routing__local + except ImportError: + pass + else: + ns3_module_global_routing__local.register_types(module) + + root_module.end_section('ns3_module_global_routing') + root_module.begin_section('ns3_module_onoff') + ns3_module_onoff.register_types(module) + + try: + import ns3_module_onoff__local + except ImportError: + pass + else: + ns3_module_onoff__local.register_types(module) + + root_module.end_section('ns3_module_onoff') + root_module.begin_section('ns3_module_olsr') + ns3_module_olsr.register_types(module) + + try: + import ns3_module_olsr__local + except ImportError: + pass + else: + ns3_module_olsr__local.register_types(module) + + root_module.end_section('ns3_module_olsr') + root_module.begin_section('ns3_module_udp_echo') + ns3_module_udp_echo.register_types(module) + + try: + import ns3_module_udp_echo__local + except ImportError: + pass + else: + ns3_module_udp_echo__local.register_types(module) + + root_module.end_section('ns3_module_udp_echo') + root_module.begin_section('ns3_module_helper') + ns3_module_helper.register_types(module) + + try: + import ns3_module_helper__local + except ImportError: + pass + else: + ns3_module_helper__local.register_types(module) + + root_module.end_section('ns3_module_helper') + + ## Register a nested module for the namespace internal + + nested_module = module.add_cpp_namespace('internal') + register_types_ns3_internal(nested_module) + + + ## Register a nested module for the namespace TimeStepPrecision + + nested_module = module.add_cpp_namespace('TimeStepPrecision') + register_types_ns3_TimeStepPrecision(nested_module) + + + ## Register a nested module for the namespace Config + + nested_module = module.add_cpp_namespace('Config') + register_types_ns3_Config(nested_module) + + + ## Register a nested module for the namespace olsr + + nested_module = module.add_cpp_namespace('olsr') + register_types_ns3_olsr(nested_module) + + +def register_types_ns3_internal(module): + root_module = module.get_root() + + +def register_types_ns3_TimeStepPrecision(module): + root_module = module.get_root() + + +def register_types_ns3_Config(module): + root_module = module.get_root() + + +def register_types_ns3_olsr(module): + root_module = module.get_root() + + +def register_methods(root_module): + root_module.begin_section('ns3_module_core') + ns3_module_core.register_methods(root_module) + + try: + import ns3_module_core__local + except ImportError: + pass + else: + ns3_module_core__local.register_methods(root_module) + + root_module.end_section('ns3_module_core') + root_module.begin_section('ns3_module_simulator') + ns3_module_simulator.register_methods(root_module) + + try: + import ns3_module_simulator__local + except ImportError: + pass + else: + ns3_module_simulator__local.register_methods(root_module) + + root_module.end_section('ns3_module_simulator') + root_module.begin_section('ns3_module_mobility') + ns3_module_mobility.register_methods(root_module) + + try: + import ns3_module_mobility__local + except ImportError: + pass + else: + ns3_module_mobility__local.register_methods(root_module) + + root_module.end_section('ns3_module_mobility') + root_module.begin_section('ns3_module_common') + ns3_module_common.register_methods(root_module) + + try: + import ns3_module_common__local + except ImportError: + pass + else: + ns3_module_common__local.register_methods(root_module) + + root_module.end_section('ns3_module_common') + root_module.begin_section('ns3_module_contrib') + ns3_module_contrib.register_methods(root_module) + + try: + import ns3_module_contrib__local + except ImportError: + pass + else: + ns3_module_contrib__local.register_methods(root_module) + + root_module.end_section('ns3_module_contrib') + root_module.begin_section('ns3_module_node') + ns3_module_node.register_methods(root_module) + + try: + import ns3_module_node__local + except ImportError: + pass + else: + ns3_module_node__local.register_methods(root_module) + + root_module.end_section('ns3_module_node') + root_module.begin_section('ns3_module_point_to_point') + ns3_module_point_to_point.register_methods(root_module) + + try: + import ns3_module_point_to_point__local + except ImportError: + pass + else: + ns3_module_point_to_point__local.register_methods(root_module) + + root_module.end_section('ns3_module_point_to_point') + root_module.begin_section('ns3_module_internet_stack') + ns3_module_internet_stack.register_methods(root_module) + + try: + import ns3_module_internet_stack__local + except ImportError: + pass + else: + ns3_module_internet_stack__local.register_methods(root_module) + + root_module.end_section('ns3_module_internet_stack') + root_module.begin_section('ns3_module_wifi') + ns3_module_wifi.register_methods(root_module) + + try: + import ns3_module_wifi__local + except ImportError: + pass + else: + ns3_module_wifi__local.register_methods(root_module) + + root_module.end_section('ns3_module_wifi') + root_module.begin_section('ns3_module_csma') + ns3_module_csma.register_methods(root_module) + + try: + import ns3_module_csma__local + except ImportError: + pass + else: + ns3_module_csma__local.register_methods(root_module) + + root_module.end_section('ns3_module_csma') + root_module.begin_section('ns3_module_packet_sink') + ns3_module_packet_sink.register_methods(root_module) + + try: + import ns3_module_packet_sink__local + except ImportError: + pass + else: + ns3_module_packet_sink__local.register_methods(root_module) + + root_module.end_section('ns3_module_packet_sink') + root_module.begin_section('ns3_module_global_routing') + ns3_module_global_routing.register_methods(root_module) + + try: + import ns3_module_global_routing__local + except ImportError: + pass + else: + ns3_module_global_routing__local.register_methods(root_module) + + root_module.end_section('ns3_module_global_routing') + root_module.begin_section('ns3_module_onoff') + ns3_module_onoff.register_methods(root_module) + + try: + import ns3_module_onoff__local + except ImportError: + pass + else: + ns3_module_onoff__local.register_methods(root_module) + + root_module.end_section('ns3_module_onoff') + root_module.begin_section('ns3_module_olsr') + ns3_module_olsr.register_methods(root_module) + + try: + import ns3_module_olsr__local + except ImportError: + pass + else: + ns3_module_olsr__local.register_methods(root_module) + + root_module.end_section('ns3_module_olsr') + root_module.begin_section('ns3_module_udp_echo') + ns3_module_udp_echo.register_methods(root_module) + + try: + import ns3_module_udp_echo__local + except ImportError: + pass + else: + ns3_module_udp_echo__local.register_methods(root_module) + + root_module.end_section('ns3_module_udp_echo') + root_module.begin_section('ns3_module_helper') + ns3_module_helper.register_methods(root_module) + + try: + import ns3_module_helper__local + except ImportError: + pass + else: + ns3_module_helper__local.register_methods(root_module) + + root_module.end_section('ns3_module_helper') + return + +def register_functions(root_module): + module = root_module + root_module.begin_section('ns3_module_core') + ns3_module_core.register_functions(root_module) + + try: + import ns3_module_core__local + except ImportError: + pass + else: + ns3_module_core__local.register_functions(root_module) + + root_module.end_section('ns3_module_core') + root_module.begin_section('ns3_module_simulator') + ns3_module_simulator.register_functions(root_module) + + try: + import ns3_module_simulator__local + except ImportError: + pass + else: + ns3_module_simulator__local.register_functions(root_module) + + root_module.end_section('ns3_module_simulator') + root_module.begin_section('ns3_module_mobility') + ns3_module_mobility.register_functions(root_module) + + try: + import ns3_module_mobility__local + except ImportError: + pass + else: + ns3_module_mobility__local.register_functions(root_module) + + root_module.end_section('ns3_module_mobility') + root_module.begin_section('ns3_module_common') + ns3_module_common.register_functions(root_module) + + try: + import ns3_module_common__local + except ImportError: + pass + else: + ns3_module_common__local.register_functions(root_module) + + root_module.end_section('ns3_module_common') + root_module.begin_section('ns3_module_contrib') + ns3_module_contrib.register_functions(root_module) + + try: + import ns3_module_contrib__local + except ImportError: + pass + else: + ns3_module_contrib__local.register_functions(root_module) + + root_module.end_section('ns3_module_contrib') + root_module.begin_section('ns3_module_node') + ns3_module_node.register_functions(root_module) + + try: + import ns3_module_node__local + except ImportError: + pass + else: + ns3_module_node__local.register_functions(root_module) + + root_module.end_section('ns3_module_node') + root_module.begin_section('ns3_module_point_to_point') + ns3_module_point_to_point.register_functions(root_module) + + try: + import ns3_module_point_to_point__local + except ImportError: + pass + else: + ns3_module_point_to_point__local.register_functions(root_module) + + root_module.end_section('ns3_module_point_to_point') + root_module.begin_section('ns3_module_internet_stack') + ns3_module_internet_stack.register_functions(root_module) + + try: + import ns3_module_internet_stack__local + except ImportError: + pass + else: + ns3_module_internet_stack__local.register_functions(root_module) + + root_module.end_section('ns3_module_internet_stack') + root_module.begin_section('ns3_module_wifi') + ns3_module_wifi.register_functions(root_module) + + try: + import ns3_module_wifi__local + except ImportError: + pass + else: + ns3_module_wifi__local.register_functions(root_module) + + root_module.end_section('ns3_module_wifi') + root_module.begin_section('ns3_module_csma') + ns3_module_csma.register_functions(root_module) + + try: + import ns3_module_csma__local + except ImportError: + pass + else: + ns3_module_csma__local.register_functions(root_module) + + root_module.end_section('ns3_module_csma') + root_module.begin_section('ns3_module_packet_sink') + ns3_module_packet_sink.register_functions(root_module) + + try: + import ns3_module_packet_sink__local + except ImportError: + pass + else: + ns3_module_packet_sink__local.register_functions(root_module) + + root_module.end_section('ns3_module_packet_sink') + root_module.begin_section('ns3_module_global_routing') + ns3_module_global_routing.register_functions(root_module) + + try: + import ns3_module_global_routing__local + except ImportError: + pass + else: + ns3_module_global_routing__local.register_functions(root_module) + + root_module.end_section('ns3_module_global_routing') + root_module.begin_section('ns3_module_onoff') + ns3_module_onoff.register_functions(root_module) + + try: + import ns3_module_onoff__local + except ImportError: + pass + else: + ns3_module_onoff__local.register_functions(root_module) + + root_module.end_section('ns3_module_onoff') + root_module.begin_section('ns3_module_olsr') + ns3_module_olsr.register_functions(root_module) + + try: + import ns3_module_olsr__local + except ImportError: + pass + else: + ns3_module_olsr__local.register_functions(root_module) + + root_module.end_section('ns3_module_olsr') + root_module.begin_section('ns3_module_udp_echo') + ns3_module_udp_echo.register_functions(root_module) + + try: + import ns3_module_udp_echo__local + except ImportError: + pass + else: + ns3_module_udp_echo__local.register_functions(root_module) + + root_module.end_section('ns3_module_udp_echo') + root_module.begin_section('ns3_module_helper') + ns3_module_helper.register_functions(root_module) + + try: + import ns3_module_helper__local + except ImportError: + pass + else: + ns3_module_helper__local.register_functions(root_module) + + root_module.end_section('ns3_module_helper') + register_functions_ns3_internal(module.get_submodule('internal'), root_module) + register_functions_ns3_TimeStepPrecision(module.get_submodule('TimeStepPrecision'), root_module) + register_functions_ns3_Config(module.get_submodule('Config'), root_module) + register_functions_ns3_olsr(module.get_submodule('olsr'), root_module) + return + +def register_functions_ns3_internal(module, root_module): + return + +def register_functions_ns3_TimeStepPrecision(module, root_module): + return + +def register_functions_ns3_Config(module, root_module): + return + +def register_functions_ns3_olsr(module, root_module): + return + +def main(): + out = FileCodeSink(sys.stdout) + root_module = module_init() + register_types(root_module) + register_methods(root_module) + register_functions(root_module) + write_preamble(out) + root_module.generate(out) + +if __name__ == '__main__': + main() + diff --git a/bindings/python/ns3modulescan.py b/bindings/python/ns3modulescan.py new file mode 100644 index 000000000..879f6ea5d --- /dev/null +++ b/bindings/python/ns3modulescan.py @@ -0,0 +1,281 @@ +#! /usr/bin/env python + +import sys +import os.path + +import pybindgen.settings +from pybindgen.gccxmlparser import ModuleParser, PygenClassifier, PygenSection, WrapperWarning +from pybindgen.typehandlers.codesink import FileCodeSink +from pygccxml.declarations import templates +from pygccxml.declarations.class_declaration import class_t +from pygccxml.declarations.calldef import free_function_t, member_function_t, constructor_t + + +## we need the smart pointer type transformation to be active even +## during gccxml scanning. +import ns3modulegen_core_customizations + + +## silence gccxmlparser errors; we only want error handling in the +## generated python script, not while scanning. +class ErrorHandler(pybindgen.settings.ErrorHandler): + def handle_error(self, dummy_wrapper, dummy_exception, dummy_traceback_): + return True +pybindgen.settings.error_handler = ErrorHandler() +import warnings +warnings.filterwarnings(category=WrapperWarning, action='ignore') + +type_annotations = { + '::ns3::RefCountBase': { + 'incref_method': 'Ref', + 'decref_method': 'Unref', + 'peekref_method': 'GetReferenceCount', + 'automatic_type_narrowing': 'true', + }, + '::ns3::Object': { + 'incref_method': 'Ref', + 'decref_method': 'Unref', + 'peekref_method': 'GetReferenceCount', + 'automatic_type_narrowing': 'true', + }, + '::ns3::Packet': { + 'incref_method': 'Ref', + 'decref_method': 'Unref', + 'peekref_method': 'GetReferenceCount', + }, + '::ns3::CallbackImplBase': { + 'incref_method': 'Ref', + 'decref_method': 'Unref', + 'peekref_method': 'GetReferenceCount', + }, + '::ns3::PacketMetadata': { + 'ignore': None, + }, + '::ns3::AttributeChecker': { + 'incref_method': 'Ref', + 'decref_method': 'Unref', + 'automatic_type_narrowing': 'true', + 'allow_subclassing': 'false', + }, + '::ns3::AttributeValue': { + 'incref_method': 'Ref', + 'decref_method': 'Unref', + 'automatic_type_narrowing': 'true', + 'allow_subclassing': 'false', + }, + 'ns3::RandomVariable::RandomVariable(ns3::RandomVariableBase const & variable) [constructor]': { + 'ignore': None, + }, + 'ns3::RandomVariableBase * ns3::RandomVariable::Peek() const [member function]': { + 'ignore': None, + }, + 'void ns3::RandomVariable::GetSeed(uint32_t * seed) const [member function]': { + 'params': {'seed':{'direction':'out', + 'array_length':'6'}} + }, + 'bool ns3::TypeId::LookupAttributeByName(std::string name, ns3::TypeId::AttributeInfo * info) const [member function]': { + 'params': {'info':{'transfer_ownership': 'false'}} + }, + 'static bool ns3::TypeId::LookupByNameFailSafe(std::string name, ns3::TypeId * tid) [member function]': { + 'params': {'tid': {'transfer_ownership': 'false'}} + }, + 'bool ns3::TraceSourceAccessor::ConnectWithoutContext(ns3::ObjectBase * obj, ns3::CallbackBase const & cb) const [member function]': { + 'params': {'obj': {'transfer_ownership':'false'}} + }, + 'bool ns3::TraceSourceAccessor::Connect(ns3::ObjectBase * obj, std::string context, ns3::CallbackBase const & cb) const [member function]': { + 'params': {'obj': {'transfer_ownership':'false'}} + }, + 'bool ns3::TraceSourceAccessor::DisconnectWithoutContext(ns3::ObjectBase * obj, ns3::CallbackBase const & cb) const [member function]': { + 'params': {'obj': {'transfer_ownership':'false'}} + }, + 'bool ns3::TraceSourceAccessor::Disconnect(ns3::ObjectBase * obj, std::string context, ns3::CallbackBase const & cb) const [member function]': { + 'params': {'obj': {'transfer_ownership':'false'}} + }, + 'bool ns3::AttributeAccessor::Set(ns3::ObjectBase * object, ns3::AttributeValue const & value) const [member function]': { + 'params': {'object': {'transfer_ownership':'false'}} + }, + 'ns3::EmpiricalVariable::EmpiricalVariable(ns3::RandomVariableBase const & variable) [constructor]': { + 'ignore': None + }, + 'static ns3::AttributeList * ns3::AttributeList::GetGlobal() [member function]': { + 'caller_owns_return': 'false' + }, + 'void ns3::CommandLine::Parse(int argc, char * * argv) const [member function]': { + 'ignore': None # manually wrapped + }, + 'extern void ns3::PythonCompleteConstruct(ns3::Ptr object, ns3::TypeId typeId, ns3::AttributeList const & attributes) [free function]': { + 'ignore': None # used transparently by, should not be wrapped + }, + } + +def get_ns3_relative_path(path): + l = [] + head = path + while head: + head, tail = os.path.split(head) + if tail == 'ns3': + return os.path.join(*l) + l.insert(0, tail) + raise AssertionError("is the path %r inside ns3?!" % path) + + +def pre_scan_hook(dummy_module_parser, + pygccxml_definition, + global_annotations, + parameter_annotations): + ns3_header = get_ns3_relative_path(pygccxml_definition.location.file_name) + + ## Note: we don't include line numbers in the comments because + ## those numbers are very likely to change frequently, which would + ## cause needless changes, since the generated python files are + ## kept under version control. + + #global_annotations['pygen_comment'] = "%s:%i: %s" % \ + # (ns3_header, pygccxml_definition.location.line, pygccxml_definition) + global_annotations['pygen_comment'] = "%s: %s" % \ + (ns3_header, pygccxml_definition) + + + ## handle ns3::Object::GetObject (left to its own devices, + ## pybindgen will generate a mangled name containing the template + ## argument type name). + if isinstance(pygccxml_definition, member_function_t) \ + and pygccxml_definition.parent.name == 'Object' \ + and pygccxml_definition.name == 'GetObject': + template_args = templates.args(pygccxml_definition.demangled_name) + if template_args == ['ns3::Object']: + global_annotations['template_instance_names'] = 'ns3::Object=>GetObject' + + ## Don't wrap Simulator::Schedule* (manually wrapped) + if isinstance(pygccxml_definition, member_function_t) \ + and pygccxml_definition.parent.name == 'Simulator' \ + and pygccxml_definition.name.startswith('Schedule'): + global_annotations['ignore'] = None + + ## classes + if isinstance(pygccxml_definition, class_t): + # no need for helper classes to allow subclassing in Python, I think... + if pygccxml_definition.name.endswith('Helper'): + global_annotations['allow_subclassing'] = 'false' + + if pygccxml_definition.decl_string.startswith('::ns3::Callback<'): + # manually handled in ns3modulegen_core_customizations.py + global_annotations['ignore'] = None + return + + if pygccxml_definition.decl_string.startswith('::ns3::Ptr<'): + # handled by pybindgen "type transformation" + global_annotations['ignore'] = None + return + + # table driven class customization + try: + annotations = type_annotations[pygccxml_definition.decl_string] + except KeyError: + pass + else: + global_annotations.update(annotations) + + ## free functions + if isinstance(pygccxml_definition, free_function_t): + if pygccxml_definition.name == 'PeekPointer': + global_annotations['ignore'] = None + return + + ## table driven methods/constructors/functions customization + if isinstance(pygccxml_definition, (free_function_t, member_function_t, constructor_t)): + try: + annotations = type_annotations[str(pygccxml_definition)] + except KeyError: + pass + else: + for key,value in annotations.items(): + if key == 'params': + parameter_annotations.update (value) + del annotations['params'] + global_annotations.update(annotations) + + +# def post_scan_hook(dummy_module_parser, dummy_pygccxml_definition, pybindgen_wrapper): +# ## classes +# if isinstance(pybindgen_wrapper, CppClass): +# if pybindgen_wrapper.name.endswith('Checker'): +# print >> sys.stderr, "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!", pybindgen_wrapper +# #pybindgen_wrapper.set_instance_creation_function(AttributeChecker_instance_creation_function) + + +def scan_callback_classes(module_parser, callback_classes_file): + callback_classes_file.write("callback_classes = [\n") + for cls in module_parser.module_namespace.classes(function=module_parser.location_filter, + recursive=False): + if not cls.name.startswith("Callback<"): + continue + assert templates.is_instantiation(cls.decl_string), "%s is not a template instantiation" % cls + dummy_cls_name, template_parameters = templates.split(cls.decl_string) + callback_classes_file.write(" %r,\n" % template_parameters) + callback_classes_file.write("]\n") + + +class MyPygenClassifier(PygenClassifier): + def __init__(self, headers_map): + self.headers_map = headers_map + + def classify(self, pygccxml_definition): + name = os.path.basename(pygccxml_definition.location.file_name) + try: + return self.headers_map[name] + except KeyError: + return '__main__' + + +def ns3_module_scan(top_builddir, pygen_file_name): + + ns3_modules = eval(sys.stdin.read()) + + ## do a topological sort on the modules graph + from topsort import topsort + graph = [] + for ns3_module_name, (ns3_module_deps, dummy) in ns3_modules.iteritems(): + for dep in ns3_module_deps: + graph.append((dep, ns3_module_name)) + sorted_ns3_modules = topsort(graph) + print >> sys.stderr, "******* topological sort: ", sorted_ns3_modules + + sections = [PygenSection('__main__', FileCodeSink(open(pygen_file_name, "wt")))] + headers_map = {} # header_name -> section_name + for ns3_module in sorted_ns3_modules: + section_name = "ns3_module_%s" % ns3_module.replace('-', '_') + file_name = os.path.join(os.path.dirname(pygen_file_name), "%s.py" % section_name) + sections.append(PygenSection(section_name, FileCodeSink(open(file_name, "wt")), + section_name + "__local")) + for header in ns3_modules[ns3_module][1]: + headers_map[header] = section_name + + module_parser = ModuleParser('ns3', 'ns3') + + module_parser.add_pre_scan_hook(pre_scan_hook) + #module_parser.add_post_scan_hook(post_scan_hook) + module_parser.parse_init([os.path.join(top_builddir, 'ns3', 'everything.h')], + include_paths=[top_builddir], whitelist_paths=[top_builddir], + #includes=['"ns3/everything.h"'], + pygen_sink=sections, + pygen_classifier=MyPygenClassifier(headers_map)) + module_parser.scan_types() + + callback_classes_file = open(os.path.join(os.path.dirname(pygen_file_name), "callbacks_list.py"), "wt") + scan_callback_classes(module_parser, callback_classes_file) + callback_classes_file.close() + + + module_parser.scan_methods() + module_parser.scan_functions() + module_parser.parse_finalize() + + for section in sections: + section.code_sink.file.close() + + + +if __name__ == '__main__': + ns3_module_scan(sys.argv[1], sys.argv[2]) + diff --git a/bindings/python/rad_util.py b/bindings/python/rad_util.py new file mode 100644 index 000000000..bf6fc5592 --- /dev/null +++ b/bindings/python/rad_util.py @@ -0,0 +1,909 @@ +# Copyright (c) 2007 RADLogic +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. +"""Provide various handy Python functions. + +Running this script directly will execute the doctests. + +Functions: +int2bin(i, n) -- Convert integer to binary string. +bin2int(bin_string) -- Convert binary string to integer. +reverse(input_string) -- Reverse a string. +transpose(matrix) -- Transpose a list of lists. +polygon_area(points_list) -- Calculate the area of an arbitrary polygon. +timestamp() -- Return string containing current time stamp. +pt2str(point) -- Return prettier string version of point tuple. +gcf(a, b) -- Return the greatest common factor of two numbers. +lcm(a, b) -- Return the least common multiple of two numbers. +permutations(input_list) -- Generate all permutations of a list of items. +reduce_fraction(fraction) -- Reduce fraction (num, denom) to simplest form. +quantile(l, p) -- Return p quantile of list l. E.g. p=0.25 for q1. +trim(l) -- Discard values in list more than 1.5*IQR outside IQR. +nice_units(value) -- Return value converted to human readable units. +uniquify(seq) -- Return sequence with duplicate items in sequence seq removed. +reverse_dict(d) -- Return the dictionary with the items as keys and vice-versa. +lsb(x, n) -- Return the n least significant bits of x. +gray_encode(i) -- Gray encode the given integer. +random_vec(bits, max_value=None) -- Return a random binary vector. +binary_range(bits) -- Return list of all possible binary numbers width=bits. +float_range([start], stop, [step]) -- Return range of floats. +find_common_fixes(s1, s2) -- Find common (prefix, suffix) of two strings. +is_rotated(seq1, seq2) -- Return true if the list is a rotation of other list. +getmodule(obj) -- Return the module that contains the object definition of obj. + (use inspect.getmodule instead, though) +get_args(argv) -- Store command-line args in a dictionary. + +This module requires Python >= 2.2 + +""" +__author__ = 'Tim Wegener ' +__date__ = '$Date: 2007/03/27 03:15:06 $' +__version__ = '$Revision: 0.45 $' +__credits__ = """ + David Chandler, for polygon area algorithm. + (http://www.davidchandler.com/AreaOfAGeneralPolygon.pdf) + """ + +import re +import sys +import time +import random + +try: + True, False +except NameError: + True, False = (1==1, 0==1) + + +def int2bin(i, n): + """Convert decimal integer i to n-bit binary number (string). + + >>> int2bin(0, 8) + '00000000' + + >>> int2bin(123, 8) + '01111011' + + >>> int2bin(123L, 8) + '01111011' + + >>> int2bin(15, 2) + Traceback (most recent call last): + ValueError: Value too large for given number of bits. + + """ + hex2bin = {'0': '0000', '1': '0001', '2': '0010', '3': '0011', + '4': '0100', '5': '0101', '6': '0110', '7': '0111', + '8': '1000', '9': '1001', 'a': '1010', 'b': '1011', + 'c': '1100', 'd': '1101', 'e': '1110', 'f': '1111'} + # Convert to hex then map each hex digit to binary equivalent. + result = ''.join([hex2bin[x] for x in hex(i).lower().replace('l','')[2:]]) + + # Shrink result to appropriate length. + # Raise an error if the value is changed by the truncation. + if '1' in result[:-n]: + raise ValueError("Value too large for given number of bits.") + result = result[-n:] + # Zero-pad if length longer than mapped result. + result = '0'*(n-len(result)) + result + return result + + +def bin2int(bin_string): + """Convert binary number string to decimal integer. + + Note: Python > v2 has int(bin_string, 2) + + >>> bin2int('1111') + 15 + + >>> bin2int('0101') + 5 + + """ +## result = 0 +## bin_list = list(bin_string) +## if len(filter(lambda x: x in ('1','0'), bin_list)) < len(bin_list): +## raise Exception ("bin2int: Error - not a binary number: %s" +## % bin_string) +## bit_list = map(int, bin_list) +## bit_list.reverse() # Make most significant bit have highest index. +## for bit_place in range(len(bit_list)): +## result = result + ((2**bit_place) * bit_list[bit_place]) +## return result + return int(bin_string, 2) + + +def reverse(input_string): + """Reverse a string. Useful for strings of binary numbers. + + >>> reverse('abc') + 'cba' + + """ + str_list = list(input_string) + str_list.reverse() + return ''.join(str_list) + + +def transpose(matrix): + """Transpose a list of lists. + + >>> transpose([['a', 'b', 'c'], ['d', 'e', 'f'], ['g', 'h', 'i']]) + [['a', 'd', 'g'], ['b', 'e', 'h'], ['c', 'f', 'i']] + + >>> transpose([['a', 'b', 'c'], ['d', 'e', 'f']]) + [['a', 'd'], ['b', 'e'], ['c', 'f']] + + >>> transpose([['a', 'b'], ['d', 'e'], ['g', 'h']]) + [['a', 'd', 'g'], ['b', 'e', 'h']] + + """ + result = zip(*matrix) + # Convert list of tuples to list of lists. + # map is faster than a list comprehension since it is being used with + # a built-in function as an argument. + result = map(list, result) + return result + + +def polygon_area(points_list, precision=100): + """Calculate area of an arbitrary polygon using an algorithm from the web. + + Return the area of the polygon as a positive float. + + Arguments: + points_list -- list of point tuples [(x0, y0), (x1, y1), (x2, y2), ...] + (Unclosed polygons will be closed automatically. + precision -- Internal arithmetic precision (integer arithmetic). + + >>> polygon_area([(0, 0), (0, 1), (1, 1), (1, 2), (2, 2), (2, 0), (0, 0)]) + 3.0 + + Credits: + Area of a General Polygon by David Chandler + http://www.davidchandler.com/AreaOfAGeneralPolygon.pdf + + """ + # Scale up co-ordinates and convert them to integers. + for i in range(len(points_list)): + points_list[i] = (int(points_list[i][0] * precision), + int(points_list[i][1] * precision)) + # Close polygon if not closed. + if points_list[-1] != points_list[0]: + points_list.append(points_list[0]) + # Calculate area. + area = 0 + for i in range(len(points_list)-1): + (x_i, y_i) = points_list[i] + (x_i_plus_1, y_i_plus_1) = points_list[i+1] + area = area + (x_i_plus_1 * y_i) - (y_i_plus_1 * x_i) + area = abs(area / 2) + # Unscale area. + area = float(area)/(precision**2) + return area + + +def timestamp(): + """Return string containing current time stamp. + + Note: In Python 2 onwards can use time.asctime() with no arguments. + + """ + + return time.asctime() + + +def pt2str(point): + """Return prettier string version of point tuple. + + >>> pt2str((1.8, 1.9)) + '(1.8, 1.9)' + + """ + return "(%s, %s)" % (str(point[0]), str(point[1])) + + +def gcf(a, b, epsilon=1e-16): + """Return the greatest common factor of a and b, using Euclidean algorithm. + + Arguments: + a, b -- two numbers + If both numbers are integers return an integer result, + otherwise return a float result. + epsilon -- floats less than this magnitude are considered to be zero + (default: 1e-16) + + Examples: + + >>> gcf(12, 34) + 2 + + >>> gcf(13.5, 4) + 0.5 + + >>> gcf(-2, 4) + 2 + + >>> gcf(5, 0) + 5 + + By (a convenient) definition: + >>> gcf(0, 0) + 0 + + """ + result = max(a, b) + remainder = min(a, b) + while remainder and abs(remainder) > epsilon: + new_remainder = result % remainder + result = remainder + remainder = new_remainder + return abs(result) + +def lcm(a, b, precision=None): + """Return the least common multiple of a and b, using the gcf function. + + Arguments: + a, b -- two numbers. If both are integers return an integer result, + otherwise a return a float result. + precision -- scaling factor if a and/or b are floats. + + >>> lcm(21, 6) + 42 + + >>> lcm(2.5, 3.5) + 17.5 + + >>> str(lcm(1.5e-8, 2.5e-8, precision=1e9)) + '7.5e-08' + + By (an arbitary) definition: + >>> lcm(0, 0) + 0 + + """ + # Note: Dummy precision argument is for backwards compatibility. + # Do the division first. + # (See http://en.wikipedia.org/wiki/Least_common_multiple ) + denom = gcf(a, b) + if denom == 0: + result = 0 + else: + result = a * (b / denom) + return result + + +def permutations(input_list): + """Return a list containing all permutations of the input list. + + Note: This is a recursive function. + + >>> perms = permutations(['a', 'b', 'c']) + >>> perms.sort() + >>> for perm in perms: + ... print perm + ['a', 'b', 'c'] + ['a', 'c', 'b'] + ['b', 'a', 'c'] + ['b', 'c', 'a'] + ['c', 'a', 'b'] + ['c', 'b', 'a'] + + """ + out_lists = [] + if len(input_list) > 1: + # Extract first item in list. + item = input_list[0] + # Find all permutations of remainder of list. (Recursive call.) + sub_lists = permutations(input_list[1:]) + # For every permutation of the sub list... + for sub_list in sub_lists: + # Insert the extracted first item at every position of the list. + for i in range(len(input_list)): + new_list = sub_list[:] + new_list.insert(i, item) + out_lists.append(new_list) + else: + # Termination condition: only one item in input list. + out_lists = [input_list] + return out_lists + + +def reduce_fraction(fraction): + """Reduce fraction tuple to simplest form. fraction=(num, denom) + + >>> reduce_fraction((14, 7)) + (2, 1) + + >>> reduce_fraction((-2, 4)) + (-1, 2) + + >>> reduce_fraction((0, 4)) + (0, 1) + + >>> reduce_fraction((4, 0)) + (1, 0) + + """ + (numerator, denominator) = fraction + common_factor = abs(gcf(numerator, denominator)) + result = (numerator/common_factor, denominator/common_factor) + return result + + +def quantile(l, p): + """Return p quantile of list l. E.g. p=0.25 for q1. + + See: + http://rweb.stat.umn.edu/R/library/base/html/quantile.html + + """ + l_sort = l[:] + l_sort.sort() + n = len(l) + r = 1 + ((n - 1) * p) + i = int(r) + f = r - i + if i < n: + result = (1-f)*l_sort[i-1] + f*l_sort[i] + else: + result = l_sort[i-1] + return result + + +def trim(l): + """Discard values in list more than 1.5*IQR outside IQR. + + (IQR is inter-quartile-range) + + This function uses rad_util.quantile + + 1.5*IQR -- mild outlier + 3*IQR -- extreme outlier + + See: + http://wind.cc.whecn.edu/~pwildman/statnew/section_7_-_exploratory_data_analysis.htm + + """ + l_sort = l[:] + l_sort.sort() + # Calculate medianscore (based on stats.py lmedianscore by Gary Strangman) + if len(l_sort) % 2 == 0: + # If even number of scores, average middle 2. + index = int(len(l_sort) / 2) # Integer division correct + median = float(l_sort[index] + l_sort[index-1]) / 2 + else: + # int divsion gives mid value when count from 0 + index = int(len(l_sort) / 2) + median = l_sort[index] + # Calculate IQR. + q1 = quantile(l_sort, 0.25) + q3 = quantile(l_sort, 0.75) + iqr = q3 - q1 + iqr_extra = iqr * 1.5 + def in_interval(x, i=iqr_extra, q1=q1, q3=q3): + return (x >= q1-i and x <= q3+i) + l_trimmed = [x for x in l_sort if in_interval(x)] + return l_trimmed + + +def nice_units(value, dp=0, sigfigs=None, suffix='', space=' ', + use_extra_prefixes=False, use_full_name=False, mode='si'): + """Return value converted to human readable units eg milli, micro, etc. + + Arguments: + value -- number in base units + dp -- number of decimal places to display (rounded) + sigfigs -- number of significant figures to display (rounded) + This overrides dp if set. + suffix -- optional unit suffix to append to unit multiplier + space -- seperator between value and unit multiplier (default: ' ') + use_extra_prefixes -- use hecto, deka, deci and centi as well if set. + (default: False) + use_full_name -- use full name for multiplier symbol, + e.g. milli instead of m + (default: False) + mode -- 'si' for SI prefixes, 'bin' for binary multipliers (1024, etc.) + (Default: 'si') + + SI prefixes from: + http://physics.nist.gov/cuu/Units/prefixes.html + (Greek mu changed to u.) + Binary prefixes based on: + http://physics.nist.gov/cuu/Units/binary.html + + >>> nice_units(2e-11) + '20 p' + + >>> nice_units(2e-11, space='') + '20p' + + """ + si_prefixes = {1e24: ('Y', 'yotta'), + 1e21: ('Z', 'zetta'), + 1e18: ('E', 'exa'), + 1e15: ('P', 'peta'), + 1e12: ('T', 'tera'), + 1e9: ('G', 'giga'), + 1e6: ('M', 'mega'), + 1e3: ('k', 'kilo'), + 1e-3: ('m', 'milli'), + 1e-6: ('u', 'micro'), + 1e-9: ('n', 'nano'), + 1e-12: ('p', 'pico'), + 1e-15: ('f', 'femto'), + 1e-18: ('a', 'atto'), + 1e-21: ('z', 'zepto'), + 1e-24: ('y', 'yocto') + } + if use_extra_prefixes: + si_prefixes.update({1e2: ('h', 'hecto'), + 1e1: ('da', 'deka'), + 1e-1: ('d', 'deci'), + 1e-2: ('c', 'centi') + }) + bin_prefixes = {2**10: ('K', 'kilo'), + 2**20: ('M', 'mega'), + 2**30: ('G', 'mega'), + 2**40: ('T', 'tera'), + 2**50: ('P', 'peta'), + 2**60: ('E', 'exa') + } + if mode == 'bin': + prefixes = bin_prefixes + else: + prefixes = si_prefixes + prefixes[1] = ('', '') # Unity. + # Determine appropriate multiplier. + multipliers = prefixes.keys() + multipliers.sort() + mult = None + for i in range(len(multipliers) - 1): + lower_mult = multipliers[i] + upper_mult = multipliers[i+1] + if lower_mult <= value < upper_mult: + mult_i = i + break + if mult is None: + if value < multipliers[0]: + mult_i = 0 + elif value >= multipliers[-1]: + mult_i = len(multipliers) - 1 + mult = multipliers[mult_i] + # Convert value for this multiplier. + new_value = value / mult + # Deal with special case due to rounding. + if sigfigs is None: + if mult_i < (len(multipliers) - 1) and \ + round(new_value, dp) == \ + round((multipliers[mult_i+1] / mult), dp): + mult = multipliers[mult_i + 1] + new_value = value / mult + # Concatenate multiplier symbol. + if use_full_name: + label_type = 1 + else: + label_type = 0 + # Round and truncate to appropriate precision. + if sigfigs is None: + str_value = eval('"%.'+str(dp)+'f" % new_value', locals(), {}) + else: + str_value = eval('"%.'+str(sigfigs)+'g" % new_value', locals(), {}) + return str_value + space + prefixes[mult][label_type] + suffix + + +def uniquify(seq, preserve_order=False): + """Return sequence with duplicate items in sequence seq removed. + + The code is based on usenet post by Tim Peters. + + This code is O(N) if the sequence items are hashable, O(N**2) if not. + + Peter Bengtsson has a blog post with an empirical comparison of other + approaches: + http://www.peterbe.com/plog/uniqifiers-benchmark + + If order is not important and the sequence items are hashable then + list(set(seq)) is readable and efficient. + + If order is important and the sequence items are hashable generator + expressions can be used (in py >= 2.4) (useful for large sequences): + seen = set() + do_something(x for x in seq if x not in seen or seen.add(x)) + + Arguments: + seq -- sequence + preserve_order -- if not set the order will be arbitrary + Using this option will incur a speed penalty. + (default: False) + + Example showing order preservation: + + >>> uniquify(['a', 'aa', 'b', 'b', 'ccc', 'ccc', 'd'], preserve_order=True) + ['a', 'aa', 'b', 'ccc', 'd'] + + Example using a sequence of un-hashable items: + + >>> uniquify([['z'], ['x'], ['y'], ['z']], preserve_order=True) + [['z'], ['x'], ['y']] + + The sorted output or the non-order-preserving approach should equal + that of the sorted order-preserving approach output: + + >>> unordered = uniquify([3, 3, 1, 2], preserve_order=False) + >>> unordered.sort() + >>> ordered = uniquify([3, 3, 1, 2], preserve_order=True) + >>> ordered.sort() + >>> ordered + [1, 2, 3] + >>> int(ordered == unordered) + 1 + + """ + try: + # Attempt fast algorithm. + d = {} + if preserve_order: + # This is based on Dave Kirby's method (f8) noted in the post: + # http://www.peterbe.com/plog/uniqifiers-benchmark + return [x for x in seq if (x not in d) and not d.__setitem__(x, 0)] + else: + for x in seq: + d[x] = 0 + return d.keys() + except TypeError: + # Have an unhashable object, so use slow algorithm. + result = [] + app = result.append + for x in seq: + if x not in result: + app(x) + return result + +# Alias to noun form for backward compatibility. +unique = uniquify + + +def reverse_dict(d): + """Reverse a dictionary so the items become the keys and vice-versa. + + Note: The results will be arbitrary if the items are not unique. + + >>> d = reverse_dict({'a': 1, 'b': 2}) + >>> d_items = d.items() + >>> d_items.sort() + >>> d_items + [(1, 'a'), (2, 'b')] + + """ + result = {} + for key, value in d.items(): + result[value] = key + return result + + +def lsb(x, n): + """Return the n least significant bits of x. + + >>> lsb(13, 3) + 5 + + """ + return x & ((2 ** n) - 1) + + +def gray_encode(i): + """Gray encode the given integer.""" + + return i ^ (i >> 1) + + +def random_vec(bits, max_value=None): + """Generate a random binary vector of length bits and given max value.""" + + vector = "" + for _ in range(int(bits / 10) + 1): + i = int((2**10) * random.random()) + vector += int2bin(i, 10) + + if max_value and (max_value < 2 ** bits - 1): + vector = int2bin((int(vector, 2) / (2 ** bits - 1)) * max_value, bits) + + return vector[0:bits] + + +def binary_range(bits): + """Return a list of all possible binary numbers in order with width=bits. + + It would be nice to extend it to match the + functionality of python's range() built-in function. + + """ + l = [] + v = ['0'] * bits + + toggle = [1] + [0] * bits + + while toggle[bits] != 1: + v_copy = v[:] + v_copy.reverse() + l.append(''.join(v_copy)) + + toggle = [1] + [0]*bits + i = 0 + while i < bits and toggle[i] == 1: + if toggle[i]: + if v[i] == '0': + v[i] = '1' + toggle[i+1] = 0 + else: + v[i] = '0' + toggle[i+1] = 1 + i += 1 + return l + + +def float_range(start, stop=None, step=None): + """Return a list containing an arithmetic progression of floats. + + Return a list of floats between 0.0 (or start) and stop with an + increment of step. + + This is in functionality to python's range() built-in function + but can accept float increments. + + As with range(), stop is omitted from the list. + + """ + if stop is None: + stop = float(start) + start = 0.0 + + if step is None: + step = 1.0 + + cur = float(start) + l = [] + while cur < stop: + l.append(cur) + cur += step + + return l + + +def find_common_fixes(s1, s2): + """Find common (prefix, suffix) of two strings. + + >>> find_common_fixes('abc', 'def') + ('', '') + + >>> find_common_fixes('abcelephantdef', 'abccowdef') + ('abc', 'def') + + >>> find_common_fixes('abcelephantdef', 'abccow') + ('abc', '') + + >>> find_common_fixes('elephantdef', 'abccowdef') + ('', 'def') + + """ + prefix = [] + suffix = [] + + i = 0 + common_len = min(len(s1), len(s2)) + while i < common_len: + if s1[i] != s2[i]: + break + + prefix.append(s1[i]) + i += 1 + + i = 1 + while i < (common_len + 1): + if s1[-i] != s2[-i]: + break + + suffix.append(s1[-i]) + i += 1 + + suffix.reverse() + + prefix = ''.join(prefix) + suffix = ''.join(suffix) + + return (prefix, suffix) + + +def is_rotated(seq1, seq2): + """Return true if the first sequence is a rotation of the second sequence. + + >>> seq1 = ['A', 'B', 'C', 'D'] + >>> seq2 = ['C', 'D', 'A', 'B'] + >>> int(is_rotated(seq1, seq2)) + 1 + + >>> seq2 = ['C', 'D', 'B', 'A'] + >>> int(is_rotated(seq1, seq2)) + 0 + + >>> seq1 = ['A', 'B', 'C', 'A'] + >>> seq2 = ['A', 'A', 'B', 'C'] + >>> int(is_rotated(seq1, seq2)) + 1 + + >>> seq2 = ['A', 'B', 'C', 'A'] + >>> int(is_rotated(seq1, seq2)) + 1 + + >>> seq2 = ['A', 'A', 'C', 'B'] + >>> int(is_rotated(seq1, seq2)) + 0 + + """ + # Do a sanity check. + if len(seq1) != len(seq2): + return False + # Look for occurrences of second sequence head item in first sequence. + start_indexes = [] + head_item = seq2[0] + for index1 in range(len(seq1)): + if seq1[index1] == head_item: + start_indexes.append(index1) + # Check that wrapped sequence matches. + double_seq1 = seq1 + seq1 + for index1 in start_indexes: + if double_seq1[index1:index1+len(seq1)] == seq2: + return True + return False + +def getmodule(obj): + """Return the module that contains the object definition of obj. + + Note: Use inspect.getmodule instead. + + Arguments: + obj -- python obj, generally a class or a function + + Examples: + + A function: + >>> module = getmodule(random.choice) + >>> module.__name__ + 'random' + >>> module is random + 1 + + A class: + >>> module = getmodule(random.Random) + >>> module.__name__ + 'random' + >>> module is random + 1 + + A class inheriting from a class in another module: + (note: The inheriting class must define at least one function.) + >>> class MyRandom(random.Random): + ... def play(self): + ... pass + >>> module = getmodule(MyRandom) + >>> if __name__ == '__main__': + ... name = 'rad_util' + ... else: + ... name = module.__name__ + >>> name + 'rad_util' + >>> module is sys.modules[__name__] + 1 + + Discussion: + This approach is slightly hackish, and won't work in various situations. + However, this was the approach recommended by GvR, so it's as good as + you'll get. + + See GvR's post in this thread: + http://groups.google.com.au/group/comp.lang.python/browse_thread/thread/966a7bdee07e3b34/c3cab3f41ea84236?lnk=st&q=python+determine+class+module&rnum=4&hl=en#c3cab3f41ea84236 + + """ + if hasattr(obj, 'func_globals'): + func = obj + else: + # Handle classes. + func = None + for item in obj.__dict__.values(): + if hasattr(item, 'func_globals'): + func = item + break + if func is None: + raise ValueError("No functions attached to object: %r" % obj) + module_name = func.func_globals['__name__'] + # Get module. + module = sys.modules[module_name] + return module + + +def round_grid(value, grid, mode=0): + """Round off the given value to the given grid size. + + Arguments: + value -- value to be roudne + grid -- result must be a multiple of this + mode -- 0 nearest, 1 up, -1 down + + Examples: + + >>> round_grid(7.5, 5) + 10 + + >>> round_grid(7.5, 5, mode=-1) + 5 + + >>> round_grid(7.3, 5, mode=1) + 10 + + >>> round_grid(7.3, 5.0, mode=1) + 10.0 + + """ + off_grid = value % grid + if mode == 0: + add_one = int(off_grid >= (grid / 2.0)) + elif mode == 1 and off_grid: + add_one = 1 + elif mode == -1 and off_grid: + add_one = 0 + result = ((int(value / grid) + add_one) * grid) + return result + + +def get_args(argv): + """Store command-line args in a dictionary. + + -, -- prefixes are removed + Items not prefixed with - or -- are stored as a list, indexed by 'args' + + For options that take a value use --option=value + + Consider using optparse or getopt (in Python standard library) instead. + + """ + d = {} + args = [] + + for arg in argv: + + if arg.startswith('-'): + parts = re.sub(r'^-+', '', arg).split('=') + if len(parts) == 2: + d[parts[0]] = parts[1] + else: + d[parts[0]] = None + else: + args.append(arg) + + d['args'] = args + + return d + + +if __name__ == '__main__': + import doctest + doctest.testmod(sys.modules['__main__']) + diff --git a/bindings/python/topsort.py b/bindings/python/topsort.py new file mode 100644 index 000000000..fc7d2663c --- /dev/null +++ b/bindings/python/topsort.py @@ -0,0 +1,392 @@ +# topsort - dependency (topological) sorting and cycle finding functions +# Copyright (C) 2007 RADLogic +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; +# version 2.1 of the License. +# +# This library 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 +# Lesser General Public License for more details. +# +# See http://www.fsf.org/licensing/licenses/lgpl.txt for full license text. +"""Provide toplogical sorting (i.e. dependency sorting) functions. + +The topsort function is based on code posted on Usenet by Tim Peters. + +Modifications: +- added doctests +- changed some bits to use current Python idioms + (listcomp instead of filter, +=/-=, inherit from Exception) +- added a topsort_levels version that ports items in each dependency level + into a sub-list +- added find_cycles to aid in cycle debugging + +Run this module directly to run the doctests (unittests). +Make sure they all pass before checking in any modifications. + +Requires Python >= 2.2 +(For Python 2.2 also requires separate sets.py module) + +This requires the rad_util.py module. + +""" + +# Provide support for Python 2.2* +from __future__ import generators + +__version__ = '$Revision: 0.9 $' +__date__ = '$Date: 2007/03/27 04:15:26 $' +__credits__ = '''Tim Peters -- original topsort code +Tim Wegener -- doctesting, updating to current idioms, topsort_levels, + find_cycles +''' + +# Make Python 2.3 sets look like Python 2.4 sets. +try: + set +except NameError: + from sets import Set as set + +from rad_util import is_rotated + + +class CycleError(Exception): + """Cycle Error""" + pass + + +def topsort(pairlist): + """Topologically sort a list of (parent, child) pairs. + + Return a list of the elements in dependency order (parent to child order). + + >>> print topsort( [(1,2), (3,4), (5,6), (1,3), (1,5), (1,6), (2,5)] ) + [1, 2, 3, 5, 4, 6] + + >>> print topsort( [(1,2), (1,3), (2,4), (3,4), (5,6), (4,5)] ) + [1, 2, 3, 4, 5, 6] + + >>> print topsort( [(1,2), (2,3), (3,2)] ) + Traceback (most recent call last): + CycleError: ([1], {2: 1, 3: 1}, {2: [3], 3: [2]}) + + """ + num_parents = {} # element -> # of predecessors + children = {} # element -> list of successors + for parent, child in pairlist: + # Make sure every element is a key in num_parents. + if not num_parents.has_key( parent ): + num_parents[parent] = 0 + if not num_parents.has_key( child ): + num_parents[child] = 0 + + # Since child has a parent, increment child's num_parents count. + num_parents[child] += 1 + + # ... and parent gains a child. + children.setdefault(parent, []).append(child) + + # Suck up everything without a parent. + answer = [x for x in num_parents.keys() if num_parents[x] == 0] + + # For everything in answer, knock down the parent count on its children. + # Note that answer grows *in* the loop. + for parent in answer: + del num_parents[parent] + if children.has_key( parent ): + for child in children[parent]: + num_parents[child] -= 1 + if num_parents[child] == 0: + answer.append( child ) + # Following "del" isn't needed; just makes + # CycleError details easier to grasp. + del children[parent] + + if num_parents: + # Everything in num_parents has at least one child -> + # there's a cycle. + raise CycleError(answer, num_parents, children) + return answer + +def topsort_levels(pairlist): + """Topologically sort a list of (parent, child) pairs into depth levels. + + This returns a generator. + Turn this into a an iterator using the iter built-in function. + (if you iterate over the iterator, each element gets generated when + it is asked for, rather than generating the whole list up-front.) + + Each generated element is a list of items at that dependency level. + + >>> dependency_pairs = [(1,2), (3,4), (5,6), (1,3), (1,5), (1,6), (2,5)] + >>> for level in iter(topsort_levels( dependency_pairs )): + ... print level + [1] + [2, 3] + [4, 5] + [6] + + >>> dependency_pairs = [(1,2), (1,3), (2,4), (3,4), (5,6), (4,5)] + >>> for level in iter(topsort_levels( dependency_pairs )): + ... print level + [1] + [2, 3] + [4] + [5] + [6] + + >>> dependency_pairs = [(1,2), (2,3), (3,4), (4, 3)] + >>> try: + ... for level in iter(topsort_levels( dependency_pairs )): + ... print level + ... except CycleError, exc: + ... print 'CycleError:', exc + [1] + [2] + CycleError: ({3: 1, 4: 1}, {3: [4], 4: [3]}) + + + The cycle error should look like. + CycleError: ({3: 1, 4: 1}, {3: [4], 4: [3]}) + # todo: Make the doctest more robust (i.e. handle arbitrary dict order). + + """ + num_parents = {} # element -> # of predecessors + children = {} # element -> list of successors + for parent, child in pairlist: + # Make sure every element is a key in num_parents. + if not num_parents.has_key( parent ): + num_parents[parent] = 0 + if not num_parents.has_key( child ): + num_parents[child] = 0 + + # Since child has a parent, increment child's num_parents count. + num_parents[child] += 1 + + # ... and parent gains a child. + children.setdefault(parent, []).append(child) + + return topsort_levels_core(num_parents, children) + +def topsort_levels_core(num_parents, children): + """Topologically sort a bunch of interdependent items based on dependency. + + This returns a generator. + Turn this into a an iterator using the iter built-in function. + (if you iterate over the iterator, each element gets generated when + it is asked for, rather than generating the whole list up-front.) + + Each generated element is a list of items at that dependency level. + + >>> list(topsort_levels_core( + ... {1: 0, 2: 1, 3: 1, 4: 1, 5: 2, 6: 2}, + ... {1: [2, 3, 5, 6], 2: [5], 3: [4], 4: [], 5: [6]})) + [[1], [2, 3], [4, 5], [6]] + + >>> list(topsort_levels_core( + ... {1: 0, 2: 2, 3: 1}, + ... {1: [2], 2: [3], 3: [2]})) + Traceback (most recent call last): + CycleError: ({2: 1, 3: 1}, {2: [3], 3: [2]}) + + This function has a more complicated interface than topsort_levels, + but is useful if the data is easier to generate in this form. + + Arguments: + num_parents -- key: item, value: number of parents (predecessors) + children -- key: item, value: list of children (successors) + + """ + while 1: + # Suck up everything without a predecessor. + level_parents = [x for x in num_parents.keys() if num_parents[x] == 0] + + if not level_parents: + break + + # Offer the next generated item, + # which is a list of the items at this dependency level. + yield level_parents + + # For everything item in this level, + # decrement the parent count, + # since we have accounted for its parent. + for level_parent in level_parents: + + del num_parents[level_parent] + + if children.has_key(level_parent): + for level_parent_child in children[level_parent]: + num_parents[level_parent_child] -= 1 + del children[level_parent] + + if num_parents: + # Everything in num_parents has at least one child -> + # there's a cycle. + raise CycleError(num_parents, children) + else: + # This is the end of the generator. + raise StopIteration + + +def find_cycles(parent_children): + """Yield cycles. Each result is a list of items comprising a cycle. + + Use a 'stack' based approach to find all the cycles. + This is a generator, so yields each cycle as it finds it. + + It is implicit that the last item in each cycle list is a parent of the + first item (thereby forming a cycle). + + Arguments: + parent_children -- parent -> collection of children + + Simplest cycle: + >>> cycles = list(find_cycles({'A': ['B'], 'B': ['A']})) + >>> len(cycles) + 1 + >>> cycle = cycles[0] + >>> cycle.sort() + >>> print cycle + ['A', 'B'] + + Simplest cycle with extra baggage at the start and the end: + >>> cycles = list(find_cycles(parent_children={'A': ['B'], + ... 'B': ['C'], + ... 'C': ['B', 'D'], + ... 'D': [], + ... })) + >>> len(cycles) + 1 + >>> cycle = cycles[0] + >>> cycle.sort() + >>> print cycle + ['B', 'C'] + + Double cycle: + >>> cycles = list(find_cycles(parent_children={'A': ['B'], + ... 'B': ['C1', 'C2'], + ... 'C1': ['D1'], + ... 'D1': ['E1'], + ... 'E1': ['D1'], + ... 'C2': ['D2'], + ... 'D2': ['E2'], + ... 'E2': ['D2'], + ... })) + >>> len(cycles) + 2 + >>> for cycle in cycles: + ... cycle.sort() + >>> cycles.sort() + >>> cycle1 = cycles[0] + >>> cycle1.sort() + >>> print cycle1 + ['D1', 'E1'] + >>> cycle2 = cycles[1] + >>> cycle2.sort() + >>> print cycle2 + ['D2', 'E2'] + + Simple cycle with children not specified for one item: + # todo: Should this barf instead? + >>> cycles = list(find_cycles(parent_children={'A': ['B'], + ... 'B': ['A'], + ... 'C': ['D']})) + >>> len(cycles) + 1 + >>> cycle = cycles[0] + >>> cycle.sort() + >>> print cycle + ['A', 'B'] + + Diamond cycle + >>> cycles = list(find_cycles(parent_children={'A': ['B1', 'B2'], + ... 'B1': ['C'], + ... 'B2': ['C'], + ... 'C': ['A', 'B1']})) + >>> len(cycles) + 3 + >>> sorted_cycles = [] + >>> for cycle in cycles: + ... cycle = list(cycle) + ... cycle.sort() + ... sorted_cycles.append(cycle) + >>> sorted_cycles.sort() + >>> for cycle in sorted_cycles: + ... print cycle + ['A', 'B1', 'C'] + ['A', 'B2', 'C'] + ['B1', 'C'] + + Hairy case (order can matter if something is wrong): + (Note order of B and C in the list.) + >>> cycles = list(find_cycles(parent_children={ + ... 'TD': ['DD'], + ... 'TC': ['DC'], + ... 'DC': ['DQ'], + ... 'C': ['DQ'], + ... 'DQ': ['IA', 'TO'], + ... 'IA': ['A'], + ... 'A': ['B', 'C'], + ... })) + >>> len(cycles) + 1 + >>> cycle = cycles[0] + >>> cycle.sort() + >>> print cycle + ['A', 'C', 'DQ', 'IA'] + + """ + cycles = [] + visited_nodes = set() + + for parent in parent_children: + if parent in visited_nodes: + # This node is part of a path that has already been traversed. + continue + + paths = [[parent]] + while paths: + path = paths.pop() + + parent = path[-1] + + try: + children = parent_children[parent] + except KeyError: + continue + + for child in children: + # Keeping a set of the path nodes, for O(1) lookups at the + # expense of more memory and complexity, actually makes speed + # worse. (Due to construction of sets.) + # This is O(N). + if child in path: + # This is a cycle. + cycle = path[path.index(child):] + # Check that this is not a dup cycle. + is_dup = False + for other_cycle in cycles: + if is_rotated(other_cycle, cycle): + is_dup = True + break + if not is_dup: + cycles.append(cycle) + yield cycle + else: + # Push this new path onto the 'stack'. + # This is probably the most expensive part of the algorithm + # (a list copy). + paths.append(path + [child]) + # Mark the node as visited. + visited_nodes.add(child) + + +if __name__ == '__main__': + # Run the doctest tests. + import sys + import doctest + doctest.testmod(sys.modules['__main__']) diff --git a/bindings/python/waf b/bindings/python/waf new file mode 100644 index 000000000..3dcf598bc --- /dev/null +++ b/bindings/python/waf @@ -0,0 +1 @@ +exec "`dirname "$0"`"/../../waf "$@" \ No newline at end of file diff --git a/bindings/python/wscript b/bindings/python/wscript new file mode 100644 index 000000000..bc513e183 --- /dev/null +++ b/bindings/python/wscript @@ -0,0 +1,367 @@ +## -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*- + +import re +import Params +import Configure +import Object +import Action +import os +import Task +import pproc as subprocess +from Params import fatal, warning +import shutil + +## Adjust python path to look for our local copy of pybindgen +LOCAL_PYBINDGEN_PATH = os.path.join(os.getcwd(), "bindings", "python", "pybindgen") +#PYBINDGEN_BRANCH = 'lp:pybindgen' +PYBINDGEN_BRANCH = 'https://launchpad.net/pybindgen' +if os.environ.get('PYTHONPATH', ''): + os.environ['PYTHONPATH'] = LOCAL_PYBINDGEN_PATH + os.pathsep + os.environ.get('PYTHONPATH') +else: + os.environ['PYTHONPATH'] = LOCAL_PYBINDGEN_PATH + +## https://launchpad.net/pybindgen/ +REQUIRED_PYBINDGEN_VERSION = (0, 8, 0, 475) +REQUIRED_PYGCCXML_VERSION = (0, 9, 5) + + +def set_options(opt): + opt.tool_options('python') + opt.add_option('--python-disable', + help=("Don't build Python bindings."), + action="store_true", default=False, + dest='python_disable') + opt.add_option('--python-scan', + help=("Rescan Python bindings. Needs working GCCXML / pygccxml environment."), + action="store_true", default=False, + dest='python_scan') + opt.add_option('--pybindgen-checkout', + help=("During configure, force checkout of pybingen inside ns-3, " + "instead of using the system installed version."), + action="store_true", default=False, + dest='pybindgen_checkout') + +def fetch_pybindgen(conf): + """ + Fetches pybindgen from launchpad as bindings/python/pybindgen. + Returns True if successful, False it not. + """ + bzr = conf.find_program("bzr") + if not bzr: + warning("the program 'bzr' is needed in order to fetch pybindgen") + return False + if len(REQUIRED_PYBINDGEN_VERSION) == 4: + rev = "-rrevno:%i" % REQUIRED_PYBINDGEN_VERSION[3] + else: + rev = "-rtag:%s" % '.'.join([str(x) for x in REQUIRED_PYBINDGEN_VERSION]) + if os.path.exists(LOCAL_PYBINDGEN_PATH): + print "Trying to update pybindgen; this will fail if no network connection is available." + + cmd = [bzr, "pull", rev, PYBINDGEN_BRANCH] + print " => ", ' '.join(cmd) + if subprocess.Popen(cmd, cwd=LOCAL_PYBINDGEN_PATH).wait(): + return False + print "Update was successful." + else: + print "Trying to fetch pybindgen; this will fail if no network connection is available." + cmd = [bzr, "checkout", rev, PYBINDGEN_BRANCH, LOCAL_PYBINDGEN_PATH] + print " => ", ' '.join(cmd) + if subprocess.Popen(cmd).wait(): + return False + print "Fetch was successful." + + ## generate a fake version.py file in pybindgen it's safer this + ## way, since the normal version generation process requires + ## bazaar python bindings, which may not be available. + vfile = open(os.path.join(LOCAL_PYBINDGEN_PATH, "pybindgen", "version.py"), "wt") + vfile.write(""" +# (fake version generated by ns-3) +__version__ = %r +""" % list(REQUIRED_PYBINDGEN_VERSION)) + vfile.close() + + return True + + +def configure(conf): + conf.env['ENABLE_PYTHON_BINDINGS'] = False + if Params.g_options.python_disable: + return + + conf.check_tool('misc') + + ## Check for Python + try: + conf.check_tool('python') + conf.check_python_version((2,4,2)) + conf.check_python_headers() + except Configure.ConfigurationError: + return + + ## Check for pybindgen + if Params.g_options.pybindgen_checkout: + fetch_pybindgen(conf) + + try: + conf.check_python_module('pybindgen') + except Configure.ConfigurationError: + warning("pybindgen missing") + if not fetch_pybindgen(conf): + return + else: + out = subprocess.Popen([conf.env['PYTHON'], "-c", + "import pybindgen.version; " + "print '.'.join([str(x) for x in pybindgen.version.__version__])"], + stdout=subprocess.PIPE).communicate()[0] + pybindgen_version_str = out.strip() + pybindgen_version = tuple([int(x) for x in pybindgen_version_str.split('.')]) + conf.check_message('pybindgen', 'version', + (pybindgen_version >= REQUIRED_PYBINDGEN_VERSION), + pybindgen_version_str) + if not (pybindgen_version >= REQUIRED_PYBINDGEN_VERSION): + warning("pybindgen (found %s) is too old (need %s)" % + (pybindgen_version_str, + '.'.join([str(x) for x in REQUIRED_PYBINDGEN_VERSION]))) + if not fetch_pybindgen(conf): + return + + ## If all has gone well, we finally enable the Python bindings + conf.env['ENABLE_PYTHON_BINDINGS'] = True + + ## Check for pygccxml + try: + conf.check_python_module('pygccxml') + except Configure.ConfigurationError: + return + + out = subprocess.Popen([conf.env['PYTHON'], "-c", + "import pygccxml; print pygccxml.__version__"], + stdout=subprocess.PIPE).communicate()[0] + pygccxml_version_str = out.strip() + pygccxml_version = tuple([int(x) for x in pygccxml_version_str.split('.')]) + conf.check_message('pygccxml', 'version', + (pygccxml_version >= REQUIRED_PYGCCXML_VERSION), + pygccxml_version_str) + if not (pygccxml_version >= REQUIRED_PYGCCXML_VERSION): + warning("pygccxml (found %s) is too old (need %s) => " + "automatic scanning of API definitions will not be possible" % + (pygccxml_version_str, + '.'.join([str(x) for x in REQUIRED_PYGCCXML_VERSION]))) + return + + + ## Check gccxml version + gccxml = conf.find_program('gccxml', var='GCCXML') + if not gccxml: + warning("gccxml missing; automatic scanning of API definitions will not be possible") + return + + gccxml_version_line = os.popen(gccxml + " --version").readline().strip() + m = re.match( "^GCC-XML version (\d\.\d(\.\d)?)$", gccxml_version_line) + gccxml_version = m.group(1) + gccxml_version_ok = ([int(s) for s in gccxml_version.split('.')] >= [0, 9]) + conf.check_message('gccxml', 'version', True, gccxml_version) + if not gccxml_version_ok: + warning("gccxml too old, need version >= 0.9; automatic scanning of API definitions will not be possible") + return + + ## If we reached + conf.env['ENABLE_PYTHON_SCANNING'] = True + + +prio_headers = { + -2: ( + "string.h", # work around http://www.gccxml.org/Bug/view.php?id=6682 + ), + -1: ( + "propagation-delay-model.h", + "propagation-loss-model.h", + "net-device.h", + ) + } + +def get_header_prio(header): + for prio, headers in prio_headers.iteritems(): + if header in headers: + return prio + return 1 + +def gen_ns3_metaheader(task): + assert len(task.m_outputs) == 1 + header_files = [os.path.basename(node.abspath(task.m_env)) for node in task.m_inputs] + outfile = file(task.m_outputs[0].bldpath(task.m_env), "w") + + def sort_func(h1, h2): + return cmp((get_header_prio(h1), h1), (get_header_prio(h1), h2)) + + header_files.sort(sort_func) + + for header in header_files: + print >> outfile, "#include \"ns3/%s\"" % (header,) + + print >> outfile, """ +namespace ns3 { +static inline Ptr +__dummy_function_to_force_template_instantiation (Ptr obj, TypeId typeId) +{ + return obj->GetObject (typeId); +} + +} +""" + outfile.close() + return 0 + + +class all_ns3_headers_taskgen(Object.task_gen): + """Generates a 'everything.h' header file that includes some/all public ns3 headers. + This single header file is to be parsed only once by gccxml, for greater efficiency. + """ + def __init__(self, *features): + Object.task_gen.__init__(self, *features) + self.inst_var = 'INCLUDEDIR' + self.inst_dir = 'ns3' + + def apply(self): + ## get all of the ns3 headers + ns3_dir_node = Params.g_build.m_srcnode.find_dir("ns3") + all_headers_inputs = [] + + for filename in self.to_list(self.source): + src_node = ns3_dir_node.find_build(filename) + if src_node is None: + Params.fatal("source ns3 header file %s not found" % (filename,)) + all_headers_inputs.append(src_node) + + ## if self.source was empty, include all ns3 headers in enabled modules + if not all_headers_inputs: + for ns3headers in Object.g_allobjs: + if type(ns3headers).__name__ == 'ns3header_taskgen': # XXX: find less hackish way to compare + ## skip headers not part of enabled modules + if self.env['NS3_ENABLED_MODULES']: + if ("ns3-%s" % ns3headers.module) not in self.env['NS3_ENABLED_MODULES']: + continue + + for source in ns3headers.to_list(ns3headers.source): + source = os.path.basename(source) + node = ns3_dir_node.find_build(os.path.basename(source)) + if node is None: + fatal("missing header file %s" % (source,)) + all_headers_inputs.append(node) + assert all_headers_inputs + all_headers_outputs = [ns3_dir_node.find_build("everything.h")] + task = self.create_task('gen-ns3-metaheader', self.env, 4) + task.set_inputs(all_headers_inputs) + task.set_outputs(all_headers_outputs) + + def install(self): + pass + + +def get_modules_and_headers(): + """ + Gets a dict of + module_name => ([module_dep1, module_dep2, ...], [module_header1, module_header2, ...]) + tuples, one for each module. + """ + + retval = {} + for module in Object.g_allobjs: + if not module.name.startswith('ns3-'): + continue + module_name = module.name[4:] # strip the ns3- prefix + ## find the headers object for this module + headers = [] + for ns3headers in Object.g_allobjs: + if type(ns3headers).__name__ != 'ns3header_taskgen': # XXX: find less hackish way to compare + continue + if ns3headers.module != module_name: + continue + for source in ns3headers.to_list(ns3headers.source): + headers.append(source) + retval[module_name] = (list(module.module_deps), headers) + return retval + + +def build(bld): + if Params.g_options.python_disable: + return + + env = bld.env_of_name('default') + #Object.register('all-ns3-headers', AllNs3Headers) + Action.Action('gen-ns3-metaheader', func=gen_ns3_metaheader, color='BLUE') + + obj = bld.create_obj('all_ns3_headers') + + if Params.g_options.python_scan: + if not env['ENABLE_PYTHON_SCANNING']: + Params.fatal("Cannot re-scan python bindings: (py)gccxml not available") + print "Rescanning the python bindings..." + curdir = bld.m_curdirnode.abspath() + argv = [ + env['PYTHON'], + os.path.join(curdir, 'ns3modulescan.py'), # scanning script + bld.m_curdirnode.find_dir('../..').abspath(env), # include path (where the ns3 include dir is) + os.path.join(curdir, 'ns3modulegen_generated.py'), # output file + ] + scan = subprocess.Popen(argv, stdin=subprocess.PIPE) + scan.stdin.write(repr(get_modules_and_headers())) + scan.stdin.close() + if scan.wait(): + raise SystemExit(1) + print "Rescanning the python bindings done." + raise SystemExit + + if env['ENABLE_PYTHON_BINDINGS']: + bindgen = bld.create_obj('command-output') + bindgen.name = 'pybindgen' + + bindgen.command = env['PYTHON'] + bindgen.command_is_external = True + bindgen.argv = [ + bindgen.input_file("ns3modulegen.py"), + bindgen.output_file("ns3module.cc"), + ] + bindgen.argv.extend(get_modules_and_headers().iterkeys()) + bindgen.hidden_inputs = ['../../ns3/everything.h', + 'ns3modulegen_generated.py', + 'ns3modulegen_core_customizations.py'] + for module in get_modules_and_headers().iterkeys(): + bindgen.hidden_inputs.append("ns3_module_%s.py" % module.replace('-', '_')) + bindgen.hidden_outputs = ['ns3module.h'] + for module in get_modules_and_headers().iterkeys(): + bindgen.hidden_outputs.append("ns3_module_%s.cc" % module.replace('-', '_')) + bindgen.prio = 50 + + + ## we build python bindings if either we have the tools to + ## generate them or if the pregenerated source file is already + ## present in the source dir. + if env['ENABLE_PYTHON_BINDINGS'] \ + or os.path.exists(os.path.join(bld.m_curdirnode.abspath(), 'ns3module.cc')): + pymod = bld.create_obj('cpp', 'shlib', 'pyext') + pymod.source = ['ns3module.cc', 'ns3module_helpers.cc'] + pymod.includes = '.' + for module in get_modules_and_headers().iterkeys(): + pymod.source.append("ns3_module_%s.cc" % module.replace('-', '_')) + pymod.target = 'ns3/_ns3' + pymod.name = 'ns3module' + pymod.uselib_local = "ns3" + + # copy the __init__.py file to the build dir waf can't handle + # this, it's against waf's principles to have build dir files + # with the same name as source dir files, apparently. + dirnode = bld.m_curdirnode.find_dir('ns3') + src = os.path.join(dirnode.abspath(), '__init__.py') + dst = os.path.join(dirnode.abspath(env), '__init__.py') + try: + need_copy = os.stat(src).st_mtime > os.stat(dst).st_mtime + except OSError: + need_copy = True + if need_copy: + try: + os.mkdir(os.path.dirname(dst)) + except OSError: + pass + print "%r -> %r" % (src, dst) + shutil.copy2(src, dst) diff --git a/samples/sample-simulator.py b/samples/sample-simulator.py new file mode 100644 index 000000000..7a6c5b74f --- /dev/null +++ b/samples/sample-simulator.py @@ -0,0 +1,28 @@ +# -*- Mode:Python; -*- + +import ns3 as ns + + +class MyModel(object): + + def Start(self): + ns.Simulator.Schedule(ns.Seconds(10.0), self.DealWithEvent, ns.Simulator.Now().GetSeconds()) + + def DealWithEvent(self, value): + print "Member method received event at ", ns.Simulator.Now().GetSeconds(), \ + "s started at ", value, "s" + +def random_function(model): + print "random function received event at ", ns.Simulator.Now().GetSeconds(), "s" + model.Start() + + +def main(dummy_argv): + model = MyModel() + ns.Simulator.Schedule(ns.Seconds(10.0), random_function, model) + ns.Simulator.Run() + ns.Simulator.Destroy() + +if __name__ == '__main__': + import sys + main(sys.argv) diff --git a/utils/python-unit-tests.py b/utils/python-unit-tests.py new file mode 100644 index 000000000..f84f05bf8 --- /dev/null +++ b/utils/python-unit-tests.py @@ -0,0 +1,86 @@ +import unittest +import ns3 + +class TestSimulator(unittest.TestCase): + + def testScheduleNow(self): + def callback(args): + self._args_received = args + self._cb_time = ns3.Simulator.Now() + ns3.Simulator.Destroy() + self._args_received = None + self._cb_time = None + ns3.Simulator.ScheduleNow(callback, "args") + ns3.Simulator.Run() + self.assertEqual(self._args_received, "args") + self.assertEqual(self._cb_time.GetSeconds(), 0.0) + + def testSchedule(self): + def callback(args): + self._args_received = args + self._cb_time = ns3.Simulator.Now() + ns3.Simulator.Destroy() + self._args_received = None + self._cb_time = None + ns3.Simulator.Schedule(ns3.Seconds(123), callback, "args") + ns3.Simulator.Run() + self.assertEqual(self._args_received, "args") + self.assertEqual(self._cb_time.GetSeconds(), 123.0) + + def testScheduleDestroy(self): + def callback(args): + self._args_received = args + self._cb_time = ns3.Simulator.Now() + ns3.Simulator.Destroy() + self._args_received = None + self._cb_time = None + def null(): pass + ns3.Simulator.Schedule(ns3.Seconds(123), null) + ns3.Simulator.ScheduleDestroy(callback, "args") + ns3.Simulator.Run() + ns3.Simulator.Destroy() + self.assertEqual(self._args_received, "args") + self.assertEqual(self._cb_time.GetSeconds(), 123.0) + + if 0: # these tests are known to fail for now (pybindgen limitation) + def testTime_EQ(self): + self.assert_(ns3.Seconds(123) == ns3.Seconds(123)) + def testTime_GE(self): + self.assert_(ns3.Seconds(123) >= ns3.Seconds(123)) + def testTime_LE(self): + self.assert_(ns3.Seconds(123) <= ns3.Seconds(123)) + def testTime_GT(self): + self.assert_(ns3.Seconds(124) > ns3.Seconds(123)) + def testTime_LT(self): + self.assert_(ns3.Seconds(123) < ns3.Seconds(124)) + + def testConfig(self): + ns3.Config.Set("ns3::OnOffApplication::PacketSize", ns3.UintegerValue(123)) + ns3.Config.SetDefault("ns3::OnOffApplication::PacketSize", ns3.UintegerValue(123)) + # hm.. no Config.Get? + + if 0: + # not yet: https://bugs.launchpad.net/pybindgen/+bug/246069 + def testSocket(self): + node = ns3.Node() + ns3.AddInternetStack(node) + self._received_packet = None + + def rx_callback(socket): + assert self._received_packet is None + self._received_packet = socket.Recv() + + sink = ns3.Socket.CreateSocket(node, ns3.TypeId.LookupByName("ns3::UdpSocketFactory")) + sink.Bind(ns3.InetSocketAddress(ns3.Ipv4Address.GetAny(), 80)) + sink.SetRecvCallback(rx_callback) + + source = ns3.Socket.CreateSocket(node, ns3.TypeId.LookupByName("ns3::UdpSocketFactory")) + source.SendTo(ns3.InetSocketAddress(ns3.Ipv4Address.GetAny(), 80), ns3.Packet(19)) + + ns3.Simulator.Run() + self.assert_(self._received_packet is not None) + self.assertEqual(self._received_packet.GetSize(), 19) + + +if __name__ == '__main__': + unittest.main() diff --git a/wscript b/wscript index 52856eeba..781493019 100644 --- a/wscript +++ b/wscript @@ -61,6 +61,9 @@ def dist_hook(): shutil.rmtree("doc/html", True) shutil.rmtree("doc/latex", True) + if not os.path.exists("bindings/python/pybindgen"): + Params.fatal("Missing pybindgen checkout; run './waf configure --pybindgen-checkout' first.") + ## build the name of the traces subdirectory. Will be something like ## ns-3-dev-ref-traces traces_name = APPNAME + '-' + VERSION + REGRESSION_SUFFIX @@ -76,7 +79,6 @@ def dist_hook(): ## Now remove it; we do not ship the traces with the main tarball... shutil.rmtree(traces_dir, True) - def set_options(opt): def debug_option_callback(option, opt, value, parser): @@ -161,6 +163,7 @@ def set_options(opt): # options provided in a script in a subdirectory named "src" opt.sub_options('src') + opt.sub_options('bindings/python') def configure(conf): @@ -222,6 +225,7 @@ def configure(conf): conf.sub_config('src') conf.sub_config('utils') + conf.sub_config('bindings/python') if Params.g_options.enable_modules: conf.env['NS3_ENABLED_MODULES'] = ['ns3-'+mod for mod in @@ -351,11 +355,13 @@ def build(bld): lib.target = 'ns3' if env['NS3_ENABLED_MODULES']: lib.add_objects = list(modules) + env['NS3_ENABLED_MODULES'] = list(modules) lib.uselib_local = list(modules) else: lib.add_objects = list(env['NS3_MODULES']) lib.uselib_local = list(env['NS3_MODULES']) + bld.add_subdirs('bindings/python') def get_command_template(): if Params.g_options.valgrind: @@ -413,8 +419,13 @@ def _run_waf_check(): raise SystemExit(1) out.close() + print "-- Running NS-3 C++ core unit tests..." run_program('run-tests', get_command_template()) + print "-- Running NS-3 Python bindings unit tests..." + _run_argv([env['PYTHON'], os.path.join("utils", "python-unit-tests.py")], proc_env) + + def _find_program(program_name, env): launch_dir = os.path.abspath(Params.g_cwd_launch) found_programs = [] @@ -457,10 +468,18 @@ def _get_proc_env(os_env=None): proc_env[pathvar] = os.pathsep.join(list(env['NS3_MODULE_PATH']) + [proc_env[pathvar]]) else: proc_env[pathvar] = os.pathsep.join(list(env['NS3_MODULE_PATH'])) + + pymoddir = Params.g_build.m_curdirnode.find_dir('bindings/python').abspath(env) + if 'PYTHONPATH' in proc_env: + proc_env['PYTHONPATH'] = os.pathsep.join([pymoddir] + [proc_env['PYTHONPATH']]) + else: + proc_env['PYTHONPATH'] = pymoddir + return proc_env def _run_argv(argv, os_env=None): proc_env = _get_proc_env(os_env) + env = Params.g_build.env_of_name('default') retval = subprocess.Popen(argv, env=proc_env).wait() if retval: Params.fatal("Command %s exited with code %i" % (argv, retval)) From 3d6e4532aeffb4e8e03d63b6f81a1c69ee6ab6a0 Mon Sep 17 00:00:00 2001 From: Mathieu Lacage Date: Tue, 8 Jul 2008 14:27:45 -0700 Subject: [PATCH 145/495] avoid direct access to Object::m_tid. Use ObjectBase::GetInstanceTypeId instead. --- src/core/object.cc | 7 ++++--- src/core/object.h | 4 ++-- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/core/object.cc b/src/core/object.cc index 1b11fc782..9640d158b 100644 --- a/src/core/object.cc +++ b/src/core/object.cc @@ -113,7 +113,7 @@ Object::DoGetObject (TypeId tid) const const Object *currentObject = this; do { NS_ASSERT (currentObject != 0); - TypeId cur = currentObject->m_tid; + TypeId cur = currentObject->GetInstanceTypeId (); while (cur != tid && cur != Object::GetTypeId ()) { cur = cur.GetParent (); @@ -146,10 +146,11 @@ Object::AggregateObject (Ptr o) NS_ASSERT (CheckLoose ()); NS_ASSERT (o->CheckLoose ()); - if (DoGetObject (o->m_tid)) + if (DoGetObject (o->GetInstanceTypeId ())) { NS_FATAL_ERROR ("Object::AggregateObject(): " - "Multiple aggregation of objects of type " << o->m_tid.GetName ()); + "Multiple aggregation of objects of type " << + o->GetInstanceTypeId ().GetName ()); } Object *other = PeekPointer (o); diff --git a/src/core/object.h b/src/core/object.h index c28c3d6c8..225ef652a 100644 --- a/src/core/object.h +++ b/src/core/object.h @@ -379,7 +379,7 @@ template Ptr CopyObject (Ptr object) { Ptr p = Ptr (new T (*PeekPointer (object)), false); - NS_ASSERT (p->m_tid == object->m_tid); + NS_ASSERT (p->GetInstanceTypeId () == object->GetInstanceTypeId ()); return p; } @@ -387,7 +387,7 @@ template Ptr CopyObject (Ptr object) { Ptr p = Ptr (new T (*PeekPointer (object)), false); - NS_ASSERT (p->m_tid == object->m_tid); + NS_ASSERT (p->GetInstanceTypeId () == object->GetInstanceTypeId ()); return p; } From 0f045371a31372db9ede37ba7b58dac2e9ab30be Mon Sep 17 00:00:00 2001 From: "Gustavo J. A. M. Carneiro" Date: Wed, 9 Jul 2008 14:58:02 +0100 Subject: [PATCH 146/495] The 'everything.h' header file is only used for Python bindings and should be generated into bindings/python/, not ns3/. --- bindings/python/ns3modulegen.py | 2 +- bindings/python/ns3modulescan.py | 10 +++++----- bindings/python/wscript | 9 +++++---- 3 files changed, 11 insertions(+), 10 deletions(-) diff --git a/bindings/python/ns3modulegen.py b/bindings/python/ns3modulegen.py index 88dcf6cca..4445d9eab 100644 --- a/bindings/python/ns3modulegen.py +++ b/bindings/python/ns3modulegen.py @@ -77,7 +77,7 @@ class MyMultiSectionFactory(MultiSectionFactory): def main(): out = MyMultiSectionFactory(sys.argv[1], sys.argv[2:]) root_module = module_init() - root_module.add_include('"ns3/everything.h"') + root_module.add_include('"everything.h"') register_types(root_module) diff --git a/bindings/python/ns3modulescan.py b/bindings/python/ns3modulescan.py index 879f6ea5d..978069b2b 100644 --- a/bindings/python/ns3modulescan.py +++ b/bindings/python/ns3modulescan.py @@ -228,7 +228,7 @@ class MyPygenClassifier(PygenClassifier): return '__main__' -def ns3_module_scan(top_builddir, pygen_file_name): +def ns3_module_scan(top_builddir, pygen_file_name, everything_h): ns3_modules = eval(sys.stdin.read()) @@ -239,7 +239,7 @@ def ns3_module_scan(top_builddir, pygen_file_name): for dep in ns3_module_deps: graph.append((dep, ns3_module_name)) sorted_ns3_modules = topsort(graph) - print >> sys.stderr, "******* topological sort: ", sorted_ns3_modules + #print >> sys.stderr, "******* topological sort: ", sorted_ns3_modules sections = [PygenSection('__main__', FileCodeSink(open(pygen_file_name, "wt")))] headers_map = {} # header_name -> section_name @@ -255,8 +255,8 @@ def ns3_module_scan(top_builddir, pygen_file_name): module_parser.add_pre_scan_hook(pre_scan_hook) #module_parser.add_post_scan_hook(post_scan_hook) - module_parser.parse_init([os.path.join(top_builddir, 'ns3', 'everything.h')], - include_paths=[top_builddir], whitelist_paths=[top_builddir], + module_parser.parse_init([everything_h], + include_paths=[top_builddir], whitelist_paths=[top_builddir, os.path.dirname(everything_h)], #includes=['"ns3/everything.h"'], pygen_sink=sections, pygen_classifier=MyPygenClassifier(headers_map)) @@ -277,5 +277,5 @@ def ns3_module_scan(top_builddir, pygen_file_name): if __name__ == '__main__': - ns3_module_scan(sys.argv[1], sys.argv[2]) + ns3_module_scan(sys.argv[1], sys.argv[3], sys.argv[2]) diff --git a/bindings/python/wscript b/bindings/python/wscript index bc513e183..503de4823 100644 --- a/bindings/python/wscript +++ b/bindings/python/wscript @@ -219,8 +219,8 @@ class all_ns3_headers_taskgen(Object.task_gen): """ def __init__(self, *features): Object.task_gen.__init__(self, *features) - self.inst_var = 'INCLUDEDIR' - self.inst_dir = 'ns3' + self.inst_var = 0#'INCLUDEDIR' + #self.inst_dir = 'ns3' def apply(self): ## get all of the ns3 headers @@ -249,7 +249,7 @@ class all_ns3_headers_taskgen(Object.task_gen): fatal("missing header file %s" % (source,)) all_headers_inputs.append(node) assert all_headers_inputs - all_headers_outputs = [ns3_dir_node.find_build("everything.h")] + all_headers_outputs = [self.path.find_build("everything.h")] task = self.create_task('gen-ns3-metaheader', self.env, 4) task.set_inputs(all_headers_inputs) task.set_outputs(all_headers_outputs) @@ -302,6 +302,7 @@ def build(bld): env['PYTHON'], os.path.join(curdir, 'ns3modulescan.py'), # scanning script bld.m_curdirnode.find_dir('../..').abspath(env), # include path (where the ns3 include dir is) + bld.m_curdirnode.find_build('everything.h').abspath(env), os.path.join(curdir, 'ns3modulegen_generated.py'), # output file ] scan = subprocess.Popen(argv, stdin=subprocess.PIPE) @@ -323,7 +324,7 @@ def build(bld): bindgen.output_file("ns3module.cc"), ] bindgen.argv.extend(get_modules_and_headers().iterkeys()) - bindgen.hidden_inputs = ['../../ns3/everything.h', + bindgen.hidden_inputs = ['everything.h', 'ns3modulegen_generated.py', 'ns3modulegen_core_customizations.py'] for module in get_modules_and_headers().iterkeys(): From 3ff7e83dd0090394255dfa93c1395975c008f22b Mon Sep 17 00:00:00 2001 From: "Gustavo J. A. M. Carneiro" Date: Wed, 9 Jul 2008 17:31:01 +0100 Subject: [PATCH 147/495] Upgrade to a patched WAF 1.4.2; needed for redirecting stderr of command-output objects. --- waf | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/waf b/waf index e55aa276e..8fd8e63e9 100755 --- a/waf +++ b/waf @@ -37,8 +37,8 @@ if 'PSYCOWAF' in os.environ: try:import psyco;psyco.full() except:pass -VERSION="1.4.1" -REVISION="92c5652afa5cd9bc5029a09cb37c5ec7" +VERSION="1.4.2" +REVISION="223b86eb6a7dae5acd7e964c237cf35e" INSTALL=sys.platform=='win32' and 'c:/temp' or '/usr/local' cwd = os.getcwd() join = os.path.join @@ -74,7 +74,7 @@ def unpack_wafdir(dir): try: shutil.rmtree(dir) except OSError: pass try: os.makedirs(join(dir, 'wafadmin', 'Tools')) - except OSError: err("Cannot unpack waf-local into %s Install waf system-wide or move waf into a writeable directory"%dir) + except OSError: err("Cannot unpack waf lib into %s\nMove waf into a writeable directory" % dir) os.chdir(dir) tmp = 't.tbz2' @@ -141,5 +141,5 @@ if Params.g_version != VERSION: Scripting.prepare() #==> -#6<\%_0gSqh;d!98+VFjF@=S%O[fB$Ms8W-!s8W-!s8W*bKE)XL!&:/]#/C9`#[s?QpO-q8zzzz4pn'uSPe4ukkY;Vg5ei41iFrp$E/eH;GD#9Vq\B3A'Sl?[a+$-:Du:+Bb^a7OJD%&c?28U:R'VGY-gliX=,^a=4VS2lb6\RdJ!=)07%(XgNB_PZiNfn]_$Dr'gB=k8#&c4\mPWeoDftVk[+>*g4f51!&)(HY@&4J(Md->@?EeYEVF+;dZ0X2ChmV_I0Pr#=Ki,V84,$;S^lV#pXuu[B@Aao3S/G*l1'2q=l4H5lMCA?/_m6Of(RdtI0BW8n4ek+fsC`nCl.K#]ECZ%V.gCp:(Vb]p)&-5pU`E-U$N4dQ):R\+S)\)2dQ+7n%8%4Xm\DEhM(^]EO#2]\9saBWcl_&[dEe?DVXPrCYnd;DnXJ"^+[1_G;d'S[dD\OiP+ca:UIjJ[N)m2bO5+F!@h#rLI'[1>.ul+Fe&9r5$E6qg%QM-%V@dVMj*UTkq>*RB@a8)54a?Z\%_/i]9d`u;9uq(m_$7AOh4r4DWPfClc-6dIG;pAN@jS/>Gn!4iUsO0>OC9[hdbp%[qF1W[qrP-f'?XK]B(X=h^AT`qk"7[1"W/s*SYF]?[(CS4r[en^4GTibH>B,gAlm,W$s2ohRekIej@i6hd"!-h9*"(-7Xluhctm!QK^4,gAHGC*-gPHT<"Epoote(cN-qH]?\9YS6SGJ0\M"FG'"UeeP2Ha[e3hgG0H_ku&$2)8-!n#*k^/Ih=aJ@e7i.!m>9\HT50;8D*@Ia&&#UCpU^+UXhEQ$j5$[0*r5OoH``k$HgGUE1[+,&EV9jM8$8Hmf:1pD@%R8aHWOMIVlT+O^;g$;k0DF;l(+-3"#@9R[;"@;lJ#@OLHEn-?Yt(2mMTe%FnYOl03I+Ze_S;Ph"1gP#DE)LRG<=c1ghDb^g!Bu!HelIh*=W4sGItGuT/YBY4gp8V&lgfhf"O0Hq?@HncL-*eNt^tFpRc*4EU)ucHG+4,%&?YBUTqo)'iAUd8Z1HomkF.@n%BZ8qej)QKAQ1e]pe\:45=bb0!DI%Fn!tf=\R]4NnS>5?#]6#U[$Xt^A5Y?Z5_Kc4eI&\?YA7Wa%9._GRkP[kj`SD,fjI;I:AC.cNeB[\4!:'LX2I:ci+l*lHt16b]S6R+n7anlbi2Y%I)RnFh]\cVsA(*XJ\kE#!fpdsHL!I4qR5og(1rtp9(&.%/Na$cVC`*:2i?6ZOiagmS++_)A!X*JaHPS-Wi.effl!Bu;YfUrgI0NtHV8l]_fX_?;?I:^RGg+NA>8e40M54oTbeT'5P=-`AOX25GMFI\'1eSu=:s`%6'M,#l+tR;YN(PXi(rVC_$:PS+7T;[K1*FaS8lCWf,a<,`fU5qje<+R%as@u\BGq)t,%O6DXNYKodAhpf=L#/HLs74_aU0Mb`Mp+s(nqkr=er9r'TFGOdA!%F;DOK`bp5_6@Y#fDM3Mi`QH9RbBhF'cRSb:V":u"D9/9uk@S15])7%AI(r[\r)+dkj[S("%M@u&*KSct$N?j4B9/RVT6:;S&6=WStKZl?9,S26JAh>GS,$7=-d)nbUZU.Bje=gJj$'l>Tg+>&mZttn+9%,U6fZKKd/2JT2,r?iWel-0;dh6KEYaHi(ZSi@l2&&nb8J+Nf`ks;@,+8s4Cm%YH8ZO88dSZbXbqa,M-512Nd[Dmg;F.])>8kmkgEhOs,,191fcsBaZkX?N@h_s5QGcfq2&_Wh?n.@>;U)NWMMY#1P`09eV3-rU=U>XVL1\AeYlc.Z&sP0UN6%/r+IE3e6t.@[KZPW31/\>+f#lQSJMS.aZ3c.>#t5+CA0d8&e;@`n/Z"(,AobP9QH".&NgXB%X(=1;l#m))NbY@jO^NUDV(<9gNH+8PI<=Nr&7-+'tG$)hI`+;Tr5RVaddNG,+dD28fNR?XOW2+^_)MT]!8ef+pbD&,%^f$UN:Z%09?9n9X[9$""Z67POS,_feT(tbTn-u@V'Ju$UaKs`8N10[qJX=V1E=KlL39h*g#fsYL)/P;>]`Be4D)H)fcC2-JMWG'XZ;T`^Q@*GjD%#bON@9#`QK$u/"\]0=KiCBYQfuJ)'iu52GK-G((H*0P>H!nP%BhnPpSt'R$pYlAdsWp9eAtRP;H/e)O"]C7\V^cZ&sXjCl&Kf8S#,m/WC\q%)Q]t,h,sS"\c9kCaRRIOCW)V'p`OU9!^ELP6qMgKOZHBN?Fl[Z"b.FVGc'f[YnlgdSrW5aGS/4R8Rj\LtX(C6%tM+0pl()P.")hZN^jRP@WC1XbeW?>;W4:Be3j1N0L]s/7QRA)TAMjRZ[k*(1Atcg-h<$).G04OsHpXRUNME@jXa$atf,R-n1W`'NS&W;U)$`Ou1X%1nn-=AW3U';N_Zi5[+hZ,pflPVH$'jVV;@lUs4k*aX"rmOK),M)*tMp6u@iNK2t]'fa03E_Efr^W[=.2R5RYlL>*n/`l95mP8-QCeHX7?;/7N*ZWOUXaJ"u!8o-Cn(*XDp6oBjbAYR'fXe`oC6*2&6=uI%1D2U\nfhF6..b6*h,]/O?P0I^?[^!9\WFB_LW_66#_e#kad2J7V`77/[.p>ZGZV?OiU;U6B>1um*9h`ou,T;ieQ>(/)Bi8Y>'d8uW<7<jA.=dCD"'/?g%AYd>)Um[NCPabTDdVN+oW2a"#d^GDi/>O^F+gkl%JCXLi-+lh_=-VDkQYcr[,p]""/HlsK!`hJMQQFap.Wq%5NO1,gB;b.9G7O7U*0]/:6/q>XniTsnOdrB7#lj0#/.`p5A([_M9LG;4--6>:uM5-W_K,7rRAo?[@D.,T^?_KE"V)#$*O_cN3=E/W"IPA@(.6&+mdS`>mR[$],NCB''NA1ik*(=**2^m"YD6ZP`'7r0Pq4aS5_8::C2%lCr`A4k@-d,_&!TSsH#_OL_OPJseQL"NV^Y\RhL%+E-HZ5_ae)DL&4tZq(m_N*151+[YP@FlcL%K*2DL8GM4\@neh;3XZUsH?k1dA^Fc69pJUC!?:.aGQ%/;$ZjVM??e8('j\%5j+u;4-m2(eX66<=94Gh^U;8'P?#-Shsj'n[VIc/A;"re7+sM'.*[GrrNJT]$k!H-/G+i*@S4BY\mZbd,l0?Gc3l\,jpRV(n7Aurbn^*^ujK,Mg6,b[u4QY7+3&q/PI4X]<3d^8&2rlmtC0R'1ZQ;"q;BB3kkDa(jt'&c*nno4rdD^]^i=MC*/k?7&*<5pcDof]Eh(Z'.:^`Ld8l"$ia^8WO+t>-noM_iqYDJc5&IZQ"c1n,b;'7Uh-/fMDsT]0K7//DeBB@UB[2,4IsjYh1;HTRjV7]\9Wf7gk;M.h_VZR7OgZd8B=e1m"h?@#V2439&ninrJqRDRmX(%G8aoF*9dK_NQ=Pp'H%,pCX'lE_t^P0S%AEcf\)F/'F-l8@,,8@.+(cFU*DMTooXm[c'WeE@_oMkNl!Xt[$7!hpT;_Z+mbYFW@+5!8mGY*WeZ.^;&R6]D9HP7:;2aFqhn`OlaY%IKY)WC]_f=mUhpJZ>;[('HjrNJTOS@,#I`'2>1*k)3>"?>hbI57A[er#uT-7C7mHZ6n>]k?)8JBtdMCee,Y4U1e;Oh;WZ6/T1@!*%la"Y*W#"2qj-W/k"'S&=q:GhlAC:gh?,Jn%aD=&fNkS)rQ&PGEE*%<>>[I"F[(iuEfs5TG]Rg9To>-BO0,0189N!$N^sd<0("+r0_C$Ih;U_)C`0UM?M?Qj[^m!'l7&j[1VraPrTBqPG[#?Kr2,C601N*\g;g5Q8l.ip4mpc&Ull?^&bp2lA*O-VTj:c`M)V[JFV`H%uNeqkTN?M=PAZGZ4?"*(f&$UQT2>U;AYn!>R[uW04"Fnl"0-oVVD*u0be-M<1&(5bWO-m:Kfk=^]qX.$/[e$T]937Ngkms)XEkqm8$I,3N3jim8,@`j1U'baBlRQ$6n%)t'RTSF1ig`@H&\b2hgEm#MMd=`W/8e\XPj`*"mS7`<)[5PUT>B'b"2lDUh';9i8T$tDh4H<8$SAI$Y!_(2s8)#%o'KCPA+$Rm2"f8\J-;ER]Ulo""=FU*k2N0`biG3A,l*ON?()EM^b8RZs>J3%VT^ZB8M!*lk%3,c\0jkMe&UQQ'#GSYt12d`L/!/mZa^*M0d_+mu[-Ct/k-IG!Y8]AVTh6-eBH@cc<+G5D!a[G`hsd)5[aNkS2^(5d?Cif*DDO?YeECa`W`mSD*0NW`+jR<3eiISDou]dCo2ObZ"(og[j;H9pK1(^VmgkT,O=Xc0ooIbfJ%"sM7Y3@d]h"TOB*FtTg.&(4FB!1#u`^Z3!bZoKBY4PE!(XYfMkNqKW#n2]d8N&ai6lU,G[qcnE%%92r?%PNZU3USKQN_,tNYL6kBY2)T_!OYplC&)Ge@*'Xj6EH9Lph.o$$XGCu,87M>GXI5QUEOHc*`UTTUG\UjkrG$!AP+PnTbc/Z!:dR:(:&PO,(hoa5,^9j.q0$2O=l,ao9'a4aD:MI<>VGuRJl$EL>'IcRdWgN[W"YKOa@it]'VA$i0cRU+@SZUY`a0pK[nI%=`XI#8Q&g5#b+gdkRhQg)CK"+]"SbC**]rRQYVSbBbsZE.Z(9k:U=0.CR6$B!=t5@UK$t.d&$\2%&mlr,[nNDYQ@oep,d8k^_tEZf*)!*%S%iTNj&(!l-?SH=1.0EMdfOWL)EGkD@['=Q^7((]dh@0r\`bJ]^?'k*8YAZ*pW'-p3n-U+p78Vkm^2F6>rl7qUmTQX+Gb,M>,U-TmIsXFR;Jc7\EkCUln3s]nu9=c8CWpFj.b%A/fq<--.oQB"jC-h3",)7X@mb3fXI&-5%mTd;#KAf7kmRsIo&E^B\7t=`'ZaY@.s(og6Fk)Q6qcl]si00gTOt*e`AGc1nceu(jV(6PB6)B*YG8+nX09H"%"#:%f1_^9P%fiaJMcW$-J*^P%YqKk*otUf]WH7O'N`9B9Y=V`;j?`GE)^-&g:G\t0ggX\7hG`0S^\7?@QKJ5h5Y*.UB#M\lFh)mN$?VN"b(i?k0mF>/b<<)nYncJ@aQ+m=+7(B*Vl&2F'AJnF$aE6MmpqJgN'4_Nmq5`4k\4#LXJ@!i^8h,mmj`YFGAm!4"]uLZEc043o;@un(JJ**md%fRYMMWj)*.LR77VOndsu^%qGoBOG@<[pua!9f/_'#.Lj/&UNW7XNN%,TMiVXm#^5j<(kWhKBh7B\HKLm.4,G=+?PGdJ(!58gjCo\,A(1dpi06&Fjqn)s7JjC(iUSn7GJV^;X%2[$T>34rO/4F:)]I[@17kN&JPQe&$u[i8sfkju@Cd0kV4D:&-&YmF-g/Hknm:(eZqh"UL1,fJZsUQ-U6pL27]flTIrG@[(3&e]LI-jFIN"NPAr0:?#7S&NR?F_9d9*c-`KEl4B@gN6rJ\9t-TO&Vp7b,!eKl=lAtOF8jqXJ`L&>JOUjOFqJD/%Tg`ZF6]%tbF!+57^lsEjaQUM`c^G\[iSk7%9d+r@ad4%KU$`>NYne5BsOj\^"iF'!7UqM3YNu,HJ#`C(D(mGWb>^6c>O`_6t`p5T'M;)P%uhPhM9eM+%UR+*DdO5h%aP07Im:CdE/@uI24jH%/#D3o?^pdN[RfbPTfFgh$SCJU2q"2$PCTg+_?MIm-fZQ+PAOp@%D>=-j(9m]u8qR2R:\5ZMjd.Hs(l=]4-[0o]Yru*9?hN?-niX-M)9G+pchDp59(U(aM6.X78,/3ilQ+cF+NIbMC5tD_TTEigq8=KArp=f>pkD"*)V%iHe,P!a[l\YbC_Cpm1U-/eWn$b>*N2LEij+]GU!)9HZc>T6Z;180fKd3sA9J@^a"9[WU&jZ^F(996."7f_d%h/rH?lY%Zh8NCB/03u<$9$-@0$!\=*(lO1\P4e_)GoEGr-lE&q+r2)NST\p.YDmD7m]`so;\/jAZL_VG8V_Y6TRd:>'<'pj+A]fND7HhIp$eGAIgYVU*`E)[$1/^i6!Z+OFL08Vo:b:b68IbPtc/T64ob4oRN"Oapl8P5D0rffii.>GkY%JI/;Q*<=7oi5rm;afi2BXp&;#Z;C@C6+$qo8qY^#1E5E)@0prJPYUHB4.1^6A]p+c62@TNF,H+IGpm>c1d_:cqF/'orTl,)^!Tj3fci8rdKE;V6:EVYV9o:@m:g@n:uk(Fd^qrJId6`Dg.qVH5eB6)QY&;OMC)Y3n3.pCYkZ,)5e5k;!Oog].oo/'#q3m2E6!\P93^UDQl"X+O9G)f:uFjUkN%Ce?bkScgfBGgip&A0\,MBIYjGrmg?'h_Pk-)]V_"G;?6\;C/,!P!EjU5"CYT)kJ'.1:khe^:2o>2dIaudI;kk2',);8l^F9?qCJ)#mOF9]Qc&f2$Lp#,f)"jeit2$PhVrZeUK"$BQl2[:><<21ao!C;,@-3;]0dD%n!>0&g)8#k>oAY!otGl+,$e^cn]GL[=EuTp^mKK;"Vgj"uP'b>NEL229fH_uBA1Xn:a::8ifnTl>EC.g13IOGa&eilc7H2X3%G-pHLDY=LO6uKY;0#k<,((IFA^4e>g@$(crK4Ah)LI*RT:i?X5Z5Q7rcgU\$(`/12kR+HP^YBo2M&.lNpUQHuV-'kiDT#ERQ=9a.8!ZeT2L(@5i&61["2#8iijCnTJ=tUF'r$3U&`a48!MD[fr7A1IuZe*jO1!oPIW!ng>1-iOMaJa+u.t>WuWDjaGNbZMebkZ;kg?+]IaWK0j3K0j;>HW3JKZAX0[f2*&iJT_0jnp\W6FMCpWP*V7Ub:2DZ!OODm%(/bfk9huhuYC8%tlKiRG6pR=&&Lq4_K;hTKU[(;a5';e\PXRHijJHS"^qWZj!=?_EgA5Sl00@;'NYqN&k$9s=X@Y24*<)3WVE.Gf/<<15agB^"_>$\"C9aD/\ff!_p0,A=OX-0lTkd7jI7K.hmZP&;iHqVDKap'XZ.[!pMn6iPn0*AqN-^^M9+YVIIif=5k2Va"%1N?GUe@,@[UQ/X?L8tGm+5UR(Cc(V(eYTi]?tEGZ7'US2eQc+GculCR"uf,3)(2\8CiXtMse1&(jF>=e,>YaY4QAl,@d8!W99,W4-+@bEJ\C`9J4`rD)UjOJBK)dAkd+pKh[@qOMme@(\Rec:A'kQ8kQL_-lu#A&u.oRb$2I\;/O$>&TF4$d&dQqu,6Tj,Ce7<`"^Ie$k7U2[2r2KLlG8UM*f%25UOk`"isu,dZmerd&GW8K2Vc.];sGJFnU>n"cE&LHOW*e#QcNZaF:SUO\":=aph&:#Z!.N<9sZ_G9;[7\d8H\o+fm,COrLV>2F'rM5b2gc@K8g=H-[jJp$KA/k)J+"3,`Q^:f6+M2Nf_)?B*9G7!>T;2!S:H<%qpnA`\Y>$5[,"=,k]#```]Lko3PWSlU%-m<6.Hbr)aHYjn>+g%q>4%kW/f;pPDt?e^m4Y:?2D\[3R.$@D0eYtIGXChRbG*1B54N%\ffaMjQI4kR$>Z'o@./XmS3V%'?7Bsca&:Rr]E)D7p=b2G>[;B"[plZB2\>[,VuX?8I.-o6ts,`pZk)/N%k->D9uU)XbZlQ2ml+Dum.:#9j==C^uBQJ^NKr0r^!%2%kZ#K*]MgB#\ISCD0/OG)qg**5q`h?gBp=US23!YCon/!K]nrI,g7;@G52,#kqaq,+m;l$ME.beGNsT\>CgBknWQIG;m9W+]Wup5ZJ"@hE^r:to2slh2<@?`P1LgChBn,R+$bjR=dNffnnZZm1h2&PYFQ4L`i5bst&``bAeEKMDuM[+P#*6k*-%7]R8d%>4bD:kHP=JPp9d+u_0)??siaF3a?Bk6XhjGri)`iAHY-g@k4%]f"!>7<`!Ngdt7p[r\`g]!Ep+2`GokmlB\BI/1mT`uc\"**L4d0*(`WtLdMi9jl];fYOkX-Va]8?.2YZm6nE.6Ap`IGdFjsbOjerM52#VUi]iru4HI=Y&Bqm)(1X@nJ(pY74\_Xn^UX=m7Yri_?+/'4Qh@=0ocDASi@FiR/3L(i`i/UU]lND,`7:@H*!J:2Rt^(-qE2QBW]*?dcuOBPN%l&Gh[$\T`n[@Eg"O2>u`Pmt6_)_=9m[ln'(/UND3/I+D@O8gSl\6P5ii>RI)Yc1i.q7-+QSG=66UU<_Vh7b-P,QF1jmc[5!&f)!%:>SGG+eOOr#^W_[$K8[$_I=[b(*>o\;Q&puCmu]4eBm.f2M$#[r"5NMZ2KXI@oQ;DWdVITC-)oTJpnB]D4)F6p\m-),f4/8l&l\8"+b+NG.99+dXa[qAP,%XHJU*KP"$X;gW?VtNi`bC#chY<'5ld@I\JkSopNA\X-Nl&f8mjha\:4g?*BrgLR^*#<8Wjg$UA*GmCC0u2D^s?ZSpgY#G"1a6\o#HY6@g/XqW2L&\r2LENKB]\.s[D/>QWV0s*Ba#$7toM4&o-L"\_3g\\ItGIOC(Opj07_),#^5GM(#anLCin>lLJp'2uTKro?G^30d@>r9/2KkuUHhD0.^6?%+X1\!LjRsnhLRf[dN5K+@\]^X\f'H*5V7mOn;%pGtfbB^M[)qbX__f]M:NmZ.T(t?\baBJW-8CBm;X]`09%&O-r+%4s4,G:Z)f^JcRTad#$Go>if`*Bh7)gh3:99i&UP'lVG@i!PiJM?ok-!`5cuPpTI$5EAg!s0V0F.Nq!3ksQLAGB0IX0,Ah'U)9Fc\HRi',1+";iqV8dpX8.kQGjGce]0RN8;])XhV<\3H+E.eiZ^D1KWff:KpRgC#6iF3_:oP"@JuUermFK%KR0eJ^Qh2=3p[02ffe9f!kJt%]@?N1hAM*8\no`A=QLu`kQ8:rdpPF"gDq3aCg\'4l%'VVT5oIA4FYYB-tJK1/P1_+,uEW6MND3'Q6J@6`2s=b+sWL7Ur:ggJlqSmVk!CCM:ce:5sH&FB':KGVsUltqq\F3rH>Kg^:J9iih2QKcU0KYgHR<[N`KRo]1Q9[T:;^*LuraIfd1sORIsc4kka#s1jqOVo-o($k^JT"pHmlLbp_55#`i&!Y>gDJI`%%pPYGc!Y?9aO+2CQ4A,.@$-hP4`rM=c7CRtk$72ZnD%;jp[(s0*(W6"$pZ_cnd5H;7rXnb!RWcjQadJC04iCIt!)BrgjIXWB^)KW$F#f#?%h&4Q!e32sadXNli\L<,WXVNGn0onH5h*Ab,YGRk&A+uqRj-HF#XfAD1:@9/sFlknGZF'gQc*r4>C25[#>Y[ZslEGd0F)-3N:Z!6u[FmRg\G/&8kGk:O,+Y>58VX[Pm/)@cMD%K];E=RT"SM63D_lLlfZ!/PQ?Y1Oi'1iqBae.RA`mHC<8mCWW1cCmFidpC6?^SoZSh0d?KL!TJOeqCg.`P;J,,=O:Tnu0@WaSUa-0fX:FDoh()Ap'+\N?ld^)mg32&WmT#h'dQ)5fsCmR;kUY,s-!>%Y90a@0:hb.5'CQ+'tfLJ$io]O&A=T,f/&UBV.qnG$WkaL"gKOcW;&c_$bRWbpXKl`W2+HKMA?6OC&l<*=9*h'TjSf_Fml)c)FHrHWk[EkedCn(3?^nE9a=?b9*82qD.'fQGZtrZ9st4Hs>CWHe>Wl/qq.A%qchm,-J<+fN30ch1%<;<%J6h+do9Yh+;l1t`@EFSTsYn!9X/?R]s/d'fq:g\Fp[f@MQ&FABCc0W(P'Ip'j%-)I5M@D-aL?Ir6H:>lU/5Ep6b,b[I7%;rC$@KO%Z_5eK/SDu*YRXms-dDlJ4+YaKDf&H'(UkNl>1]#$7q7O]XpC*)fhi9'onITs@s(ghJ^31o_'0@$cUQGTg6ImlAB[nf0`%VNu@C@$`?rsdZIl*AAoW-(Eb.NGE9'7Vqu[=OB0K2?Ju]?(FJ=*uOQ@S1%8&Z@qCIudQA'-o_gZb,Ms%G%AX:(cd_1mbn#!gW'524>T"Nh9c,uN@#J"tMKN-CZ8eP'\d9Q3/Vj.mm):!+.k:N`iNl!/^Pa!F2FS/F$.f')dp4'VB/tR(NqP>JZT:\7WJ_+0]S%X\8Qf$,79)+_.oTMD/b=\Q"]tVqSArSj^oAF9Sa7ODYf7f?oX.%p9AL\-LQUKrk>_Bt]R3(tZ,L8M&:$;+-*"?eDNI.[l7dc9o1rekILL688E@@*rrVdE%_jb"==t,Cn#+m8#=;p+HGjVGJ50qRFZ;`;s2LWX,VP%aY?BTqCHs^`Po"#$-VaNG]$hT6W]AX[^,!CFqdsS%(4!=_-;rB"15m0K:)D@MBbTt;k.iLSnmLM:9D4gWKHF[a3]m=+spe/?#ccP[-oBDd)-+s9#c8N:[=%Bt>7$ZQB/4o,Mn!t9Dq#$&dp/`]V@L)9_&c=j#qlTO:)!_"prZ@1S^ZRdGO(khdoS66!(_9L!FdrreF27?YBIkjW!bHdD0_$95D"IXiN,e(8+.tb=kP&L/N&5\NF)W7i&9e_)Z.^oJ#.FHDouEPsk_"=QfH>H-q51lqXhPfV@1aCVpk9DAk-dg)uApQ_fj3W.,n&\l\)s4ft1:fS3IhCf;%Zs],M4V[iYGDcLojtiqXN.]gTE6K1chi6e)2VLL49%g8aC#1pc@>D0i2gTe]dH[XIejIU%=_E795=**BI/E\jM6q#4e&K>"(+^,Y0?`=*DI9)gb553cJ3$1oD#LO1D364c=C]e#^DCMijUl`32?d0fgFoZW/sl!*&U4RqA>a+#*akg&d9H0hHa@8-=0t'+8lqYXeR8%YGA-_OId_ZnlktesOfb2&K>!Mc^IV@W'>#4]iSZ(8'EXWNlFuk:aX$4=,5A_j/iQ1g.o@@=#p_h4n`l&o!WP;F5gse*Z])Y+L,L:['s3(Lsk=S^]E\AoiNa&>R0A6WbNLa[AT0(^r0^W1_e"Q=5X\iZ6fGaMEG`cfG-MhtXP-2?0*m)jfpj3M)i"2L_3\50+*`OVFI7.ANFc#/'R\O3dUe`gXRUoj'4@F>]SbQ_t;L4SsOcId&\uqYcPWRVeR1N^l*>Y4LHI\P&o,Ne/'@AL5h&FD0k9e)Ai\Q.>NZ,PTI@+qWoaEbZZqfB`&-h`'`rJ(=+hEtUm;V!@cdGTPABlh'b<2Te.*m./bF]Ii2+\Sgm$iUq70cP;p*G.Q-5lmH/dc,[,JTVO'B#2/]@_Pr*Dq^*J_%Uu;V76qbL_ep5,nWJ<\-RY?&M&R>BaooX&K/hoi>C)u^10TjaTAgoQ7+SZ!fTB<=2JaPYk8b@&VJcQQ.(JT`mJQ?/Bf>IN/3u.-oRi6pR9P"r0K`k<7(o=JC^r7W%+C@i@8U9DMk4lCUDb]IWm#0"!JI(#,7;9gGEK-t2?3j/r7e-bYWm_7$'NLr5P"I4Nb79gA;6h)ZCi5M9$H&#TX9jk0W*4]l:$nF0>R_>")RQR*Uq$rY%Y:]7bXFF-'$.7et,D!h=^bO7D-o+cgqY$3Qn[\66[LI6'6^6k[Jlr&H*X#^YKR(G,TN6='[6qrRp1Pf,:1dom-QZAb]hLNQq]^Lt)9I+U<4@_=[S]90u&OmH,B;p2Y8Qc&R_-pepC`8ft6X[-\e[g\NBOZJ>%0[u\)m];1T]0J#:rhS4CJdj,%%,``Q7;.^h;5f/>VI>M3I?C>%\@)Kg>;SOp*V1>iJRf`?c8kSkI/J68B7![*#'V+UBfaD2_sl&Vt.]=.ed)bQ^K?-JK5FC[38\D&ZV,$7MT?@#PZFaO(@s&7orW<%R0>apGCNb`#tdKG6A-doP%E_E:O1+tNZD"Y:n?*,['-<.l1KVroi;C:R1b)abU$M*dB6li+D#``JkSNS*8cOJF,'2HF,rJH`/Fh9ejL6j+"nU(A@$ipMRhfXP;IhtI^DNX&_5VPBi*q@7KNLKA@$e`Zd9Epi3E%@alAoGe)qOFo6D"9FL9,!'1a*\_H-OFp5"$O6qaD$XNW_@31@3^u!8d:d-STT7c@!tu(^Bo0:7j:!FNQ+#os!L9WR%DjMOeG=+X;aA_&p;%*h\S[j\o_q)0nFc_QiGm15:h"BNAI),'MA80e6.Rl/"/tYXZY2`pN15i:_V3r_Xqh'`7#KI9+O%b8O7I$g#8ANIKS!Yr2pJ4U_b&iR7h@)M-*WT.;Q7"!NAR$pkt8t'MN;C)XkC%^16,P&Tj\/[*e;4N,\7/e4%N?$LbNO21AZ+jSd(BjL*q`hf1@qY?_(IW<1Oq31Cl_2`AkgT%CXi"8i`tV73:`HZ"-uh#OUeWM7+QU0>&;hP)RA80`%\@24qVG!,9'1.#THB-Gd`:rR4i=`#,3)CKN^lD3fUNopTaWOPD/YnR]D(+?EM(%8L>_:)$3%:gG6YkE`u-#[C1oRB@r_mC;P7sYWNRtd43QC;p>3No1,`i9@MDL&+l%/L_D.g1LOUlmM9ZR%ATi<:5Ee%<+Ro+UkfJ/YB^M/e@H-@dt6TV!ZGVIC/qdn$c*ISnjShH)8Ij*uK.tV!uK*riZ!n8[7/.iEl5hFWr7koD\'i*]3^s^toc13Nfd/ADSC5*]-\hQH8fq$[@+b^Kp!f8L!5H*B\\=+1LmoCFQ[bS.M:l_96kE@gXF1$LtG73MHa!%=b.Bu^ntQo[iNOPhkGp(G.o?\4E`6gb]PC1U?$O[/bdu2R-R82U;\O'\-?uSKVApl_`ad2=R8`gXm;Jf`(DpuZYm2d4Hd6$jIsuB17!08jI,5k,\hpC!LhIn&=Qi;iH%S&s/`O'1'Pn9'#+fMeOCHl299[Z]XaHW[S0&@QTqN`p)%a2nWh%HAkp)Wc+)ZYa16LbKU&KE%;/G'CEE*R(?t9$<.MW:g%>mS[8!ES5ID'Y]c/)\p/7j@i41hdOP[O3Gm6aP]e"AstF,nh9@0TIl[_L=rnUKnD<'Odro`>pIA*;m,\;e=\+UC^\Ioc-KE]PSN^nm/&n>9"!FVD5d&jpJ7(\uaU7P=HeFR?o!hk;L1;itq6%-Fh>`oH3'HT>r1f36m9fSaVO&7NLIIX"elphI,&o&b$]#A1[f`6'WG0^laNhVZrVebYWQj5Uu4A3g6T'G-Cg%u9?Ehh11Z]_1s32m_Oif:hr^Fe/"o1W;q*rBDdb-O8A2&pI=D%kRH/*T"boM24>6+D$?dckB.?ad`ee,AB`4Dgb)2qTi7Q",j!pH>mQ$2a&qL+gW(_f7n>1G#RXk]q3Npa@Vp`DL\RI4V0MI@J0KlWGcseC,d+?S9"5n\CR)nO?dVQ?aj(q[5jN!W)IP;imBPYKf:ED.?^WVY+PLU(L(KOS8XQ7aRhKaLC`HtYD0)pr)a:$`S]i74P!#6c60EtFj(C#b:/Hu04_B0B)!GPnLN-bOSZ&G=)Udt-@%fHP`J!((DeZ1SHNS&/[/LR*L=]miAogWiHFEH\3\G-"5nl6`B&R)YMsC,jep]KTZHb64)l.;q?:EEa:K/\e5Y+$;i1-hsBq"@OL&\Ti&qtp<8LYgd(m8DZOE#`IuBm&KUKK?VP5"X__4E4cAuKg?C$0K,KhnFBT?#kH9_q4?+EkV49/)PGBERL;S]*,o#nTJ7B">pU]Jff7.J??#6^Y^Xho>%TmX6D^s8U=2GBGmGMTbYZn4IU*5RcMu7S8U:ts?O_jc,Y0>*FjtjoJ2#>lr3u5+9t3CRWNe@D_pJA9kJ%-Vr-iq]BfkG^F+!`W./+1&.!s%jWBrf[K9Di>Ol$t+QI)l$Sd`G)$D;([B"?)2A=g)Pbd4'n/>6"/Fr`j%jOB1U1,6BBje#l:PD*g:]L1Tq>>dW9KLM\dmc\\nY2+LOEH,jdRh!TsSrtjTTq4BL$e9f_AtdG`gS.fq1Yg/Tg5puM3_Q>bpZWOf/SLA7d%M-4+3Tu]7si)I-J*U"7J1rrQH@Sm@h/Mdqk,d[/D:`?5c/M(Stf(M-9_b7Q^tgH+l-S?,K=Qo`bK47j*H&YlhBQ@f%O_XmQ2.CBkSOJ3[(\.S&RX9`LLEpr%f82Xa?O6r/P]?N9g?&(nG6rpSMsm097d>-90mTp;;&,""\'he=BP*pdAugaQq<@f485]3Rr#:XE2V7bhTZV,e.WcrXE#%qXi[H;'&Jf0]7FaM<1JANua0n%s'P!>S+eQ4&;Z+:?(Lh9IKtODKnR7W7,Bm2kl]]\@QkLh1NWcsL+9]=N4N[9h3C:7q6X'/G77msdD[L,g)"5*f#[Z;te33#0KL^IdBDC+SB3(0]B?/dWbuqJHV.9eq,4u^WThG3ZNOAo(GqM>-+D-^r<]AtAC"V@A+-`C)rGs`%a%W=l=`l[eC!ApE9cZc;abKno[usbF`Bk)_S)(3"dROR&W;0[B;^`6eG=V8l+()]l.8n!h/'R"c\nY:VAQ:,.L14Y2@VI&e7NA(P&AIFPjQQ;Q"hI8GbL_j;a)Eu']1[m#^#YC3hr`2OE]9$K-t2"[-QK-Qa]JHrnLAJ05pcf`ZX>J4iSuY7;njlhTGe&]\pPBeK.2+`sIf5[S6.ik!"\2cc8)tYMV7][K8VJ0QjBCPL`N#.dcPIp0Rcod(`$+9Op^JC>W8;?9#Zu[C,V/Y?I^WT>N@]X,T=*[FB,BZDc;piiNURG*=>[TmOmD@0"s`n:k+O]63L9%eV0.qtFij`S"_okpFljmebt-hT=HH8o/Z"i-[l*dW'/a)pD*dW.MF<_G8tE0p*4*>?mE+h[4&6TgrmeiU1XPqMu>736lrb]In)]_5/hs7*c5"cVYNXIYgi]X4k6GQIghEl_RRc^5EpV@\r<$iMJ<^Y,c`meQ"rQX\cT5'tqr<39oBA([>,[*9Dn/0&Kq>6F@P($mAmaE`AdJ#X4)d,&8%MQ.[X$X3!;sl5-J6PJ'Y]:-ojkLP8o4=\7]CV'lRJ\6EdE5!$I0okQs`hfF"d&Pri\eJfg@7%&ND1X-W9bl)XP]Q!PC;6p^@.K%!G2@06;"O3L)?r;Kb8'8(V2D,.&$s_$`cID.AZtK_o@6^nfL8H%HkXrrRLTUbng]S%(m1fmnuBdQb][%tjMC52;=*.`55s2u*c[`BGu)m@ihTgGMY9j6''9>/GLj1Q.+mpN4a!n6:%F.#Ap;'oqd#)<$eOF"^3?`L1b-d@j,8l!C-\Y3FU-p\'ahM8;JFk7Kgmc1.V^f)9[Aq)u75*giB\*b8T`ZQ1fjZD@b6fdj?@OEZ=3kkFX3^)/Q[BqI<\1Tu4l`KAX8;sWk0M'G;_VQFE/M!\#ZNJ]osh9LESlYa12@l7-TN-'N+jMj%;=07M8qUA,0T@:^(PPP,e13(n4;@["/H/h!&HkY4;3YA%H*&$/M8D>S]\2;RdeItN<'6N_;WP:K`KgciTmY]uGX1FUdBk:'0Y05uc:4^_[NaZg$71mVo!USpFnjg^V8*b-CJWG;!G%Qj!X0c=.VmgkJLTYD(+gu@77tqc6UQXZOXR.&D4lmqnc###4JYs-)pCY@\a^1_Y*V`)0JJ%daHPAlN[MEEE>4h35b>"HNrdNCmWimF/hl"!CL.@@,?$Lbiarkp>Hg?\F>DQRTR`N6f`9-B'u,k&;b9lg*ftWY*Z3ZUdLk>^-'g]89W0pK2-e=(d2hWQ3YTQ=ftMl%/2k`5s@-+F3-UpY+H[[Kj&c6E.oE>qW.l*;M!;f!]$pdl^!>q7P[kFC;7)PgS9O!@SqthY-N4LHK.LACu`7L_+@s!jHLe]lKl9NF"<0c0ljmu'j_KObP4E6isSgSS!IAql6NCC>5*2\Hkf-i;'&tYKCY9[0b.ig1O@r-F9B;ru<("Th*ZpRU!CQ)rkFfEXHUn!IV);%`+_HWoHDo5[Z6?Pe\kKm&;>dY7Iedkp'j8=[!=R`P0:[K_rOSLR&a1D;p.OSq]aMu1@cQdmOSG//fJ&(0fKT*49n;Z=lpjGB)_^&aXV'#XdP7E1O_8bs+fu:KT.F&cWH=0`:?-aJ!_?-?,:1l1A^>CfU7Rot.`+NcZksb%23to%PW9!ZtGLK;!Q1$eI3_;B)h\C"up][q%,^O!Z0f&Z;X:7Op3=HF3a)o5+MErXHKH:!e$7fF)YE'*&*rp@_dIY9=b6@g9_r(.84$JVF0$,2Z;Tbq+T@tU/1OWD\tMuT=UI*Ad:-ALWhp9OC"J]q4JqL_XUQl2i3C*LP.lkXFe$qD-)_8FkmYlWO%fOU9Gs?j5nC-j)W_Y7FMu.'#@\:9.Mel?1&?J[gO\f0Tlfh^FCCt2&'KQTUYD!GZ4sstf7V-ON9#3-h*SmO6%#[2HOYj_)=^0kF.1t65%gUGm2'h$J,N[.:p[cLl=g`rmBU<1pUjfRme,-J(R#,?SA!7V9_!7-G\ZEX?q>B0r%J1?udsp$s&`b#]m.jq!4]X\[8)I:qD_VZeOXFKs6@+!!lf$GB&isbk#Q,.`^0R9g9KJFa2aU&d0Hsi.$SF7Xm=^T`'*KjoDBes(E0DVfOFdB:J?B8?K?GPjR/Q:UnR3QM<_mHMBDe8EUBeG4G?,BG(;b:b'ert\OCn-6Y:JR?gkUU>2HR,L.\T[.XX5&If]qdD2)j<B.g_SsP/D\7%+LG\&+t$=2A"?uj%Z6QNV])C5:)gJi5.C5SL:RYE8ZQ.HcVG@hU<^Gl1:$%/+EBFNe/^d$m0L*f0?\3l1DJ&%=`mEhAWiHtVTiD\$_)9[VH0*HYgSoeB1scSK9J;3muL^32"nAWIMMLnfRN`8[W4*2I4J%#9U@-OY'l@OAQ28lW4B(DaUV6ZF5[,#HT75g%PP.hN7J4V]`ABYd%Z;AD3V8ARPlB;JQdn6#9#"8AcM*r)BcGVs-AF27Wnlp7bF5&6XKC,'Krh9T@',WB'lup*DEDe0gO5[9F&a^Vk(3_@$s$UkYY11nKP&jrR)cc@M'n\u<:NDZ_oP4XH6TQ>e`Sg6*q@c2stZLT_[\`F9k;HK5K6bmHZlP4j92\QUt0St;.1I'H#a($@F?plfoRs=/;iVbr.fsYdG)2pb%k+LLKI"u@@%CVb.0^6^c-LD(!ps#;p*RP.sP(&1ZpD^ZSr#!B@R>Fu)pj#%]K(]BOZ`Ig$VtNEKMjNMdD9nV<5gk69rPfqa:K>20Ecce&h*))V1oGn+3BgX\6X(ILO'&P9qYr4N0V'i/;9-NQ,G/e;T_%W;/t2:R5kQp*%n*$)%L<[n&:UCeKI#02_mUap8`]7Cd*C@*dLr#&\S!^@"u-./LEuCYXea0dg$HneUIH=mii[IFdtc(>#Qa.GTn8AD@QR$]7.*a5Ih_E`Xp>8\(>QIf.*MnaXq3T:U1BP9VBeaOYB$17=W#_F5&,A=K`4G>&t##6rmA(,)k:#Y1MTrRd\,L(s?6?T]Fn(RNkJBu`(+Iri4Hqkf2AY%a_W-g^N/'W<)%2>"jkDta'Q/j+W:A3$[W]=TJPT:RZUKHr>1H#!OaKNiKCogum?%\iAH@;gGBS7jlS>p>DA8l!eSFNE9`phlL4)-0_%X^6.BNuFJZ8AYZPDnbHK;JEeeDo6R-q#4C6[tS]a(J1:'5ZnQ;rL2ImG?%gX)K:eaU\CNRfKE,?gQX:SOP(rk25AgjU%gH[rNV`"1Jom(3'+r.B+."3Im^Z9TkP@rjIMf[KOTi^Goqgcs!d(!j>f1qeNA'8FoDkoQ2"-hbLksT?6YdZ0=dpoEme..=@,dIqnHQ;%3pc,NcslUUDPu,^Rm8PPe.Vq!)=aD:FKSK]?9-Q<9>&P1kmJ5,U!DO@M0t;0-4g8+mDbjLC,+_;RU&8P_/)0@VI*0aG'Lsac9.7Fu9Z16d$]>2tWYZVXokgr<,IYC9/^bMprn%M\2[h$M/!rb@#`9dKE1Om`,q"m/=RZ0+.t*9^L7a-'f(uj(E9cOA(US_opY[GNR+,E#aj$i\Qr[2RHo1B!Sl*3"lBejtGbM(jL/dD$P*teY\)pCj95XdqQR:cO2!,%prW2Z73F^>&L"l(OIbjP%tE7]aI)]MNN(q;6$-lZ,%Y;K2(`e1YZVb\7%gMf'1gZ6Cn5il+=E7hj2hJ-mNZ$,>184GNl@PC4&'c,Qeur0p-gk[g8,YALqh_q8]#H\oAdRP-cHDc0![5$,r&o8U`%Qg#.^P0cX@ZdZ2Q]-m\cf;Lh/qW,kBT)Wf'[2E+#G*"AB1DgDcX0(@RFCP8a(7ha7c9f#9kHXY;FEQ0=>KHXipiDOR=_mp[sR"3kX&h5Lq]%B!fR\B]Wjp*OL3UMmBEeM&3A4Y5^hTLF/;`F;>L_Naud@arKn``KmNI3A%;!di-i`9lJ4r%ApM^R57dNHJR/1^`dr5.35'.aeR7?_B[QiM;V6e%7eRFHgmo.,#OA(d3ZgWm?X(**\EGtQ=^*LSU&eRJU)'N#f4(o5XNOmQjTl;:D;-7FOE>S2D?0!hpX[IDCFnY9o6H^O/Kn-T3+gPPmGJSV.nOd=`ob\=XpO-KPgkPGC\')+Fa#Wl8"'7H7V,8HIJj`$4L);,=M#2G+kWg(D06EQbjCn1ngcofrW2Ju9l2O@9m4'_36bk)uOq:+dhLtI"^M-Z,8`?bm7iQ4#V%;I'#Nm+NG*b9EUY_%.=6.gqDbAec5#R"cNScZTSr-M#;,_l#E<+tHo/2ms]*sOu=&s";T2L/q:PB7p,P=2q^U>8aa7BFY*"X>O>dei9k:%bqN.>[$&25]?2=M^7XK-U-$dChA,XgZ,\Y2`6!QBKO]N=%fiXcU:54Gg'LNoX<$N=SB41->sE:R=Br1Ed(nEsq(PS!p]&@jQfdE(_6ZmTlABk1$q4'4QU>`RCl5@"?+l=,HWR8QMdjgl"U[lmN&b,p)&`JC*HJ/r+pS9"#a;K0t#dC`btc>P]d:"e$[(jX"?eaEeI*\Sc0@0Y/T[KFT4`+^A)p2PO\B)<2t`7gL%60qL7Qr/4`/>!Ic9#`aiL9kSOEqF.>te48UH$$d0Q;7b!EL@"Xp$,_X52)YI"&U\aB&Ik=gLeagJ3[HhEk"pkb7s%>W5OCaI_L-AYg%#K*mRK8A(N.u>c>=l.ne%Q_#mVf5);h_,&tchkk7PV/S6X>^D1=4R@u-,+R"U5LDie+1cD`^.MB?`>;2%)s-D7T`Hub1jCnA=nO%5S$SK\n9H:KjMbDr+qpCrTL-=UO`\/GC2"sSkjN5LL\0K16N9m:"t!^o'`;-:,H:Z"]_LB,n)%PG[FPT_Q6ooo1X-F.MX2@0<%ITtek"c.0ff?]gK$(%&=;bla;bk9611iW^f,S@7t,A"@f3G>'/1Y$;@b!E!H*^VLkaa#ar[H[K(f*^#(MY'?9S9J^G#96-DnegC4H[p@Ihh=F(]0o,0!/o:(d"DaHjDicudR"Q1^)MWD+@pX%<,_U##1!?"G\.b9odIhWj1"!M^*J)=KH3_d*MO_()3$B_U*Lia+ELZCLg1m7lt]q@G2B'!nZ[Xm[-Htgfr5T6Xl:kM!1f$/V>=Sp1)-,)(O!&Vi`B@eIE%C,Z.oadHq>UPQY.MGZd6nbo#5lW6UHVb=XbR;EMJC"D1^MkrM,BCLoe=>]6bJ)CC^FXLC'*:?pl^D.7HN06R:d%XL)gaAZ8-IC/'HR6W8IddqtjnE=AD7AOa0S36bAuW(4VEd1LOn5GS8+_66PSq'N/1!%/iofcU"bVIkA',<:*PM[I/?9RL7/V3K+MA:Qp6")G!Yfk^e^2e]8iu^9\=+"GB40iqD^[dCVpipKWm\@c+6Te`Wr;(A2S>rbDA'Q"5*_'NRf6d5eUWJ2t,sI1>e\N#o/Og6mgZe*6#IEDY!%/gCuIKqjo\P)h`I$!WdpO_fMfqTPjZ/&e[Mub/lt="(`]iSW-ZdV50+Y374Fo0Ok;AY\ZZF_WE7-iUN^Dk6gmWi.pehmpW!\]LZTjfPsKK^oWgO8M\2S)H6HHggt]<)lldKhQS];r\:kjkncoor_=T`FFG7K%7&FNMpiS2'k_02'YqDB;O;$>/1&H/1VtP'd)O!5G).fD;=W*/Oqqi2#@g!Ae:)WTO\`?&;J$!j`FF7@,\=*+X3%3cXR3k*F<-<=,G\O7_0%5l+>#uJYlFcsODsX;0eW3TK1Tn.PJ4M6$4)b.p+Y,Spu6)HD=Z=2in[#C-]+tE1nl`<"WU%oJH3n*+ubcjsFDUf82RcdXqSDRCZ;VcLBYatJt1%;>HW8GpcCW_icOeqq$Hn[DK12>Q;XA'@1(IIn5+E]!!U$7FGgCU6e@r!$[i^8tPI=c(@RjO.ufXaM@\`E6q;S7e4g&$;]\S2u/2UCI"W&SA#)a3B'/<&c4DC0dJOS+_/*OP>j+b&]6+hr:t8AO+Ar-KFcc\=VU&@)>+(:/sTsj[ubg?g^o'"6e=oCg4-UE*dcu)PGhjkj'/V0l[TX<'+QF(8ZHiGnJUSQcCEHnB\`&Nj5,1$p#9hF6Te&D;\D\P.VmK-6rqmuTG""#<1F`A-0V)R*Q+Jeg/A2XmmGA8r+.Kr?\JJnB,I6/ehc4Pq>:H((pl@[%i*XDk#X-8'CVTpZ`b)uHbdf=p+.7_8d.cs7YSWoOMD6'P<$V?$a2#mnd_o:+!'BA/:JWZbk-"%l-.cmF*6UkiG3iZ\HMJS#DhOSHQO"TImZ_0iUG;.AY1i-02DX6V%l5Z&-r8[71_Pl\q'k0idcM-1*@W+.ljo3O6-!.p&MkW+;"sF"ot`=YY%kDqA:Ygfh,0)#BYlqP,2^d6a07.68Yja!k"mJ:V75DJf;pFCJlPXgt^B$#Qn6"n+urmr!)'-4$!#Id'I>\htQsKqWNSM#nW5_&?sO>50nns=/4g7a4c"6O4X"^D!>`uNHh$YNOIH,g(h46Ch.L.D$s)-Yp@P.&oX!I+EALEeGeoTR.C.QS\6_0oI2cuH["gp]-[9RO.G0$Yj'KCS,,TFU1W2$:,g08;4:<$BCFfgoA4N%]i&C`NonN1,[+X7=e`BR-qbrR9iqBH>2m5h?D9@B0oReT'%`+-aphj?bOW,#8jY@i7Z<'AP@hSJiKN+pNBMu`\!;PpEmo0iCKlfO##r:N\(Pk=V,l90QnLRe2m[C,'/\&Cli62m*`K2_fKh3?]Lcjc@H`o.Pe4lbBDl#uf^[^8-ZAQt2]TjoaM8Y'Q?lDW-`1HqR1o@.ojhOS7f57gcfYO>\F[[%`GkJQ3hPI-PN4D#ZOVqpc=u1S;X"]3la6M<&tHDU]hSqgr9A2b[]5aoTPhBZj/Lk&>`HZhnkoZH1RRusThpq"ph0"Wfq@uPtGb56.h3uSoX%'>nakVmCYdV+gRs)Wi,d\5\#-a6rU8;CZh>T?G5I(ET$^(>;eI)%:[YV*rH,jZJmV+!qY_/#b#E$ZA/H5g]8o(;B&`=;;\ETZs?\.V7]33A/F/j?51DN8SB':@arSM+GB]/!S2]lAY1.r;4puJ(3I$I`LKOYJkU7rfls)E(M^_l^2sW`=rha>pR#1`j-g,%M`V@\^*_5e*cOKNLGd!e`Ss`[B&)YTD#1BRcERqhb\nh,.?0"0:a-s:cbmA'<<1!'cPP>JjZl>-@k23G-E4C"&a^FFCn`.lCsMNj4<@K)c0j-&gE%%1D)XpR%H"hUu=UjeG;2XQ/*uCXL>KYM)@K:KV$R4S]60`[UpBfEj$n%XG//Y9D@aPo_rj3@a-H2V4L@Jr8!?G*joHVHISYW`MbIc)78LW(8C8[on=g.>%:E-/9&J.XrLgAXk%JG657)$:0%-cf>Oc39$)aJ8pacOlrKEiUcWB0?:c]p.#[l9c,`r$_.YqL/D!=`BOt8CSX<,Y:%S^"6Rbs2]F./n+usQHo\b:+*YojWrnFE4f=*s$$lAn'+OEsj&&GUJ/!LD[@g+';Hp,-Ru:BJ+JVm_3@G+d+2:O4F%1<;_,BN1;6mtUY:\j0gmL)f2%U`h304Xc(.eGf*N4s2F@3f+#C`"2Z1T!'b,SW'*gKj?j.tcc>YU0nFe5;2$j(h?7&Xnko/0ga6\W!lCs`;.0sITFp$@j;F.1^EqB"l9;A7Je[(:(%6&gd+`m)J(3F2/cS>nu0Eg-si0>MqQf@)"\2T>3=T.BU!N\p.1Nu&8V$"N!AoD4_.p8<\)k_JR;l>+c*'u/.qL0i\NeP`JIFH6.h%&V")V2d+LuQdkR:--M)u*>O8eZB.Fp8O<(=68PU(((H2+b/4^-h:td>P5C',q'XN,Ws58W9eJs3n@!OkK5peW4.jf7s]\_J\O'If!JW&!%U#DbeK\\iHpXTDZA$+/>a?kbKu;0GFELa=0\QSV%ic8QR""+:iPI/^IK3o2;-k/ojt&bjE$*4aP.a8$&>$0jd*#g,sV0dZ:C^U/1:C7.S$n_,TN[F-DU.*ZK0+XSDfD65r5=fE,YLafj)RAtgdA+OkT`*1.KHuUL\PPEC'Xf^#m\mkr?,*A-.m-n_$_=4\8Ja;CXgR,jr0ht%qW5Z20XsS,)*6[=Hn^Y-(FhrC$?cbg1d>"1^iF#`aP,/_#9t.d>q*.riAco6V6n0in.1$Ss"5\%YG@A-Ws.c,iY1niVeW+)S:.igA_2?nm,+f<^8"gH1Un7]IGJA_\'1+f>"?68C.NO=S&gOoI5F,;e&^0Q-hH.@b*/QYWcEZ:jKkJO?Z$8R\EX(?VCmcM=26big6Q-8ilM*),K"jXcmNn%2?;%:E!:rWq/$b[o'*M';U!Y]Sf6>=W^%YL,417bJ"`f*Xchj$L&diTb2PA/N]9H7pF[->uKMhGc6N2]F]\gC$)Y[;UGEAgDRU^H*EL9_HMr,8!FmQ$]k/a0d"Kl&d'KItjFU,(2S'7ujRrRoqo:E6>Q-[l>QKV(SdVnZajg;Y3B)oVkDGnEB#H4LoaWq7(#P"K#aSU+<0K,5n3[eum8&8qY(>ide:##c&\a8'_srZ$JfU7VLja9=S4@9D.&?1/%OY(^BG>l0J%B,`fbqj-Z5!U22r^78dI#i^6tNf7lhei:.J;:_)=Q'q6'&;hOp/YjP;b\fDW#bSeOlN_,<=]g<;F=YH8AGQN>ZT2l-UhFmRWX2Q%jPbm$BO+o$_[mcWHX4g1mU\.^"*ib9`=7XQ!8sK2UiE&k3eOG!9T'@]asGcII0\SEZg-:hQ.#VgDE9&JY&-L2icoc0ih6\]e\Gr%Z=I5`Si4P#k.,%X[HrT^FX5i"4[(QM:UhXJXXuOD."gS+nGH1F>hR/7YtUI/:%@TT,g&c"aK3#%:Er&^5-V)cs(k=KZ#Fm`9*XR;FC-R0U!81Pc":b>&A!3p3gGX-S=V0U$W65<>@%qNJ-/Fh=j[JcOI'Xgrh-?VRqUn*>J1XS@sFqgMeNAn*&2R5GQ#"(DSV3^j'+%Bek7Zm'':WcRd6VW!6h]IrnqelG.+-I;:gfClGMK2ZVfPViY964nS[75;?6/ReonGJlX`0ULqs>b`0YLD6XPKe$G6e\iJm!YCh1$s]f%52mI>pnS;5cdWJi8BL@sU0NZqcQi\"OB-"Fn/7"GQ"$q_0eN_k'Aep>(Sp(Igk4cQ5f,'sjhJt2S0-^r:XRQCDnR\(QJI`f1f8!uL'mA:5ZNiBh7685H5CGltdDacEP>*D"(Wbkt35EW1sHb(-]k7kJ%g&m:r(YlGaQVh->c"5?l;P=@BJi1(^*:Y1h$:p;MV\3,KS$,2gJ>F04hG*g^DCjC5%,#'KE!=MY:YR1*RQB[NPRB&)[QWZ(g6a)OIoB0_q[F_2AO$9\+nomA-On_p#eu9;M@O;r@e2jJ%i`DBYlRZLo!pRH6HL(DiGh."lJ)V(>(3JMRF"$EMAh_f-#A2r4'5h"KLR*a@oe-WgTQMpT`sf/gVT%RB1Gg#M%,%H[4O3l!9cN_/dVE$FLsdNdj@8CBJ_MF(TM_e`/IQ2.Q'&W5@?W*[M"iP5j^)](ZD:]mR^ZH+fX$#-/BTfnGI\#Y%3nI_f8_cQ+j$,;BQ0m[HEH*=S%3+Z=N;gXc8b>@6p_ZUFKe&!g(B%YY(AVWL9cJVb'b8?VUDp_3d'nE3)P9@iILVOPCl@2cN)g3m`!/D&0H%oQfgi(Gh0qRA4(d@Di:_2Z<52$V%mo(bW[$YpPTc;!VK+B6>mg8+9&"3Op0@ZkN#NTW,3&4*h,RsI)seP9#j59p"!'(J=,?"eO.#9M']-[ge5<(u5EogFY@^hqr,'4^Wd17JJg)SY(\DVl^DuH-ATe:sYAM+mU<3rkoCAAZ#j(\GUtGA`9IZL2Ak.hrgNr>$[YTD9#s=57'36;U2'aW;$='WLEuiZ>I&>'`\Pp_la!Dc+^[uBjpq6T)m,pPs?GgeD1"?g&Mu?.#c"hZ.ee3V4D_,1_#fZ,uj7E5H>$nEQCbiT%pfj;:oN++BIEK$aenSWef[C>L9&\D)%RbcP3;6MT&n#&[(h-UZTj['@tH*1%ErBN?+P]2!+hZT\D\a9gckK+s"pbW41rT3\+t.DX:Elj![m*kM!>"H[!=Wlcg)4rk)7>Dmp:Z5AS_>[H*,Z/U[maY"&PcL*%XaIf&(7nH[o7n"^u(;1aUORXBtU^/>kK:SJn[s?L`s5s2rJK$BYZAW4>"/+E]QkZ4Fa!]XDUm]Hm\u[h7TcM&@**#L\2C[F%D?P1Zi/D_8Q]rSP)=#9)&h)Jb@A?koY0OS9!6[o,E;#f]P7'LjfH,t<;DDm?U9$[fnMbs8f.fi-Ajp]j@2Zcar?miGhcOcl:BO>P\EpfpV\RX6*;O2d07&/2]+J9HbDrAn!PEWa5K4_G784PrpKo&$=b&I:i;M\)U36OlKek#be:'-40_N/TDWbnl!D7E2Y\1R#+:1*Fq8Oc+Vkp^+ZddjX[NM3EMf;>k)[i,/#IP'c7,jGLE9d\$=sIa@bFO#"nOm?Di);qV[YjBQ%!k:SHY"JI?)YbD?V`'P$[0ukB[_;1R\eQud3D`mS'-WS5`_u6*t5;k0jpePQ^p6;rbIW#an#JY1BQ5=5K?RSBtYU?bA9pSu!rakr^kP@ISUMfjCeQW')B3M^pA3DIj,fp00Br:q8NTpi=^.^o-9jr"A.k[]3/5I>3\NJ*&sJsc(M0bp1h>D3%2FR%@;^a>PaKWa^<5*Y/O&iE2Qntge\*Y`GrY$jZ]=l)OVRU,([Cd'WbP3&*-':U_59:NTKY&Wcp31!(5Pu.p6AJY@qo[3:gDPC0rE-O,7X-'"qDLE6SWE^_$CK5V!;)db,;2Uk9Q2h.cBNuW[$Rm\-pMaoB]nV;Z_q(MZ4IL;jLY$Z(=`tj,sg_n@-l*"43>6A[h?m'3a+-nH[5I'!JG9VJsbHQY.#[DG'TpjB8g'sI/`T3#t!"[jQJOBg"V7b!%F8hh-RNcE]-R/oX)-h@]J0.##5A+&MqJTnN7I*=+0/:=5+@6d'9U4P7mg^SF;/Nb(qk.2EfS:=&-WWkiWXt=JOG956SN&Nj&cN0[jVepRIVdK3[uW>JIhgMkmQJY\Af-IU*86.n8RPB_X6)tEEqEg]p9gZ%R%P>TK=Npe5%/KG1*0=Tiu5pFX@t?q+OcKHfI))DK(_5Mke5^o.*S,#4H5P7!hk8"SF2im;DOZAbA/m]RW20gC*G'ai2(9sX0/f#ElP^?(G5'X\C'!_S__X!nT!%YnX%GJ>095&L@Ok`dN8LqfgT6I.(*SMYTO`5`cJp^W'C(q+i)=`5C?i64n0@)5B4f548@cLiOFBhmig*KIDHIii%"rR5BZid$'q8OUSu)ADlgj..,4,BQlj^Ng:YG@gIKkFdh@E4ZL)]@HIt@#"YDLL`pIs;_Xc)!SN!m+pS4;lpGDNqF\GkXqnn<@.j?9J@6]fj]/(@")<%?oAC^Z84B$5%&PN`tuS`_(\\kLo[b%eOf,84CjUM-9CZe7u+0/0ttqemsHkm;^s0GFp*kP4:tL53FM3F4NMa:!cod[#=pTV"0`l&q>Te4d2[K10N?aJr0._r!e?;'i0_JfW^\bYTUX85#D@OrmUC!B)ZUeIi^/%qjtK>[CHCG$$]F^'i`O@@;(;@aNW2IO(RC8Om=!IL3R$Z3qo?0rX[V1#M\N+IR:hX#=p6;s_DP=:rLjf=B0jGQ`1?%tJm"b<%lM27?c6D-,ptJDq-cL(bm:KZI33fS%==)fCkqXU#JK?ste%6hsfOaeUTOrl1T9!/Ol#Y109R)^f-fTB;-2_2RZ)TNi#Fh[]LW8J:kTYsqb/JD!A#,:)f%\rb>6B1(N>r)WFpin9E$+,Srl',4=UK1n[jBi.o(7T-!17^e1.,tlX]K-G;%6&DiUK4#3PPBGuW`1=$T?>1n/Z)BpT84[9Y.IJ^Aag0[Sd$!tW\$76u7"<-?-c>9tVLj-HSO!7pC7N"J]_*>2n-ST"`a^Ao,n<]jI0ljTLbn1\:fD!VMi,`%51*M<.kKnT/PL6<#6i0$VS7(cG"M@uV`Q:Qu6-55NgmU1Ks5g#*Qq.aFpL3u[S5s#JPduao6XggDV"6$tdKLe8ZIc;@sagBc-O*R='U<[USkihPIg[0A64Hk;h"DM8;I/"gPi-\8N4Z>]R#8jl2[p=@[oT>jP+,9Th`lh&]Zr^Sk]D$aRWQa(k1rtJ.coph`gf435r280]foW/l%`^sZD']4&9Q^e!RYaMX/kSY#i!kptQr4)3)0.tN?q+Hr>%RbKd&9Wgd)"eZU6uXQXs&UR(\Ut6eL3`j;%I4SVSb(4nP)Q%Jj?*Wb#CAF<"o.=!#s9ZP!'80I'6*N7bWMVqmgkC=3-gAQ4_BFS-^HP<7Y$37HeXQH$hcjq!kV)8rL[5k+t##<*`/Bf,:D#Uk>F+Y3K3*;F.!%s7I,Re/qqZsSF60s1N@1]^lnQ".,VqAS]RQ>38NRHPN[rh7a2qJltK"te4k!HpQ.8s2eR_tt0I*%-!f>C\q?%N;%h>elEUH[^TXQ2Jd>tkaAmr[`e4rqKq'JBPrl93,&Z,.QuU/qD=6XDp205u8`I\W_KW3I&l*X#nuTEJX.LLU<@fTKBW]M+`D7iLY*>O!oG*@]FO=M+D)Y.EemK%l8]2l%+_Z/C%.T77Y_gi;-UYN>"ec1T]Y2sAtYhj.LKTVrD?pBh>JX;2Z<)mu+S79'4Bi@4Un@/Qptb26XYC7a+Fl7=&baF2N`-U2hAf;1L?h.,=a&Lo$.UbE9%#]BD"j"At*4oO?O]t:J)$*'XX,2(jX;8b@!`?RoJUpO5`1"iR8aDH^n@72>%kW%F*ZpV&:%FJ8!hKf:%Vfi']Yp&%7KD"[.O7Yb7F4gAt?,SX:jUOmfhF-kC1jUJYLQnRF\tV@+9sSQqI*Y/oo)gf53!#-K)4SOKaFU#J,sN&n'_+#=-u"a:^aVR3EFfX'j7,:hhd;a$[1(V.bf@eCP86D[*uMU@MDTeWrc(QY-LJ:R#-ClEj6[jSq#;<$j973g7e,4JO_!?nh)=Memf!a+q:n3.hLA^s(+CkYl]FsI%d!9,W0KJAm?I\D7!tUUl>67f>?#T;?jVM4mn[Ct?g1A%i28@2Hh_LZnT"H>o5^;jT#\M-$Gq,?qSj)'kfHG!L[?hEG>haW41X5//-uM9%"M:O+(@8<\\;GR/m(RV,48pre3A$^\cTZ#n7h$;Z7$kC>C>f(*T3;"@<+09F"3^hdj*I2g19AeQM"V:gL+OmP:'8cXRnKUEZQ+Lj#4*Y;ugnYF;H$qZo37hoj3ld##ns'`t>Z1m/H)b/+n6'k8+jE)?;>=Hg],6&hNC_-fRL,J<&G]F3?6Ad\A?!WDkUBEm\lkt_X3LRY_u,Oj5RE6rS-JA.09W]2a"N&Oi>e.0N3lT^-q_01;Tr?qf%R@p>-8?O#f*u"=KBs$HP:ZBe1o8-;*6+W/@(a:7p2o-Gb&d$Mr/f$k_Jm8JudL:p_KHc[\NX-@3$j6_^q.U3Z'dNpF9\C&?EZ(Rp:V*M-&.D&S<,@(#6mf8L(bt*bp&Ak-hn7bal,:)7U9(5ONR#XHQDP-DOD\r8_h!RnK.2Ie>O)ecS_9,mcNH.rL>3$OaCT>SS2\"WHnH4BJbcj:.@&!dAn]o\cbopX3/WTnfSuM>\1%>K&:mA;8dF#gWjoq0`j?hpOc8ENHOo*-`SQt,9pXD?s=$Wr\en7T`<*PlgT[0lNcT(0n<^[PQtsfUGAf,Je+jl=CB!^D9usTDEh:-hLu8o#slg+(hFDUpm:!$#pj>L[U?.LVEHm/+PGOp!f'/;gDP,-6Y,G(T6/E\FPmJRX'FGN@SAT+@jg@6M0rYM6L%]r-hl?B3f/ct5B'\N"j1C:KbiWk;a;A'U07d7XN,Ve8Nm;4+I[IU1f(Ygt51PV#19qBV*hNAt[lBd(C@*IJ9P^A@an)=+J\[>?PQehK3Dr8!NaWbb9G(DnIU/R4GB*&C/Y&ONeG9:X*"!&+&MDkhs`(`_fQkt>o:!)>I5B0cq7;Cp44(1[FORLC4U.7LH&87!cs&2UAX&;!Zqt?(fdq1]YPJ]da%h<8<_DPL`4teemqoI0UK$6C3V(;a(K"@hD#pFdCOf0ND'h3\f**c8!]!q4g_pU)W5K&oe)s%s!bhU@8rd,UP?+04b?"t9&T=EHp@;ioP3d*nA4d=k$`SGa]W;c551G450DtQk.7B]\%j])Ut4DsIgiCR,+T&QK5s4HaHp2o`6hb<>3"=BNK^*gnWoh!_U>YubUVC-YApJi2RN@&=5UikYmY0^Z'qc%[.G,Wge:E@oJIIU[c7/4BjOu721^,fq4Zbjdk^FD*@>u;aRLSQ,WA[t5FYIQdMO3Haf8Qu-OPH9WY*GULs9GaQs@)?6?e.E7\;m`ICed%)1+S5,L&kh?L=7,&IrY0Q5e+*Nf^#[*A1Ss)/'N]P$D\$_`@gPaRN'=_J47J=&_lAKT!e]U_UBV@>[@5_c8"#i@_;PZ.Qeq-LLIT.nS12.&_-N'nM%Me.dG%MD?>#a'jmaj?N9OhWQf;ApD#NpI(Y8g)iGfBKBcC5Ca#WUC#LQeopi_nNG;7==KB$$R6g.>.V+F(M4M&9s@U=o7dO4R@9G'-\qZL^$rLkKh@-?e)R*`DXb[R8j^&EFqI>GMnO8_'l7R/;pa#fP9ROt9hof>T*-5hXSSEYkrb5f%!QCp-`eFLYDhQVV<.LpP&s;./,%R@aQfR'lp)1o_3r^*e7E21_\XV$='B5f,j:[%hM/uQ;&rpjG@+=rMDJXnQrDL5[-3$-9c8g:&u4(J]5P66G+g?@Xupr4"!a,_c?74QLKq,>l^+'rc/PIP5jq-94*lJ3o>%*1H3&HaT""2QtE"+uMER[OJ62#hee;($X'k%48k;c<7''FP8$-dffmN`8Z#ck)C#2g'0!",K+0](oM5^)4Cd!7\Uo&gX)clS=ia[r:S:@!#V9\crJni`hQ$Xj*oc4JSlI8MCI:n(I2+Oa&8b4K54[aMh5rj?uFe^e1>M44\331W\0[061O$9JrZP%!c"mYHro'R,6U[N50`ZJs-m+@gdS,W#B6?CDh>$^L*n#CHthVUeP&hPJ]!M_=?e&+TVeU#M(pcS4N%tur,aq>gWY[rLL>gL8U.=)hH9V)a]81>ZpSKs_$H]Lo+3j-&IG0Dag[X3:27UpnZstF?Rf,8OVPskoHOngED)T,kOH$5WGCI%Qre:BPEQEZJ1C_@$*JTfUpdYHHmZVu"1I,pV(<";0@+,0LAL(eNEsV5Ip^&Vnk[dZ%KS_nKQmumP885@1r;1cP(&)>:3Na$e()BUfT\1nD@D&d#bF&8['J$]433b:ufg5ip9Hnp/3lA&!$7RoNHm&BBns"gj6,S#G!I+R=.4'g/^XDQC8L8pAhEhlAfPqDJ"^2J-pZUOH#/#^!=MQkb#:>5P5;9WWJZH,(a;Z.E##uGL]`$+SGoF"!oB%[9IM.o-:BI\"*X">q2^&jd4&SVKbgS/g-Dh:3OJdRo?KjgI`RD+6grJB/.U65V0c.--PAd(!H/mN8pBl^k!QA))%rF-Aa1;(C$@F#A,E(R[Nm"$+G-1,BocbhQUW(BEeNP3)lUqhGcH6<7_S*Yo]L$K`k%9u7Rn-+P*hlSY,6KAKmOT,::9o7U\F4:8RN&1$';`IG_?8m40STf:<)F9qSn8Ilq+3.>bsHS[W)Lj^@-0l##^BgG4Lt;'kiqIj_d[(df313"o\X#B[i2=,lE?0:`uO&WS4SefP<4f7$60r+7C@*W@?%#f3;$QXD_=`*EZX[4eP"#/$_hKSgk+jboFE#u/.kPmS[(#'1CjZIK0V,\cA?ZN%HA4qp(U:88tn[c-[OpPM+s9K-jP!=3TO0sS`Qg%JMf@oZ[XTaM'lFo,XOYX7s\uhUS2mWS!I@:8"Et+lIjE.K7#T#c3\(A&9f%'Qc+V<-BEH?q"FEP-eYq/mb,&'PjVdm,_74IM=t5,Gd5)3\OqW3Bc'3,hIYe?9%n13W0TN>68TY5^Qf"he2W88U#0Jn!8IoRM@q&!YXSaSl?3MFBos6oGWRY1b^5;/L`D&1_?B+s#fP9`%8Q!FA/q,gLp#omDA,u1HCB\B*8Pjp,F-=l-F](f9VU3t\[&WeUW?R@B+;>+l@Wtri7EfGGbY;^h^^Bj)F.ji*F3cig/85>1,"%#n'$>si@9s'##+Qp):GWK9S6o[0hg5W,6@9g@53_mAJ%aZVThV>KXF,Z5aZU&PE`5o7+A#lK.%E(9>pUDta/?nTeYm:mu%S1-/fo]A@^sSb7k%JSMa@PpaYHR*`;1:.^dhbK0&Vh2s]ChJ.P3te7Q-f*[3Ltc@k0SKcM.>nu@r4"e:[r.,T.`mehH\%<45E&Y2k\-e0)@lJBc;).#\(G45F&siMUFS(oiWpA'SV9M[)!u0$j(V^<8g.TU$-d(+f2!.^jGs'8"ih@*8-g//Mgk#@Vk4>Tr]@mG8ZQ\"dic#TJ$r'RBSOr;K<&r3%XiLd.8.#Q\:tP!0d]e3BQ=8-<&m#b_p'oq8H`L*Zj>q2*R;r]Ho&WsU0Kg=LiG7J1R"=R$Tqok'in:T6O;oLV)_gOE.%rN^_6\cd"N/S,n8&XALFj4P>iP!BF<1[7O?1>?'[^FH6?%X;@Ilog0o.]b2*"GBK(.:6R-UPbjgD[dRS.]:%O?fH:=]l-_7s])&0W*'7Y$Qb&_5fMNpquVUSq52K@UHaSnHgM3ic`o*BM1qgm!OfEC"[TS1#pO@Ap1?e$$o4M#99p[^>rcG@DMu<$?-QMiAj%_&>4gAmNP]gJ@rI]=\a`F+XbT9c%+gU#@op"aJfT%q,X'qE\a#[+Tt)>&:a^D>k.5t^iUm0N"63IjHXC7@,]CP1FNsc-0M5H?aThfeA:(reh!s"7f5=pDI\*,,I3X0WS1bMrgk^S\6:Csf-M\Cg;IC\6J]ECE83i,7kB^@BKI*17`aKum=DHbFEK2"D+etd;dEi]Q#4"#%hb)*6h7`BnCf'4KA(>LRDc;M7CotPcgs?:`0`jk3ILbUb9A'HToCp^&bLWR(cBY\T3cREP>shfH9boo4Ddj9tg`DAG0r@'(Eq#%C"WO!NG9!&3"I3T$-%gNC@Gl%el5gs*K`:fK^r!;0keZXX!7f6D.e'&+%T):.$MP8B<6iU"^AlKb&gZd3A`6IBfn#bO)XF%V$i!V@n\=N.E2T,_6e`CP@>42tGAG'Ktga!:d:!40ucF*#oJ#E+EVTO[1l[ltY4e(;6aFs-`chfUVq]GR;>u`W1PIL'p.PA]2A#e)T_tPu%j7TgX45*:HVT.q%%f@Tk?C2<&9eW'*!W0<9Hl_\c*JI`d7TfdY'[n]G(DD:?KdE.%.>[Gi"9d:1LVF^Q^!c33JnGGYCaUThIL'?s:YFbX?n3@fXM?Po.Dn#/Hk^_%goS$Gf9!;L"D2(F0oX)I%eYr\T.O\HlN[O=/.:_K'#;INe+9hD]5F#]LMAb/#VhE-!aiinQMej_.uIY)d&kKCc5!EZ*fK.KI!E=-*Z/L%JYUp[\=e[31]&"lkm/3!nV&K^K].Ob-JdQlgEH*:j!_L?i.fU125(chu5dU"%cU.E+^F=\BK!X)1FbTM@e8K1V;Gho9mGCPK;?'7Lh^/u'Eko5>rfE_%897[A?BOVF5/nAQbi,Zn6r.AECmiig?KI9XeOOVWI6/MhQM=@rV/Y]3YYTjWM5[boPghmC+-I?KfK(>%1YGbIH/4.>0"]LR\(a8"mo@d^9'-qW*#XT,:YmE[Ar+GMior5LW."R2L(r".UqYdu')[TC4%B'>]#pPN\8I7K*[9>(Me4N$4,Y4CD;FEF:+@uj7:f9SN!^LTg8Z>ui^lI!^7"E=Gmk0+.:*`m0(tLAFV@-#5@?>djT3iRRMNV:]\mCU%Z%doEU7NP/m#'1I*Tn@jLl`_]0N/<,>X6VM5W'atD$a[f]>&fLn)Qb?!^Zr#J>eS>heN`U/-hmsK?jsTEuglul[E6UEU\!`Y`_r(Z9XC#*UjC;b(IM#4(au#+qA>TEa[*M[hZNG1Nlr*@g7m%"r!T3lU_T5R[jBhIQ3p_D&(`5*sh*bGMI8s-R:G=+.IIn+^$->$^-,331]&\ILgH_p'=$[+no-F/*@K7+B1sb"Gj3GVn>SO?M.%hL9t'`?[]!HDl0CF5TiNc&VNZfla2;]0H'rC^\*USA067j^Gr`/)]_a,pUp2=TFVD%*R&u#,*F\b&h&11)Oq:4[[29eKVUu(J6%5c5r(<\/.T,JbBW'd-p\X;)SHaWfm0s*YnS[WCYb^K3/tqpcG;u8r(cJIqrDQEaXFuKF!\_JWfG5(i"RE;,Ca%A`b!*It+,"WE;+sFg7pg,VmlTgRrmC,_D_+4o,AINp^fSBSZ'HF*g)HGJ!Tu^/*Prpib#>Op?(pH;9'l?b2Aj1i.s_*AfX_8?]"(V)/]V6ae"@PEo9VG/B8:3KR-5Lqhe=8;K^uK`Jm*1BsSVpq(0\59`K]n.>^)&VO9k7$&25Yn&BF?'eFi&kBMDK"db.:@X1E,s)qQMa4^mHP\g3_2g.S)7&L[G];ql'$79CG1KQ%MlsnN0MO.LTp]=7bfs4?+<:^-Z)6ZDt[tOt\)569p)&+:O'W"V4pX.'\SI2t*q:r!?:Fh.#o30ns>qE6lB8n2I=dlSa:Qk;uWg1d@:O2]8Zah3r$GAoUA8S5..K^_m:scm)4LLLOF;f_mGk.EE=2A3h!$*(0fl@RJ9?FWRuB6Uom=#de`s>:E[/NmhF,=A_AdLKTQ?4+873?&/:["8`3'_Q%q[@"g)$]\ctLk-@HHi0+mE+-pQ[XLdbZYNo90heLP9;6B[K8kQXuF)A'X>.I^/=5R?aOILH&#:'3''M"V0itp=[h1T0=N[7#DWPKcl?6t/]5Q;.[VE;)m8@cRU3e_oU[1]`l7U"Y!e!Z,KSXWqDlJ-YenY9rAJ%dBQq!!Wm#@lP^mnP3g[4Y:/X6Gn.C09HLUXn(,YffT[8^/'Dn(e8Qln2n(;@+kL'MO"Nt:MT*Y$[Q=t[A+CO/n)sc]FUK0m$8pC$68fCl']FI=kITejDpu&S=\DG^&eNQpd$q$R43K$!)W8_tL9mc(I\@X[8:]'B7gIDM3L_EpgM+gM4/^>F-;Gd!0j/uj5M+\bDN,^c)"U/?NYNX8VDjS]+:'apZ%c9XFjf(%sc_E5[*s&a"d!Co@j,_Y<$d/bUfNC##K4Q=a6`FWWAj>,@r-JGN"SH]nQuO.rS5Yl\k#2cAHpa!7r$rJPUeu5fZiX"(A#+n51os,70gXH?ikc"hYZ2l(7,TmYWLdEb\e/%:t0=ehO[hju`8^QZCi1-$R"1gTM_]Y`nemP6u98NJ)fN*9#NYl1S1r:.4I(,eD^t2ghKtH=N"=0M?M&V$D:g+efJ`K$tdGXSstNi@)2l9LJr7=S8&40pXe/RH"qCQC&m6)'%,@740eQnp+f;QM%MXh^$\2ui6San-CAmlqDY/nVj>!$FkGM99T(*kR7"4&=FnBtJsuQ!iO\'q65'!5+hMu"_RVt2@9Oh;NMI9lDQ"tNaZ^qBQ=EJo56f8"bN^M-Nm8Z5:[[Q?6Z6H6fWf>-uURJ@_o9jN[-nB)5iVE[aubLY3$ut`I.6@a-@Lipa.`&OCSL#^UH]\[M?XM@.-JF3]_7Wlc6L\"8O,a'K#&k52X<_,\MgSF3-=7+"dGa+B7dHoJC"$hT%CGm0]$d908,hFb4fff2&d+L;P`ktK+6,R&Z+&5=Y0IC4fq[&\#C!t"18<'VkPiD8p=u#I=`eE&N9Uke*kKGjpJ9(-?Fo0T[Y0Ai:l`h]I+-.2815R3<8HPo!#"_7n-][%srtL5g+J%_We5(h$Ic/\dS8hjX<<5@0QX7pa2(Bl&;.Pf+b>6gY]GVbOgD;BT)jcQ8\lUajoD6*kiN3R@D]7`>Eq"p.?9>XVK(gFRY,<#h9MRnNO*+Qg?sr0aT`n5"td[3/Qr-K>$rrlkHL#HNi17b(q!?:lje#sC>2WG[3LWt_Ea7rE_)\dr(jX:fZBQ!oYaHaOTM)kLtaijH#s&L/nW$+RUCgS.O69m(4!p.#ognB5bF(H25q8YJE>g'MMKOY)9oJ!uVYd+b*:GNG0#Xs@enXZ:KFPhB#QIZ0a(ASX`7a<@7(rd`gn1%p6`9C7B#Jfh[M(s+9Q5`f^N,7sF?eJ:T@*ifpdhkU@AV4LA&`8H>@S-m&Fl/0Hgn.jhbG_IK&\uFRD]0e.on6XfmVTiqc3c:p@>ar2lV#B;fJm=UOV$]37#E&Zi*oY-#,rjS)O24u'Df#\>'J"I"]pmh`EV?.4Z6kbg5Tn(W7>=_5ojLfg@-^)lS>l[.:Bh&foI?OYZ,"fP;cpakN?=af>8e6$^6Ab9CI9Y'T$s0&@f9>/LZC%i6'&U:p%PLl=./`qC'4*Kh\(#Ak)f"'jQW0hfUkB#br^2(&NFJf7[+PT+p];%b^p#7U\;(i%B1[tSuOHG_/'`\*$5J.1Ii8t"@"A;l7#qlC;GWP0)5D;\c]rImE$jao>*`T8[0Zl3b!a9Oaln60tU/.TnK@k)/EGi6T\Jf9SPU`@t+\4N4Q4qlIH41Y\n"racR^Km7^H>4Z*qP=&ZK31l@hJ&Hd$ckljCcgEA/^)OdBeG1YQn>7=0Nn\_S$j7HS#M&K&As_-qAR(\:@9#=rZ4AL$V/&ESVg$q(59f3"G@"H!:ij)%@tN;=q1d_$pujo*PoCm=a\q*/CLE0Q-scfBoVE4[FBik65E4jQ8j<83rV6%>^Rb)`1c%XiC/E0]f*t6bD_27d0b*/^(O0f2H<(eYmD]p+[H,97O`A1LE9IEE8UkD(;3l/\qSG!KIgM*bI6`GG6J2==[M)G&2Zp+m#Z9r:.EueW,DKBkG`G]!6::!"qtr^rZ;i,#`t!u8AI"6=m%>DE:`pLf[7ep)qm@rqOhf$Qurt1ICNZcDD5g=r<(UO!J&08O]4s:V1#JsC2;B5:)U3KRP+CZ__(n.:Z>34>Lo%-$0YW#m+L`<@NfP7F_8T9coCb@m6X-!p,l8Nr$JR`XX0pAZ*_Tj@'WcWD&.&fDOD]E`AJp_"BnuC9iR+HfWr>ERk]_2<68WNAi!@Zc'ouT!`5@bEan51$Q"^^Y13o[P"1N6TV.Z)/W[/==V;J!=QmP;-L7Kj"S@g#6+r_J,7!FgNJoQ&&-bj>"YhE<&'fMqUbFm&7@G`"X<\Zm$&3qcWajl3+@cr@LPFD`fl6$H+Tq\.]&;?\crK:@5U'Faib\?+5\iIZ*a=->I/4+G#qk/LK-!8Hkk_<+_7@9hC]4X6@hc#7Ceoo&\n\]_Ztt>D:=Rk/!!gfYM*La>=3Ebga7A"#mG/L0E'93<)e!\KLPMTuZFEa.pQ%dG_k)?@!F;?_jssa?EjZC%*\XZ+ArXboUK$NUTm+n+:Im`h+3%p1>g%D.XWuTR8B<"p8CG<$en1+DBc'`2hOPMjE:8lo;=)\iZEBRFY`8c]T9^;VR,ptX:@uAg;Dij0V_<\)c>rn>"Tm$;8"rT"!-N7rQFcpomPX>8j46l?/LTcLr=1r(DS!(S406:BCOTHa50t=nJiAq%(t1LNO]pRRj=6DOb?1q1W_S."?(?e9e:#NVB7SNBa*Y29pBBA`s9U!(=k&0KAY$sCmtioZ8*]Sf<+>qI:E"0$VcQi)Pp&Y&H!9&d8QAoGs"^&Y<6^^2]NNOHdcLmY5QZKX8I]eAmqdF@G*=<3;6VpQS*>UlNU&][oAfO"fVe:UTu$IdYj-Z$Hd@9d1EmA8eQfB?r2\c0d)\q_gsQcm&TNKYT1Bn(`-+(8NkM7I#XT*S%a4e&Cgc+FHlVfU?k&*o!iEuHU1=hH![H\ie$ki$UBGmZV0cbR,15sr+?!M^:I?c@FS5hX$2fi]9%jY2BWU&J.#N==WkY!=CI[eFMMHBe2`SI\pOeqcCi&T21oHuUgL&]WDUL@"o2BcA%@\RS8`_O5WbY$fXi<9^u;PN2OUo,]8TU^+V]RGeAgFfg;X_:6oQ+,X%2_p9fTtoRm$P?&qOI-%^U@dZsth@eJX698i5H"P;ts3^s:]7'[:6fp;g2W;;*!jjqYLb>%EM(D]F8K/R;Mc6Z$AYV3utAR?)a'i>YYZNajkEF/3c:Dl)UrGtT.CnHC1&iKbmg@&>-uMnOMQqu@O!a)q-l`;-IS#5i*1e\B(MU@1l@0[HdLkI%c&C)IJ6Ji#/1!`W,)GJ1O_n\]5F<-r[kIjN+*4)glcYB;n5E*72'D6Z1=ZVJ.kHU'CdqRQ;o9k4BW0R^sW1NRqn2leWDn:aACT\p--Og0hX;s=;&(!VmGi'/2rGB`4(+]l&3Z,8/B\YM)#U1/<@l"tTh.MUlh]6$*.56r/gcK'dQLYD(R,D(V?)&<-r?k'M4Q8[;T^5tVHo0WAGLS3Uq*=J;l4/GHh+2;W!ShR>la1[ZUN$e"e)hGKh$jgj\NGU^P_q2jR2AsQ0fiNNRr;_k`*VX:g.#21i%YXS1bOC^,9W`c%rn!rf2HT<.W16eL='-T-&O$mZEW%Qe=8C"D'm,]EH)%kK[#0gPpFXMEBV36X6==Gg,2#3N3p#g@T=d87PO!MTbJ[WEDr%%MB6hp850As-k7_=dZcQL1Ot$_LSYG3"6c,iYuRZKBW7%,gs8?gig(e1NfVTT5?b5$ApeP]_KqQ^]p^uH<+&7#iRX4+&NHJK4ET]1Z]"".gLB3!Ai?DHo*7Zr8I!2i8ePu"6LJ25#'%jqRB);>=FQ+2fq94&)4.gYOVISJ@kR)D2*WqNYm5iJL>!o1#:Q7BQq>;<7>i,m_ie;ABsMR9AJ5bpL90[u\otTT[dl1lXh]%BZk&jKV"&QQ%bXCN71!BR2XJH&(D,,VUJ4UTZP?DdbfJLkBbE%$/Ucf:[DPJUdE=N0XM-h-1POMPD[t*p1GNdD[GAiB'P5(%E>Zjdc`_a;gtS"2c)sLn__2^fVKC4^21]`(+]_Z&C9n*crPb+Oc*J:Q8KAg1%NM4`(q4&8INp@oG0si2'CN2(Y,2"8tK72rCKn1,->Q8i#R54]L;A:hf78t?U61Jk%\kbWu",m'dUEADXdpMLC4cs#Pb.!cpbT0T@>bD]K/l=Op&d@>4s*nX$D@SNF^5mB0!ad(uoBZH)"^qEr])*$'.ON*Ci>YIjMPACW@&p$dTZ8NIMW2Z4#L7X8oU!F`n<[bkV5o/Q@8W'!,)i>j)*(?Z.!bc?f=TdSI8tt,$%T&PcLkq>%5s0.N:PDJ$@07@+;Dhil;=;L72?VH4@9VWZ%;!LG':4KBWE*#%@,N.uCbZVMQ7g>c7AeHP6:muT)bq97YAKdKd&*R1`%qL@@@a81as54A]'B8WD0;Wt<.Iq8A]4[X:E+o5&n9r-%WQ1M43q3@`dt?P`56B[@],e^U5"HR1N3oNr@(`\XHhU0Kabh1BB?pQn!hT^aCU0G)Sn8Ud2hh7[;;0K`IT738Z%]___MN0h5uE^(gth/qMdbAoc%EGNA/mbDMaIQKH]:)+e:dF;@m>TjGfFm,C;3\IOq6cY>L/hb[_U7;%:7C/-3I0Jg23Hb>X0L=Ae=kE:2u/%>+nH+)HbjP0,B/Ct9%Cd"SWb4<[3"LXXA+\CBsudF+NN1Ia;K5eR&(M_Qtd1q7>PSBUs=]ooU&k0qbWV)>S3..>20tW,^)kOCNMG'TQ&&[9O7rI#fLd:,*GYKDG\FZ%Vg78_uoc=_8B8ofJ(.2)Q&HCD7'Vf:8jY=_;6F_1h;e^DnPJ?$?!=b1gm7J0UW=nnQ"%60!bDOM5oP&E1n\"$`3JFAELE?fd9CM';6a'Oe*GlV;g6Ki?B[nFbk*QVHFo/`!n]siJ',DS!H(Wl)jEhOs,?9WRn=)bnUJj[\5c1)*BIIM%1];fi]"M*t$^A;j#L"T9]^uR(4V0'Y]#rkhNfs<(*s)lejHegmP-URFnY4$aO2U*RG([glg;LdNcG=rV%"o-Uju_s"n/9+!+0EK6&1iIAP=#L:l6)60#7R]+D(e71l`&2BVkdD&]G7l.!=9%pfdH4Z2bM*1OO+jNNV#7)ei^";rpQ[6(FXt^cA-e#)'5g_"S']2XSs?<1I-C,arY7RjOg=%V*J8Yqn1hd4ur>6Z?OgQubUhOMGC=88-^J&eYdok&;GA^b?Y.PB4CdOO_apPj*9`"bJdPOHNF_#3.>9mPqSCN!#iKO:JfHYh:@k.Z(C.`<0M`5dVP"1J6AqoccW'8?$P"EWGn"Lo,U=M$YHa5`em.#jj;_;gPIN+BX3UaBK2?.q[&`6A`(*3+DWVPS19a,`P\'@fe?A;CQRI$:a+dYbFESo?BPDFCjeM]SuZ<+D^L@R1-k%?NkZ<&Tu0U7.?*PJK[=%#dsLm6_0[ih[&_6l(Doi(oq864/*;$7G@LaB_.h7bF)3.j_'.b'",\2`*!(nKE.9,rien3Ecr-\<5)nLXjHlDnaicHLjfZjra4,T*1p$'\S`e8d[i,t\a=r5P7fl3g1-gsSA[aPB\][IFZF__NQBGs774:MLl-:Aq?%d:^REo'&.>nVJ=,PRp-SAfWe-C]2g%d@Ks(A,XD[5P`M"QKlqt8$O>iSJ6(Y.QmHea=B\OmOpuukc3S:J$/l'PSWG*h+\.?^p06FE>i[:iKTUu$^eJUG"KJ\Z58Po@/qpQV0t-k:bG*VN>Uf>D.T\=OLWif\.@HcaOF6piN.]`G\VEbG>?$<9^LPhnp@(OO>;"(s/']N-&qe<]I/q;4u*fVCHApXTm#Z72aLKg>mm+YfDg:`f5H5;;;hD7_m"QGjdAFGG;q=j^'uO;SoB`JVYGqRr,NCihK$4rSo>N*8c2/\T`."DWq*B.NTFA6_'*d!YL(jLAKIRYVe(l"3tTW:>NAW5SJF'?sgna*;ejH*KL9Gn8)&j$leB?)'DIeF_"_lsuWD[17H&Wc&K40=?iuj(b@!-@o(60=W:#clhEQ9If_M!SrJhX#TMfmZ4mR'h6Ht[/eJ$@=n>VMgSO?#\S?+Z/_!=1?3#mgrql9m`^Ys,$R.@Ck4#<++CF,K<26>EAec@kj_Cg>c(^u%:^G;no[+&WN5L?W`c(Mci:D&C>b"AU&I:rrim@p7HaHt[7=%?3hN%L[1"4C`\*@b(p#K^DW)bKECblDnp+<+4UI%rC9+NJu/VRP&93)i0BK\C4M].[JA@B6>QV9'+9/F[iUWTVGB5S/umPMpaX4]bo1Bk1Y^3&eQ@oJ_g&4bHn0>QY-de\nL(qq]V9@@h$'DcJ'7QCpql!EL)_R%ZNNLMAgpYlAoOB\[*l/[$6F6=<3l]jLcEi*"k3KQ=7?XbqR-jCOE7*5*G8B)Vdb)YZW#:5\=@2VQ5Rq41\:ARZgurU_)?Y6cZ^*#iC^?Hs6'S=dG?:Ab5@2%u[;hsQBU%9&,d`f3Y/T,,S[Vh,4P,S*GdMKWN"H\EUhiHB*Adj8(.3bjG#XT)Z+V0(4k@8I=H0>7EX-^m-=`!H"6nXRY&4mS0<)`Y^W?%@(0N5LV-m_YO3`gWr&Jbtn[W[F'kC_Bo_/)o*F0I29i7&4s%_c$Sa:T$NM9FI=kOP??8gU-$7M^i4EsocgOQ$o7l"qRhKS]SucN2)MjU9o%,ib`RNUj@q_9bQu'cEZ@d>4N;kcYq=?G_$s/eDG$W3>Lc/[#tVX[[UuFoN"4..d7Y@?7Qo`Mg)#RAcX`&Q_%1*>"Kr:L2=K?fKA>[%4!m(F0kna/B@75!%846u[)T`;oe(NBumG4g:P*N@1Z;!3Zh/6t1VV3K$,?&H99Tp*$>=P)oTP:]pQ'G9(DH4Sg>0T^p]#Mmh'5I=,G,@kIaXpu,'iF>]TkjBA?%%'*A6GeK1q&TGCMMNW7BPgd&diAfV3p"_kFO.oUk2WM/Z?'/WF\Y.412*EWgTZ8B!jIo8m/3+j/\`JZ5Y@&b>lZ`7BXn`?/I2+L$rX+k$Nq-6e%R_ul0mY,[6S[=2n1!&,Z!fHS#V$UWQaWL>>,`g&-F;sgWfC:Z[T[^0);eu6$dMt=(3/Qodga:VZBFlM.WN)nI9c)maF7ApCuAjj]9fI5^[fb"?Ak&5l83r8K?,`9MW@>l#:g$#k[ShS6sR+B^b)q_c;PHQcO8%PYiot1Wn]cP%D".;#0!6SS*eMdK6UO@lNKBd2/QPB_'3:D:Bco<,a^("p?M3.hWab">W6b+O[")_s"7@n3bVG2_mDGKe;+_Jn\JFB:RBT!Q5U?6'4"),RiZt9sMY.:#]aC;u6h7HSTTFHNV$LA2aZZS&C?B0NbP.cr"+(9bWun?UkVi@jbeK,'o:R>7H[@p1R[8MMiK!#Ya,1"`=L-e>#QhJl%+D'aFX]qj1PKe*Va=")Ce#i"D!;F@V@c=oe0J.ep*$d3GMrhcKhhl=R],iEn$Y;F&B6kkuE1AJ"nun2;$q#nXKN$W%s%iK0#oOfZ>U0gg\\48QWr7d6?7ho+e'iAOXU'Q<6(cC*N,6n?6Vu;U#+2dF=r>+5UAKdR4EkIXRaX`W`WEuV2+Ck=!O7cV[B92U`5\.(n1-DsBTU[9s&oHXGV4?gf/ZK1\\WX?8^RMajTTg`1+#h[;nt1;OX_Tdj#GBUZFk2L>?d+IaWuAWG`*&i`)H/bpmT*@:@LN2#Z7!tV(;ei\F3,:Q_dB3#I$@a;#+EHpCU9sPRf8R<8.q%0u)(V!pdqRoNs1gV1*UT"'cO.R*LRoiG;f>;r6E1.+g'nV/"hJmrCK-9MT/GRFiJmDMt"([Q4;EqYrr:JD[=hL>TQ[BcgN4AP-R)s5DT`n`UK1'*'mk,jYI2]qf.2&o0/m%mnAVg\XQ+](EnK"u\U8a=lqN7&^oEmj>7h+H8?Bj_,;jO@!p[5]d0q\,0@jq_S2d1d;TeFf^^#T5g1ZW.eLAX@(ghe&0<:uQ:gIKcI06Fc/`j$;gQcQ'@![;]4-Y^uX+<#83LL!OeCbT=.#@<3oo4h3#,Vc;&>'cA5j+@+)c1oP7p[?'mj>q2eS$>G60u5i(p$k2XTAL.0aN%5%Vt4mROP`G88>%F'P?UjA1&L$nVMXi<92B<-L^2p[)f_$8D':0#NC[QYEEREhNo6%;,cE8:XMjd?O^rqrC#gnQ/u&=[5(TpC?3Z-mZSnEFNf7bY[_[O8#1@,J"h&VI,2ZmaZ:J!/p:"r$Y/u4I+fqidlbVqMKPfDHG_e'?`5E(GOfg!7,VBhrnh/?>],dH5,%"KFcd/."cQZ'G[_6478L,REIs59n9d>,YC4eki/p'qWp?,s%b6\=XKMipJRpB=h]um1?e6<\^ZrI6k+p+io>q:l/saY?STm]=$3Dem7(AH03p];3k-4hHS6L$^K.N;bE7>.PcYaa&iEY+>mgf."h0n-lW_CE;G?=gd28C[,t@!;?XhVENE7^pS[Dh+]pjInlmcW!h_03<>cLG$9hi"#"O26:\"kk8r9US#eJlLXbW@XBW@CGRehOC]'4]*V(1U1Z0LYWA]1Oe[5V.c7'S'"6$s\s!<,iRn6DS(Y&;-N`BOS]Qie;=kVX8:@YX&A(!K)D"]:eG.^=_,^M=b!TC1b93&2+'QLepp85_d2Xd'N'2q39EOn"&2H6,fe0283<&;M0ZJ,8coGIeo'7)mo5QP9slU!->N$=7\MZ[n8LZ+7sj)D!"SHS1=RM(Df@3Hm_ORro=-SYP$`2gOeFm16Ur]Q3tU5]^hME@'f+@ZtX2cFCi:TiSpk+aq9-jYn<%YgWHF;23-5[9rD3W(r<$u?*C9\]UYa2AbZt3#OXS>JE@LS3,$k\=0Ah67Bg?mKC`9aYs@IHlS[d"A&64Up-uZmOGele1D6KdKke1]$VZ6[Rh,)_mg/hl'WV(D`IkO_k9Fep_Q*;m;:Gh-B&lLCp#'6Wh?G0XjWSXoh*W$T/>;F(Il6Se0s*kB-EZb[inC6"I1G^,g@:o4-#"5AZ9q^n3;-e!'W.1?N:uY"*+GdkCT8?6pNtY:f7m+`/5lB8Ei0K._J3RBL(c*gi.QkYZ)7R7hS-)4@%-+6@n3<:Z1Zrs/(`fe**m%&iEbQ4lqlhJ^D1m3VQjXcO%dopJ;Y![ao]!";\J">cj2RpQ.1!r0[#.C$_/@\.odgqs"&18R_9l-b-!LG]>SC^(@n&00,Lf@a+giR/2#s]s7::&$onqu^8>L$@JK!!4jUs;1JW(5D^"0`YXB;a29ij/U8OcFGXN6JmRp.S++gD',"Ci!g/8@"OEjmX^k>pG&2?:kK`YF2K,-=qQR-$phiulp?Iop[n)`7OWU+EUWdgd$5"DeSidieN,jA]mP0kb;eN<=e9k'H(k=n$nFDPM8SfWL^c[)H$[f.k-Re'PV9jk(lUt1N.;VG&aLrQ8C->?)]^+LZR+./,q[]qE_7$LTSD@K^l[dhmg>@DC.Y.'GGF*+NeR_2X*Xg]L5DVI)#JX)?q-rPR-7:6+"'kAH*Vqg(/T.$e9u"HX(UO>p'rrD#5`2sD/$37#tDID.M`coGu10t%L4P@B$fr\N6Ao;H;.d#IC.09hL9%G9i3.TLHKG"E5\8#4TgJiN>S-_TBQ9kf'd1VVp[1biX\Hj<\!4\7I$o%u@5hqba%JOi`3YW-V%:_j75R="qCle*CKOW/g&XrkS'6J97RYX/QJ\hGeQpP3]pO1(]$Yc*\n"8.jEZJ-7fY;E?lbl'S^SDq[8uTlN1WeC[k2J6WG*ff0eL0r`\*RWN0l1pCOCf#YG2_&L0f%G*/K6BR._#&[XIl'.&#cj'4o5W]Z!tYH'%I/JYrpsbD!+9I$[Y9X#hC?aZlD\H[$k*j:ra5CEO_n!)ohW(!7T.Kaq#qQ"K0D.gHIPJ!MRN$+Cp9sF^.9YS#G*a%;A@fY8thG;9m`im204Rr!.EYCGeeE,2K:^'G8r_j?E#cP*_=W-kQ].X@'kYnnRXdKO@Ck;5Qfg.cZ2\A\$.cp>7%fl]Q'gZZkEcVZ%-jQ51I2p?Ta:6eq0Ejg4is1GHN[O-5Rt+h@dqCl[JJ@$j-ohPhj3YP%?fF'f^W_D\&#,Fo&.?\1rDf9,:sg%Ug]Co;c#&L6>`LjWRbW378lOM9e'@GBiq7T9U;d!Zrj1VfW.q!3k)3@le<[Pj[^&/OJqOE'(k@bT8+24(>,e5(&OXJAcpXRU`m?r'M@!-VW6l3A/J+"7FbPV*l104AK"UGXKb3o1;'fc(,VP!"fVCCqb9m[Or'_5'A9+>`KoXJmlrK2#(TZJ55kL.l2Hh7$Z+?S7$AceU$PMi7OWDq'0i-?@;T@17;PA-HIscuaLDE>[+XDm]834SKA-46B$(MXOD>n>WTldM8:]s0LK9DNaTjST%"\H8n4:0nC+'f'U9c5u<6VM/P%jA5r"b2ZQGm:/+Q.(k`PCBn`Fa4pn#D`$@GfAJA%Ro5$\t,n5[TRfU7%ju$,E#S,656TT*rcB>+S/"cMr,7hiLiKI;+lfK,`ijjOT7M[i<*Lf66>"rh#@9^)a+K[HmO;%Jc[d,/c&>8rg[*^tNP'X[#jC]0*_s\N]?Es)=kY/YN:,mKc=540g=DX9g*&2E(ET#7@YFnO,-)[tEKHu2[%(gR;PFg*Tt^h:r,VYiFTgRdnZD71`np@YSUK%W.cI&;&/c*GD):X.>%J-Y#-_QL5k;pR[KDX@7p(]Jd6tI&V4DR-'0(U)"@_#GbL!5M&[W9GOVMOH_d(Z3VHPJ?p8:9".i_*arX6O)'H;;&,<$??A-Xn"fq)5bANhnK8\rX:8bEhHDu^a3q4fi4-\]0uLB-5tf9$_pklVK,-KO?jA:FE>Rl13R+U#_F_.WWI8p9D?(fcLMO0lU?ZC'P?cs-FX17]br!M9WZ>I9IGLDJ)Li>[]M\7>NkEEB+3aorg\r+_7k`hTi0Z^LJ2tmCmmdHcaN+uj4igdP=MRm^`(.QTVU>kAsCHCD#3s6?.uqu-L+8IC_H+j3u%8fCNC78k`Sr&5is'+FNp9#gCSe!!:g?3%WHEr)(d.J]EGdd&%gGFi%n'KTD#Gi-1L]T:jGDe;J/]Z[qpaXFn!c1OPiVUL5e5Z[IBN!@c7f"fkAaqmVbh&$)/(_6DtC+DVcU4SkXEENq$hBI$5j,2Na]A@2F`))3;No#)g3NOEu"[Ci)#i3uEul2!cZ#9TY*8:(V+ZVVq`(Z5Xu#(VdtZ%@G,F!\SXrU]-mVR)$E;4XZ3=D/_h8K>=#8Rp9W?>7r3fd"Md:lV]Qo;[J101/]G!aAIYe\1'g[/lHs66R];*V,)[5n,h\:%3\j9)E4TT0WRPbZhf[qc[:l%'@6i\\)0/oBF9"&!YMe"q>"UIBYp_#>oX:p[8d$t/-m_:].2JC3V$C:C9*GEd?,%e%(MpT;Fr*0duiOiYPCm)"&l]jPmJT.NtC3_)k.hL?SD!7,48N6AKLTU4^X]I8^.Lg?cmiRQC=S\`iYK;Xi[BL=#A!UdZi!K0q0)e=A_c$EPelbDUqkUesfT(!];/5.6]gEK+pO5-uL.u4e$8@8CjJA_AeOCfTU0G7Q),/AGS*>6B!dhOf"3sb)?VmAHuJA(bZ[DCbA*faUm/1`<>D-:lQ[Y/I'5go\JWcK6NA,al;j:**q28k(@BPXGD_An<+sqTJ3Kc1(Jq&M5i6mS&Y468e=_V2kI/'O'SXMGJSr-`!Qo@Cj[0h8SE'+'I(.;bn+*i!a#OqfFVkX^m(/#D?D#E"(8H$LHU4`OCSmgiqN`Nb1r\oQFRn_\'<^=Ngk+$gU=:mF&cGiDB2ZX^M0b2.h>9+1@&]);/m4M.DdNjHQ_Aq58sf;/I2Q]d6rGU7%b#V&.WYBpEE>!2b9rHQP6!p.Tr$Agc<>oP1[\rqg'e3`Oen1*b+>]]6g[nG3qfpa$r$(lp0q3.:(reAq>\=GeDM"*)K9L;Y2Y^*&U5hM@gE3JJIm>E,KMDE3ZABpa->^a9a).>L[7Og`[Gr@%!=\V#ObRlNZkp7Y6u.X+l^uoBegf-M.ED$=t()P(:_]?=u_?Ge>6\Ql0QH$cMVs`W-#ErA6^8(\TciC]PAG@_5geMRDelV@MT5,rOc$5p<.Hobd>UXGh<^j833G:I,g1e,ih$U%$%+/"=B4.C%E>2@4!VLP4'gj8d7.G!K\VPHcp"+j!-r&j1]Ns=4P9)`!lIe!^UH$8#RT39VIU'oKG%X(Tf=0niLYWGkS[#^<>nLauOgDimbas+QXZ$0DW:&ECB/%mlHp<)`uf26DH/])eb:!,=tg/_ZK1.=Mt#+-\C!4!etFI(-oBdA93+>Oga%D9]8a$?b:!"0-Ma;!EkO?9J3.96(/oEBO*-f^T08ACb-r:oC9'(t]pBALQ3_L;f'P=fk(Pukt53p,gth,?[aGE_>l<>ptE-[9s.[t#gurE-?L^Ob6'.3BYD:m"&+/3s_tjmr4T@F4N5412X(`&8-#<^Jb]OoV0>$g"MMe[j=fq(GA/:H)KnUd>(^!@)"[qg!;UM'lbYg6lE3I%=Y>H;[.1;_t^hES-%VLQ%iL-)d;)_WQAt0r=cH[mnQ!rqgCAFPWY29FK'aq&>[u)p8Pk0(,5S'C`X"/#8Fc2lQN&H&N[dILd>F0r(fh2]5]@mG,[AMCljAFWjqVEjg7XEJ^K58JoOiB14siS6>`lVL1?`k*34s;a>RW.1n;XbFHoJ"'@#@"^(t4jQ4\B%#WMYjUY'q;EWkaZKDdl>Vfem&M7'@T:#*L+h^WLPLj-SI9p__hm:P",ZR`PN5m"bT1H41nI0'dI=B58YH5Qe(]cn$1nYs>`MJA>!X1,@NC/bskrS+=8t#6kcVF>Oao2caKFfB.kYQd.3qCPfQfai&uFRk$Ph`\Z/*PtUY8M]&lFbZ72neO&O'NTe#HUqr`&,dSK`qQZ8L#&gH)NR@7n1m1/>!r3\aS[@pZ*@$W=VODb;7-!7/#5mcEHuH=22SNN+?aiY_L5\2$;W;fg`EaK=o71;k5DE)7F(E!RTt2$7]l.]'pR@]r;"90`R^6.B;6&/#*^F:m#ZLngnh!N_6V.'b0fKK+/PMIH7V8H@Z*bA*IDEcNc]mpOAQh2``U;,0E)RC<2Gr3*6kmf[S+I]@[/Je5Su5j&'9;l3?+-"c7Ge]j:V;oqRH0JhK;bZ3864cnLLhkYJ^J[S_cGpg-ke4-Oh[gl4kl279gG-l&]:lq1kB1>%1CA6((;.#*b7\KpKH2(J#E_W1#D-OC3;(=P%FrfA)iO=p+hsIf"Ce_B6+C<)[Yg9YI+j"QU0Pc0M0U$#&)cOo_&*8CU\EK(4`gCQBl/4dK>%_['Tp784)05'if.h3K&Au^s7)uCriMTVV1;&WiA]";r0)`@,T^)jjdmcsB+Rk.Yhqq<8Oj)]'9)be7>$jK$E)E&RYb(_$gfrS;N#k/(mN+0"lZ(\N_g)oCkJE[:aOVg5i!\T[a)Rr&Nd?-8keik:^0d.eJ&>LOTCobZ_l+8dp<0;fkBP*TXX8>B^maOkb6;\i=M"sHeNU7$69<`_fT(OZ/*Od/l6n''W@6C,%OmZ6:A;;"c'.9#j]Ro*m+4@5V=iLr$/\,FM'f!5N(R+n9$j:`=5/NdfCgUf7ZZ&K$0eJRN]pgOiX4J6Wr]6QV4'C0n"tle:s!o'3i!OXNeq6O(p.(sku>P)Mg`d$V,Yd*3K?`OcH:#ba$%4)\8:^aYu*$-d7AQ6A^&/%+l?>FL(hKGCg$"Zm;-WPEkSi:%XP#*f9$,Z'+A`rVo%2382=GnQHRD+Ok?VqVGa/qJX'A%:kL<:5;DS7;YRjdmGZ*m@uDfk';bePC\DgY2`(7J1k<-I7lD#)`X0?_:]hVe)XIB9*:uZ'!$M5_iO@hpA`++N`mFolT&HPA4kb+3Rg^lV_WH#KBKopIi,1U_++2*DK3pPb_;Tcbu\PXZ\L_&Sqa"pDcjD2khN@[&]g9'?AuL/#Q0M@qp5B:,T3W$?@[tf-Qq?@A%15&eNnf4F+8D)tn?#@)XS2K>e4U/+/d4p0ggE%Kd[iX?2eNR=.aqc1i:F\e_:c/&:Ee"-AXr3ln_NAGWTXJe7t4sQiBQAHg,Z8)df+NKP>5kHcM'*&k7TG0XVs#!FXR#6FRq&+?*aS&Qr58/N18QZrXdj[rZ`KC,**P=,=7@2n#2\Zs-io2JTb&E!")n.`*K#@UDWF5g0_+SHU/@L_i,6A-%@mF.k!f@6d92WGA,ZKrSEDV*b2D=&4)@/cC`F'<1"Z[2HMEm!5Jj=ngh[Cb,0"nP`<2t@hj)#NG.O/c9)'VojbfHfP)cTMTVRBu(Q&8I6-uH4("G'3(d>]!411huDU=ou(=Z%WmuSVVf`$6%Kc&*^gn+A4"':KL#!pY4B1NPARk,.0qL4KX`jl<^DiPL+P,I5WNcVgfF97<[#@D"J.)fC0V,IN&5cF4ge*oVMN?9daSjAJKSuCaXee^Z;aY2<*W7`K*M5H(El7Mr%H[4)=G`ZH24lOA,pq7\>QZp%j/HKLCncaLd7(h.0`)?RaJHQC[p`Nr?_9k1Sc:'0c54'Ih'9p`SZ)k=4]@`\'lVHV%sUppf'D\A9/3d"!j6!hVg0\0S.6D5k9:k($"9N):#@%0V-utp;:K`Zj>\rn#b<^:c-@oJQa&q/S%'(P[N&4^UooMZ]!p"HOB1t+1C+U9Tm84cFc)e&5$IfdH'.'j>nuIdNd'BSXM3P=KoNlmY3TXVQ>@,ESI8##f*LUDBZCA[%e;$n%em+Z&BQtR&e>Gaaf7=&AC#-A@X%iK0_l1RNnn&Mo\nKDCT*h,E:5/%g1;lDW#R'aU^&j/G.;"7n(:,FTC45!Pc6@B"`(uW\Sl'&NGi]JD=7gfadW3qX3F'#S;WC'a:bDDs.E*ML8V(5E$Q_LKI;VjQ33Ef_Pe`$'FUl\*iUc.NgSPW?\3/"4=R+?RTbEgdjPNOnO'J(23n7P!N4c!6TW*_?\A!p91P*5f?=#&jU&N?8mZn^@3u()U#O>(e,Dej-hYl1_=@%<'f4>"@qja+P[W24+#j$Y&)68ZcL5o_-QM&!;40lFiQ!g1WY(rpVM=q+AG8.?mI)&Q3Z`54FXQN9r5$=li17[^3^.+&>DYt>9j&HH@XO4n4Or!M/Aj>LY-[sj!40cRee.$8rr:hj_(_%Gm2cB+_JVGWm>?1c8bS*(l"kjcJ4n,D=\L*7ODhUG;U6`Z"1,P[<#E5V7CY]FfVWYe[ngdgJi&p9VY;'.B.+&2Nr$"-LHbh;6t*Rdkb"7>r5XRAT&m(PtNDL.;cKS$F!DV#6^h[+<^Z\$f*`jb+$;?#BB/n@2JB"_rm]FCC%\TV,9lVd_pYAC"&5obLbaP-]/ukciE_9NjV-b@)0GiZe5nAY+ug=5`m3%A5=PmSFd9dm5psn3!jRYHj,0$Z./TYK^/9f3WgT'>T9YP+[m^'3Iei[Mj2gN/q'9qYKD$%h0GTVC4/c#R!C8M'3uI^kj6HJuKuq!T43S-YSbqPm)U'[&5hT4^OIc[n>c"&B50PG!V\)e1leuf=I>`b(7&6IbH818;2LqmCL9Pq%rJ2*_Pn:2Dj_@\@-!X&naFooZ3iZLLr?/d7O'r,VOm,HaN[b4WL[8D9M;M>ib5mS&(,YVlbIN:]HMQYA\b>aZp][+5e*Df`3L]B:E=VYOh9(tQnrNfs\qZ3>p"ac%*+@V0]#ZFZ%Rn].u"PZi'#>cVm+iOjX5=`D1iuboDi=@L?F[L*n,-"3X+M3.fMGUR^OWpNC^B+94(VV"_Eu>5%!HAiEk63'+`3KC36qPD/c[:]Wknlf3QG%7CRQ'1&#+8<=+j;,$`6jSU@[&3fh0j%QAYNU2Jm`qmOB/mR$8gR6mK&=,6MP2=&i'A8/#I9*?#(%TiFak!8BqX!5f5`c&to/67Woh__g+LB,8rA'!,n"N(o+E:/+P-@a&D2[`2tISsM9=6"CP>N.Mu\/dd1b11r-i=@=O1s"Nb@1Tm9p/LK!oWr_GStj)W;b4JgB[N9^/r2&3",Ag45D6[c%JM_j&,RgPQQE42[g27$\Dg(r;;C,9&/6Xr3!'.sj7@ZnT:JD)U%@KL!dJB'OdPjcU'F!^^20C0sd@S%kB8C;c#cQVtmetRkaG@pBh$+Lf,!/s%fr9pUeeNOC99'\0?3a;NN(6(jUl7KCXa`A.Sp,Sj[*`ob6/C21^kV?gK?844XemD#;23DSlZW)a>6QXkajpqPRU`KV3rc=D#qc,1H*rja?_[3g?Aq)Y)%so<48Md#7E4lq!4\apn;>%b^\jGi0fOHED//1)/79A*P(E\#G!b?79TeiCS9lS0.S'=T)Fd#X%Uc-B8!s=jTC]$-0j.X^W4nn63DWrl%asMbThcs@Xn@*8d3P3E\S6U0ID"&o'O*On4gH"!0F?WCsEZo\W.Y\=29OhrF>q`P5cLpRQ-_JQa$Cj=6<0?WCO>61Fmust&'5Cj[\@M3u2\O[bYndX#9h,N#I3dhn[7q"f9SAgJPVX9lkX-Qm@;NIH#)rlgH&c`m`5[/+,+3=VG)5&Po@cJNR^nSX>RqoOadJm6JRK"LudH*@@*JK/D@=%G";O*$=).?aI#qQ"4a?2*ON+(L3N_4$Zb2=#JkCjP2CPIS'PmasetoH^@+*<'"BF7^(+n6$RJtR\Kfm#Mhp]JDR/j#itlPm]^m]MOL[6IR-m(O64p[UK2oBi/R,E>_>#hPiG#XfGgiI*8-SGs7R=m)`PfqCKb0YL_m&PnQh#0_&[f/Ei0bWuND[_5V>t4j1T<_YI[J@s*3NX,jq/#2=Zi=YD&HgQGG0f/kIgRQFPJH8HGbi$\3Nq(JVsf3')'<,@>kRr\)K9&iS'oD;/93i=85G%Y]n%M"Ak_@4N2O4$9+SqeXdX@%84(1q5m6:YjIqt&O+/3U3p#/\[V]g'iUpSjqle[VZ2VK+KZ?+m'Z)8Fq:ZY].%,aUAB^ISa95*@,87G6Tji:EkS).5hL`M)K@(>KP>E)96%`!q=f*hMU(j/fa2S:jSZ%EBJ3q4*$qq[$8i,(9]eVtMh*0-qa/OQa^E:3_=5^<,kK2fob^G&gp;QW.(ua-!dP8+7m=:!,9TMfhZ9t7,X7*tKscSB`!R2jpN#Fok3kU>1S$[_g09RC95T)JJ*H3/[]*BPH]?N.BDu&fIF="h63\H&"dDO9IP1UhR:R%t`2OmF'K[LJ5]Uf3H$W@n8lA-Ad]Gnab!_]b,e#&/$31+1t.$+W-qC!_=O[S[\"]!1*iHrMW('/'lQ>Xaau7>P%:Cpt$Pf[+Wr8f[a%^3BH/hTK/D1HJtc)Uqg"4/'sutk]q.ctLbN*[_,/gi,XFpo;[%VIO(@:bR9$(.*'[I\ddP6e+*ePk5m&-pnJI^?:K-DPTQ1.nBcK.KioLQM*qbp]?M8VKccWSY-uAT/e0faOnF(c(.*)PG0>)KJOUPt6tj6pZed6Q0N6AlPjg7_tmrJlDrMDG!o>.5.5L,h"lY?BRI%A'!Cu)2/20,\^Hq56i#ON<(BV-l*s;Bh!?SQT6!NN?F/t'd4hJ@23(0DQDj79YV*nJ6#qMi3WCI)$HL)5tA(Y$M_4WcmKhq`'V\G+N=pDKdCRK5\ZprL+2tZAj]Q$!3F)lOWc;O%cRQ=%H1V24H.L_=#DuY96YS?9LRNjo[dA@l)CfEf1O(^XklsbQK/TjGYBjOEKDA$Bs8p/,\'FT9sV2>+otgJ>)+CLNW@L2"rLb14;^RSR8FMr=%L1`a?[-Cb1J.NobAC]+\"74+@9;XH*9AShQkupbpT[QG8o;J/dkWt_3u46_t87l=!>E"p9`MM7HXc([s,uS0Vho'N3bu)2JA5dJs_oPhKF]"Q#VHoOq=CmMO15V2)?Fs%,MY8%)K$4h'.+(HIR3R1957abeudld/`RcnStWr-#COCAj]U$7`:;%dXdTJ<(O*a7[k&+"]V88`]>H8.*s_"PYbSOZ'S(J;2\("WHC!jBsu'^5]mqb(4h\e;a=:po1Z\DkTcH))3N$0`,QK-%E:!FVDF/O+<(o2B_*?c0V6e<,YK:-]aP!R721rG[2);ad/jdFAU8&CQb+W/HV;goH.nHedHr.)d_K=/)T+PP9`o)lNQ)3(IErhK$Y<:G]>f[MORjlq.-![2@oX+6]4c7#">VkE&9Zf6`*d-l!ORAT&R?SWP=3YT`$:#lYTCe7@n:(uRQ`Sf]\7tqWcI5;fr*7CW$,8R%^XVtpS5jg)3T$Co4,WYBGAHEDNb0#F[mZK1-@q5Xr-pe@n"(3&T;7(6$&:n7]"LFnT8XcO`#:Tr+D8;G<,9Y!l+\]PGB(\dd7I]&'P-7r0nZT\(?\;k]p5H"6)KjV3<`V[U[RhlHJSQ#P64c^NnX/RAqQU<`&;!<'+HLQ>!0flJ+,?/-rq#/bAU)f)1)8;!roI''pB9I\YNrU/e0>#d!/*fE(p&g,64bCfP&%=iF&%.jjID"^e97SU%rB\/Npc@Z!oc@e9u[_XLVZ=3NBa8<2V@q!%D6kWjr'&"6_'<-<^B95'K$^2Om!/R&%#T<&Q=rt]+MP,,"CLW(6o?#+jl/n?4;fQPQ_Mq8;&!RB%;1_c+,p4c.=Rl:@=W5M&]!\+@(T.1MBZLns&!]7+H#r<&qNo`keYs+MhpX]=WuG26O,VGOc[`d421Nee`no)W)\+@,CZFhpNE,]3ukfRb"B`A&@0jP;&@N_Vg<6AgJ[EaQ%6&.X*t5I!5eD0?!h/[TsP0;%n9@HpiK`j@(_pfA@&\I:F!)6k4tF$KmT_T4J\<[d@Dm-8_,G8nq>V/&'a7)h2V9bR/k]<&3!L5\bg[':;d%5??>\rb)=A$UK'B0Y`Q?jiZ5^B%H5G?32OY3.-0AC_f-`MT\/19CuS2rq3@H;\+uVp-1qb`cqLuOZgdXLZ"b6nH/>-ktAFb:U(M$l011Dr3P1%?2c453NLH!FUcW&DS@(TF`9Z%%`QW*'B?]U)a*.0-PsM+hBE2,[_%;Ft.U,V*DG01`gPWMnGd+o-t)sJe$*.c.g\56*!4p47HYu0b78b1!Vrg!]UHm5&>U#i@B_VGZu'N2->G=TdVZ7tg,>6+CL0fXpXfq;cuFYS+d+9b,=Sh(Cf1BQ0oe([P8[#q@Yi#8KZbnmJB&ODCp$u3dUe)BAZuOb&V4dr+s]/,'<"IE$7%BZ"&V,ANDC9XP1pXtZ!8@7u8(RZHW_o^5U+nTel[BsANPCo,+=,3oO757rfHEiimnWV]\>VB_LEOg^$@ch0X]eF_lqUjoVTh*4Z\_,6WZN&&;if2uY#,MkY7Sr:!m#BKA3_jd<)oks>%V:dW02*F;#9ZDj(m8u/`qhFkhl]DV=h:FD9n_lc't7hJ2Vp:MS(1J.>l.t],$(Ih(aA(Z\5q!I<=7>qKI*H2?Qi;=.P5,BV9`f8lU1IU#QhK6ou-O*0*sqN]]D.GrIO6il@5r>urpXO)s!iH@34:K@YG5I1;70*6e"S>/aTkmf5AQKseWCJiX\uGkjGHaP9Ar#1PdlVn&8&U>MFt$Dc`#reW9FFC7Ye4sH%H@Dn[-$/5fEH$\";TI/SjCj0HoS?YJlgV15;b&"T\-QM]c!fRksl?-O$`A_0WE"Yc>JV5aF^+`!/5>%0AF&apM@M/(hZqNRRoo7R:HgM73_j6fjNRb%/ak*b-ZB2q,+cR,_`g$*(%RG`"EOt-CLecVu\pUlZ`Q_?qDTR9s[=aihKlHL;Cj11LRJ^A*rQe5q"W2Jj.pNsTO[I(RY^hN52)i_Eq:=Eq\P<(jbpCOVtA2GeI_g]eI]8_['F-PpgBY$#9pYgf%n601%)'dgtEQW<7D>TOC,MNgK4Ks_I*oZhMsD:e'pZu.kQp*F,$eC+o&0mYZ^QGK$DRdZY)&aKOOrdF!B5Rh3o"IU3J8[<&ml@o%G)a-/42j+gG^N:@5a([L.9p`iihnd*GiO1@FUmt*rX&6'.69X)('*r"j%,9P&_5^778.SO(25$dSYc:3Sn=`hh!=+]$je@,LF[A\UiLRFA=o,AQQ4CBh,\qpjcm12\Ic4[N>P/L6e9U&c:tc0Z;G#(T8MsY*7??BP.2Tg8%XD1`m2=-\o02`H"rmt.o@$)[*l@L`OmF$i6qN3%?,17JeNd.om:"E0r".k=Cg@E%52(Vc80r@N\]87NCGgrM$BbKBC7AgAr69@^7Lm+A7BD`p#cgRmb1+^?*VIj8o#EHUt+gn]$6@H9TO#U['eh5R$NUR@)HDAEC#=i,a_;8Gnj3C^jHf4(iO/]Js@Cj#J-sK_8r3H1.U:7C&a42A/RL+e:@?/'EnTon.S<3!YYb>'\IsCWF8*X4'`N8q&KQX@>VM#DimReGRuf!:gHiSrP"*LN0%ZA82q?HBrj+TKp'jqZ@!T<(u^*7#$OS/!bj7&1u(g@r2s-aN<@>^F"j:>SeV?l6i0]tUm[YPT7$)>F0;GGhsI%CUdQ0&s*(e9)aXY&Kaa5Lc[UW'LUDn*Y>&HCU?SoK="JFdod_f6lPc5N>GlU9f3<%1eL%C@Z%s#8JPfCHOpR;q+D1sKRbGT[pDX@5pp"^&1Z!_9#\>_ka<5DCUH6Ge%7'PR$]Vs#>\J_h-6YC0Lk`f&<=^`>dP+NVIW5,!AYBUtPnY-IKcq.-9rAa9%`8W@GYNqu7uDsG;:r?+9,%8i1JS!cX;"8/)e6.7NF\>G(_\mR@Z5,U,%,qSF/p;9gIVa>k_aWP*]8(P`&i>D9I#/93*J`VZ/`fc^RcB[7[5"M&S%L/g'*[U1o(P$X@2:K&u7p1AHQ@?QC`V8ACQs(Clsl?A=QO;Z^\?\9iArfQr&MK#"VdMW)aa/iq&Q1Pn8N%dNfJN:?YqCC62O?6=LO1:1@s8PcA]nJi=X2e?e)aS;JP;P"Kn<#&flN1Gq4,,/QO*JWS%\DaDP#)[]DO[9>XjRoCk@_b@$ub(g2J@E/i.C0NcF-UprY1-uV0FJ[ckh9NPCX@UQKh)/+bO]J4c*hsD"_fYtL%AX,iaYQIl>;;,k[q:e:*4-,a+T]8ug6\Y4Xq1JV\kdbt9gs\/n"Q7Q*)231'Xi_GCl\ftD2]Ad>Z[>%=VGZCm]j+%CYG[=I-XAZiR-fWba]=R'sWX`9f5R\BdAj1Q'VFjYd,P`YGT5B\[Gq"/4:%:'G5U]BMm*["4f2Sor^[B`&*UF0iIC;c6,GlYVNNL-=">HnaCgP?;8A&M^(r`h3L08cVO=l@oXY"e$Zf8:q$g1__BHfa,$;c-!h0gNtt\j\A.:F\^bIs!+lFO\$E'6oMfhR!lp/!K\0':rM.mbm6C_,X&L7o_!!pai(!R+/KVr,\jjnN#?ZL&Wo>?Vr\qfdqXkO^.qDSm/B`T>cZt(1X=;D=UYVK[RP-_R%G'T*e8Wl'0[c1GO',gT;Qb35&_S],SEF*5m\.p!8c[Y=3PW)7MkQ('8/@bA%V/Y&Y"q^LcDn&@3A)D+MnOW=3bYfrGp*gQLoa`I(`=&'\K(fQlQYs_F/Ju:u%&iR*(4Y&NB&D.12_"/P$+240"XgnF:1d0-H"1H@]Tnld5t_+Mo646>31F?6ZPp[^hB4^$2YZc3*uLt[1,Fn#a#Z#tXJCn;7$4`O#mrf%LJ-e=K)V.IoAm\dJ4Tn;GImU)Mq),>WP'LD&IXu6O,)?1,H!g$O:2R'JEu9>lg">b\5YEth+>`PLG#^U^6k>d+o^_bLms?k*0UR\D#@#"&s[$tq&Ng+#u;?r0,tND#!BcnGGtfI/c_19fgWX*C\k3(29Q)duQ<@'Mu#[i9j&?31/R4MhY`8HKN9)^*&QbWNm@J)!"?9n5\sl0PlnPG:!7IM6_VRMaL?Y)8M,V%t*6>S!ZD5MA4!k(CcQg:K0'qpGT]=Q\.X!<:2/eqI]B6tRj?Zl@Dsp8@(S9GmhHL>%__@&54U@I'ZZII%djHPd=>f)p#CIQjuUolG^KOU2$Tsh3k(G+(GJZ"'VV3[3M%Tcgqs'@nNo=7niFtGX0oIf(NdI_6`>N\VjI6Y^@I1Gbi:7?SPr5$4V0VG&<2chMpGbKMiG[u`7QJ,%E/*Z6XX:Mg`d6UV*a[m+@+B2+V'1Zc!q[ZA5q!7^f]bp`]@4IPILbtX2]&%@_'qM_p_1jp&kGJGSs];(4.^eF-jL#=l/5.rSpcg"S5iRuoI-RhAfUG]nGGOdIV^%<.\P.LZUXdqP@&SG=C;A1:iZt!MZn,Yl:oT:"!Q,%:6TB_@+cH:2##HP6C_tCaj<_i_'O_B\mBL5CN$+6R0HhT5Bcq"2Lg%':#o(:pKr]0&1b#,TJq2M/6Zrm?9&jcnFTt7<(op2t,8f[XBFj:P/KHmC.@k)V,fXAbHOEuAO"l$SgeHP(g#6GlJR+sSi%m!>07:6(%:/G\bS2Cr8T@9b>US@]oj+Uo*&`_(@3h"Of7:OXsu#Tgi]UJ@&@BW&l4B>BA?aF9`"d\)I_Y&Zs/'p&VBb9ua1H(KX/#O\En:KAW?q$A"je$[&6s)a\[74k:I*\;SgMfU2u^brCM0:7U=;V'l-GBOH&/N2aA86*MS.XuNC7Fi?'/@0=6@[B5n6bnR^_6,lK;3k3fu9XNBDm4%d&Y%EaRRd%;4B&0na.MB4^ak.;I"C]-oN56iY'hM>Cmd`6Fo%(A\g'k/OJDSpikn;`MbpprDaTP8SrG0(BTj#JM!RBk/JU@Dp8B*HFtdXhOT_,HQVDP8^`2RE5l0K-6]h"1$GJ=c.)rjd,1:Or#f+$e`$R^m02VEjq4q#W>H8\aoC\2G2BS9g#<-uLQ9b$c0Mt)-1'%'@_L3?d`bi3.?F%BPH!s'Z`Ui3H_Q-=#U%K.@"<<&Z3?_QMQ.iW=?K&lI@%eGG[-TK(J'[";!(eK.UNqd;maQRG;["hu]2M\a/8e>)6-JdOX?55=cVCL+l@:N4AjG.QJQ_SZlRSM-a_8R(OfTP`$/uIDC/MuMS(("[@eq0Rh6uU(%#4-sUEM>B@,Tb`)C@,hB@eJ'm_Ch;\MSk4*WLI-NDK%gCgVl7R0lZARUGde.6@tL@0)+qD2:k&8QQYINX\f7)%#/$^M,]4GNK\mg;..7kg`Q#Qm>"N<.i"@5o('Lb]9iM.M?u%7?_LfU,i!+[HZskRjOoN&NZi9lR)%V9sH7?m/B'U':d22@r+k!u.1NL5,X9!02rUg_tksTLIW@Z*=nnZ;fYSCb%h+fKst_i&*jOG=@$iTEep`WQ7+'&iNl!$ngV6Z.S9#a!%=2!X!1JE"n$'(R(TlU0Z.IG"I%nNI"A-m5^+\p]ID$XSHI2O]a7T[QA?5Ej.VY`;-a"b=Wii\:iSE9i4Vs/Lu78e[Nf'[Sh&]!GZH!+0OeL6Zt_;edf]a1Ic9sAtY4)c+uY':_UP"Z#04__>*T^g0Ac4A,QZN0OrGDoKEEFKZXkPE0MdElU=W_)b-]j+FRGWet*<'[$W7!#/GH"*aO1L/@!a8i/>UbAhc<#MKoch2;0K$$nPU_r.P%c[fnT5bN6=+KgU5:pS`TOQF=_o;"]a8Obu0T6.B*G$8BVH%9<97^]f"khi!:iRTXM`2gh^uS;1R;YUr5\WF@CbD,-^72k?/LtXQggZ/8e"A+TgZXXiPq1'>1i&$YgaWA9=(S)&XGrHH"KTJ8h/I9f,*Gf4VPAZu*Jk,@B;LAA]TH6JC:m_GeQ?!-f[Kq=f[K"ICdVe_[rJ)nMT@jfMVEr1AuY8YNf^G7]JR=2$$q5snb>_DEfsLe(V(G1G*m.q;GW;6%B6>>bSJ+D*K1X-eGl;@'`70L]kJ!^Hn#"cEs#5SHme"UVaapV]kRgMgmm%3fR*l'hEtX*>IT!28@)_6-ZL3@&I_pV:JhIQF/VB[TXtmSSO^B2eq]l[r%BACLR]G\u6_V+LpA/%L/mH.7K:F'0d1tFJWK@6%3!VcqHD]eR#bfcDT9[PEKmT3&6[b_+6'4f@M1"+Y'`=@ag`3p&U"+#hKr%HdCg]/61)NOgc$?[@n55"0FcTf(j?aA7it7]t\mIoO=gff]8AA,(B4\r*BQ:3H)O"MUrIe\HoeY>t2$4_rNg6'WFOG0L21M5'p$FV4aUb.hNe=.Bqg\Im>[PlrjAo!?Y\iT?o`@9D@a=cc,1_R"6>dPMnlW4+E#O_4Q3sbfbC%rt4[f/#%h7?&LZ4=8f#ul+K8L-UcG2+,nnAg>6@I9L&r$Ok:=X&6LU`tmu-jGmt7j'[?mG[+<%_>XF,M0Pj(7&HSPeequI#$9$?c8P(1B0]+pk/M0LOaFHp%&\+]71K>&\X]?m@DnOW:NB:@WLr'LS14fRM(l'eD:,>Y4[:000[/2=<24Y.8Yo6K5+gd\kL0&ppU+(U&o"gEW"AeRZH9SQD=X$+a,+d]%pQOu]/Vg&ZKJ9LIPurE9a.WA%@$YN#^.!pQEiMC\h-%IdRG4)6=#J5-cn-[tK2clHIMDkZKLkcGVKd9!]f5Ge]imM.#5JdE)0(/Y>_mbBH/862*/]&j\@*-Vs]$kB[bM[sU10fEYD7*(R&*!A!PkMo>+\V=*8+GqTk#pSl='-O,Ied'YR!VcM>F<*PJ>!Xs2,T\ZgNC#mmC!3rQg(,b/IbmRnkO21c^RMk/F"\&=Ri[BZejB:YBk;S52H,i$IR8#O<56!Nkas&\?ck%k80/:IFANWZoW+<9(7O]iRdk14_j9E9F%Ipp\Ttj>S%GW:??N_q)C3h%2#PsL9=jG6<&A/;QJC1,`M[l:EjiWe>5T/rkTWJ\)QH!YQVJL5>CG4MJF5S`]K?=e5WUopIN*/%BW1GoOD$;[[SRBUf_/i@_mAe+bU.%9T_Q&,V4/$YoFo!2B'Y'!WB5Y)$%:E.O8Pf-[)t/B-XEXG4+dTZ>5dq<_TJmr4BE7gM^hD;)WrH>)2[E",\T.DEK;_!Uc`.B)Q(h54ZER"**i4iOOB*h@q,K0Sd'dr*fE1-$t*GUWbjIJg;Q_&@V_gmfY=Jm]pEb6-qgf$0,GbHfUM[&gXJLK(cT=?Ds"brd@GSaeO?mqk1YX.]cX,3C"i8+EB:Qrpk[)#N\SI"R6Qr$2$]AfJQB-DQUNuR&&U)Rp@\FSJ8J"Q6I[#.oEsg=)Uj25tXV+`Ln?>63.$2<$MQg+K55?A3*()%0gk9l`c7s^&J>#-)52oIoAHL0^Ie.6N2)0"q`(&^G1J=Fb)qj"Z6o(K&DX6q\IUm/];">-"OB3_LqL`e+p?]r#u/ObRtsgqQM+K*d,q0d\9Gl-;#H)[Z$J/6B\;trm>%tF@$`iCdf.#1Mi5^&t9_s69,_2NS'V[ODI=G+Uh$%+)=.(>2DbB0b[8-AJu;i%7AZCR@T:sq=>[aVaDA;h]BN)Oml!m7QPE)Jg9HQln8@"&NK#^"R"b#KPH38no_0oV&1Qaif68*l2]>QWqRU6HfH&BdBu?eET"SRgk-)?Gd^g4Kt"[7C`XdRhrM3E'tc84H'U,+B^jOVQ$%U(]sbWl#NeBoP7&-j=9*]\CQ6`5n[@]=b%J4J@qhltJ3mcdLQTcnEE?<\&]cpYd+\iY4nmeB>%44J@P.a&AC?$PH)a?/E>KsLY:A8[9BbCf]1@`J+rk*j)L$11`C8U.7E/VEP+S2["O=2=t#"E1pp>(kg!huU4:C=I,N?I;.r22^`NEYUY(M)*!;!c8X1q;S.PQA[^G0M2p2Oe&=2ZtTe0BdheG'?bR6:\P!M/b#=6R#"BE5qY$kWPutf:.&d,u!oITk=;(Z%8"(&0G7P#Yfm,kN;!>,jq%jS3`WZ7/D2%$t=n7iT35E)GMFp6)hh/^$iSu@.e"FO="$t9cQrTehM#oYp55Jr:6I.XL)YZ5*"-+fitGQ*<*mfLVVb02('Q[8(k^njq'%:@JKC[V`U?LrmRqX1P`F-.QEFU;2ltGRrF@."QB3o#B!p=&+m%Xh?M3QQ1Sc(.o$eL(/T13E0KV@[ArqAa?*jO.NK?#P66sU6)jP'T2Qu#cR75(+B-u7q.f-@gd+\b%tgA)?ZhVu/:;([SO&J7;>_RE,M&EnB<9J2OQ2Zc'c19,fb4f;dhlh(eSsan&]'A,fGM!PT1AlFp4'FK^\@2X&%ghNbQ$c*YOc,mkI^btqJ?%Yr-j_,hu%u_rnm`?X7bHOa8Xn!J)UF2s)6NgmdDd":X/nThuA1mrP.Inn+ZjKp\j"LIt.9C^\@bpq0bm6njY)%2=>,0Iq_?Db#;>.n/E+$9GW*G[3+O03-G.sI=[>WCSF4H)u??-d"E0-Mj])>XdjYo2J`f0.P_Ka'8&M?+/UMHJ&jG;V(#@U%a9-75iu&YN/5E)YT+-B6-K5[#Xgur+mlHtK3-XSk-$B97_JUWQTUP?g\mJ2d7sVlL=*lW6^7S`gNY?3%Wi+^A())!,/GS%=]e#lP%IFh4/+XQ?L$.W;jO1($.@!BI!B+OM,BA)>hZn8_G6'H\T42US[W[R:#oPE(`Y1PV/AX@$M`sIMA`F_!h":t8UY1L^U,1&ADl)^CiN9>H7jWl^#ahp+@I&6]5DjmZrfi`Uikd,?5YZSCL(h#brVG_XBEJj=JHT[=l7?-+-cAiD%R&P'irr*%GI[3U9a6cL;R6jQ%6+jA@(2f(H0MPO`QDtgk.gE.PX2WaGb%h6C6a%(nX2hl"B3<9lpn-fNc\`)eLB\1ss[`2Joh]thCAuJWtYYeS&;>@;JV%i-D^92r=//S,TL#R\a#YL2C"%#tM7[<`rG+Lo`J7m=(7$*a@j9gIb^*jR8mt!;`KV1t"W>9?,65F(;\pNdg^()MQ@F.cX//MMA+FOO*f!!)_(ZuF3;]U3/"_etKD.:l=1i"rP)&sPW0NmdcM_Uibad@%->iG*)Xea]8a;V&gftfGf/V/@O4,5ZR(`g9,nS@W4Y#;\CHnUi4&utddU:g?*nQIiFX2lG]'8-NO&5q_hi":`[_g5FNB&jPFd,cfL:,8RDg8?.I75p2_K#3sA3e8B[!A4KY2Gu.5$[g`74/"fZal@pEg61phh:h'SK2cnB;tk/MePCU@0@PA5s%9`>`D]73D+p]*La4)cB]Ofj7LD[/0T&E:+?MT^:YmfE4$aD,&D<^!FV#b4#Xh.r'Rk*J>j:fb!++Ag)"os*n:K8VDU(UnP\.BbV[h_$R*GRknj0/Hu"d'2("m+DR"\BkD4TR`[benllTDqM*k!T)J#l`-LpM1(Y]]#iQVqX#3Wf:3oIp,EY/4$AQSoCTXK'Y1EghGfK6.KiQ(r$DuSYbO?k"A40O=0qkF<.?^%,ZWIOL91JRljVuM[5/Xq%ba8[M#*jO6c.*gUsYF]*Ts0hKdC.Lo(3/5ULV>e3s"K$!k.5@!,RY$sVp0;P7mk+>U[?7rB5aNoErM[ph?G-".c^Q'5Flc0JD]/$0qm5=XAhg_PgL7b:$JTBAcFUV4+/uKk:6be"a@q]Op"73rSKF8S!<<$NjGIoM+LE7X,Q +#6<\%_0gSqh;d#9;X![tFFT;C@^PGL3s8W-!s8W-!s8W+-"9:cQ!WW?W+Vk9t!$OmAVk!K[2m<8^zzz!!"1h&#%g:?XhYa!H#MPaK)``S[,iLTF)sqgT*n,POpsDUDI.lsp^^&54!!!DCgGf`E+9V'+*q-J4PA$!2)rIJr4XMaHT*[[@mSCXc<(eYBY7L*pi=4U!%cl;g*8pC.D&`fA"d=f*:R$G4s&El-Hi:ID5#k2rDd?bJ)F4%S5T,k)h[qaUb?/'MP:]NWi84c4"!fobdZRu7j<$&E$C1.7&#S=X"PR&]D=$otZ"tqm'h/@So?*q4MG+%3YpV-OnH^MfkY;A'm*np-jk?W55)s[12XD70CSfR.+NjQ3rf_;dRnijarQZc08^:sKtgt?i2.$Z6q_k:)Fk;;kp^"lcGleV05O&*CNSiaBe3LS0P3c]Z'P\il+Y+tH6g@C_6qr>'@QY#nRIGR-\FnN7`%oXjDp"aKW10g^IoN-lqW*^MO%Gu)McZS[1kDAN5T(D=;[eAU!^$dQ'k.GraB?S?/p?C_m]^Q0U5QH4W+XQ`NdsO<**koWJ*IZVt^$fh)YH(uJIAdb*h=Yu?mc+$+F.g-d>+*or.+>h?=U\)h:BX$XoUcib*!)AmGC@2P^(0N"^2LYsEbD@qHTd>]To-6i7;6:%QF(J]Y1T(agTnK[p3kJ7k,,amo]I0XqXa0'hY-[3ZUlhR]#D81sjs8+92BA8n\c(#S8r5nY@I#QYA]d$e\f-;C:8r7+=&T%-%S%oMF0Vl2gZo`,!=!7O3[!!g:=f`&9nY2$M]$7hFnk&e?JeP=P]6euL[m?080'\8FX+sA-[+n@o14bq4NpJk;8*t9;1_3+<%>g;&(@h)d*Eu&7#M8h#"EE?.9=+UCkICD8QcJX`Q!.lGk5X4HD%49Xq6kWlu&d3q.V,8s1(G>Y@3.&VRabWlS=V"L&j73X'Jq%*+FMR&&*JPDQ3:l$IE;d^!.UEg1j"6lfa(D^D(O!,c)Y\r^8l+NemtT"-!4_,;DNfcU2;\<,&7WEULHVUhQ$%<_Z/l9a8]oAD#7`=H*AV-l-SS9Sm>?-;>X/da2G,!#ERk+g@d]8s5E;:_kfdVUS(A"@$s_,Ym$*-K/?GiV&D6`.+sH^R9M#fO_fcp,o\OO)@">.A4W]$b\Ut?C5,&WZ*J,#bor$VKb[6";e$4ad=sL/Be1Zh8CD'-N>0QFL/B`o1m&KsM?K+Y-;h,s>9l&%V(*0+=[\49&3r&Y/BNiJM(g8*)7#(?$t>>t%&Bpp>:!*;O[;qY(,;9rLsegs7'fadN?Ub+'1-2#Z9i.<,m8f&Q41a/,QphpC(1TI8t.X_gBs/rc%.Xe`>_7C@4Ogh-F-[?TZ4uNYXr8k/7C!$)^_k[0rC>%ArVJc1praUJr-G#MMar^8nKsoYsKn4e<\3&(_iFEM^FUH(tNDbBV@,L@@!/*MNX,3W1qqqMT4=#.1$_'Rhj*aOu8o2Z>1;OZ8B!6fd,'N8X4h+9rOnXAfDHtR'e@WBP"'^abhX&Lc2+d2C+QD)%.:GTpRBC7$C1F^_*:c&Jd2M8OF?:8/kK3.p8#:?AF(hVF"1GZm*b8DiZ_IFl`YbN&29.$=c)A5t(fd(DI@obBVZUo!bVF##8Zq(DKW[-$!)bAP;75ieL,$C(ng*5%31MEkt;/KaGRC:LQD2iBNZ"k0aBV_R7>@agiD2F@3R2SJTbS_hK`>][^B%41&-=UL;W@D&6gM0orZNSZb_5/S<)eN#\fpS58.Mg[U6#!VC;O!J^C/)(7B[BdXb%[h_b_d'"Ob$A'.]B5+>%K";c(pS;"AG\OVG3g_MaJ@?=IN-V0qoji`INr-K.1VuaGjZKag$b5_6G/hC(3du9X8MuUr^_8'4eBq@+_JidqWU&9[QD0C/'hU)Mlb+`^U>E;C!\+-'HDQ[PVfb1C9j[CfrV!9XI3(-"J_QaP&P0b:I3N=dDaF$3@D"N+FQFU_F(m/OLr?AM&k!BXX^2,t(Hs6rmJbb*-@P7aW,0$nRjpN5EMdQ*OBt0OW:22GL/#fTU(qCsnb%a^[$#8P;bj`>0m.[PfmM9h>F%M_LPk`aVUfN3O.UaV%NgbqRg^0p+9WZCEMT3ju`mi+B[+*i4eOHNID6^*6;Im[VWts)$PdJBZ6*i(F9rPBmOLCmX2Q[_&PhO5nRM(:+;HXXW/O^PR8Yn7CL1QcO9W8`'.T6pk=IN2_`lp0'P8Z3>Am%#iD+uNP;/@SRWFi2*D(8Fd85`JUClhU)g$sBDX'gl4)1o`8XrH%r/R3nKOs*;rdXV$c?]90k>$qUrp:*t;DKUriRMX"LpAN9JYsr*3_lYu:N;@h+"@7C.AcH90L`+&l\fV5OW08.X7cmjX!3&k.m^?9a4h_`)KBESk"&bTAf+>ac1NAR!BA+H([9e7n)t.eGI/jp?i1ktM+mQdk<9oWj9'HaEirP3GN.(/21Fn5g\t>MhC.I1b.',a(6I3HdfaEtF@5SNJ9&*WOaDG29^nea9G*g`,KD'!8"$,belb`FmGqHOo2*l/#q4q80,>q6G]m<2l]VI6O0i]Kp9p9Gh3mQpR\hrRRY6hN7R,CscFTjXVnk_W5,o5&[pJoTdjppEpIjop1t@_^L%X];UUaLNb^WTk.hbS1'/rdc3MBbYYfIo_l\sB=d]IU'uN9SnEdi>ioSA^r*cQ4q0rA.:XaM0an^s^&?X+_2*K-+sDoMkrQ<2C1WV!AgHUKCqlg]I?f5D?i2?TW.2\*<=i*kpjKXC*;QsOms\D"0^g/\Yi\fRrk'k`iP//3;_@L?bSpsGJ:lOF8q!+>t4VHC+0_)'1-4rG>=?Ngq5"0R(\i`'jDDgbn:^%]VaWL$.(]hTSE'@nAQNE>^(-i?gZXXF_2ZIZmrQHK%Z%?_Y[ST@o2grG$:\:PC7Bk,^NYsO0SR2r/%.qWCp$A?\;aFK9#e6/_;)-HK"lF"lP`drL(CSPLfXcZIpc(IV.%kZbh%dGNGjFN%f]0j(%[c\RM0hVnj_d4XK>rd_ZG2I98mc1RVn63pPXZpRd$<8Ufo%Z_%Tdd8(L)bgS^@c#WmV=-/?SRK"BjM/mN50WSgZbWRb72,-$^?.ek9gq3IT[oo%#[5=l.7Y;.N'*s9aje.I;7=Uf\XkQ7Lf(gtY:"5XE@sXC?+-H6NCT*JIhNK)p4M[rir.\74s*sMc<@okHeYtn[emY%ajq7GKLS&6pZF/33'>tJ6`_\ZG(1%uBZ3N'k#JMB3qqt\35jPUFfk738\(D9hl6m:K#nR+:@lGgnGE((c4@hWZUI=Z4G,g:E-kj)n0.U+RXa;J)(Nq10S4Qk!=IG[2eZXSU29kfPKlYS[mu*LVrlckB2/!h:CTk>d5;2U?ZZk'6@Nt6em$u#LrD<9g50eiLNZu9:A^@>$k]ECC^Vp(+Jd!aZ3aJQH-1ff,WG)^V[)>6T6h*EG`bc.AGS!U&:<3MZ%P+BJSHND(Y/@LfKCbaf9ja19=d4@$#(5H:7T-k[RhVq<'>-i2Uu0!bd6\S3l[pFg=N.u>[rAC[-Kl!gBti*/JFo-eNoCbeg2UIC#8!A+,>fmiD6@nIb_ss(>=pS'3fCYQ>n_'XCTQHSG/h]W4a*%gkOq9OC_n-1]CUrF"/.d-q5ZDe3aL<6^W2T*Uo(n_ImiA4C&O<'0a7d)a*#.4C6O\iNlS5ChDMbP58W+lU:dp]0`F(A,S];3b89/$Am3Aa?/PA7[r,SM*;SR^pO>0]Ih=DX2HT?5RA\A:o_+YYVenf,G+n"f3g!(KmhcbP-B5QsS%Dh_%ZkIt0ZB:V*bm$oY=^a6JHfU%CJ[BTZ#1'^.F,9hjPEh1U@6-XBS%ao;o<[VA4bQON2=`c,hrZABu4Zb)$>W=+f.=,#IF]do;Zl<\&aZU;s?/XmYTV$m"&JO2TY)#HpUQ]"0)GabS>db6&'MlR$IjRX_Y1U(alL=hrkYdGXr,UD@hUg3S[JVVN*+i69hm6kS*@VAL)<1`qK^C^q@Nq"LT+]!:#!;B(NP)=@7irsq4rbj)2m;R;0NN^_6Hq+P%jbP_?g@lY5_@2PXX"f@&rb7/PQUeg*P>;)F8[?5Z@0*`%*.b0ri$97t@Or!cZP7HLcQ$f8eV??u_\q4kEjIPSnh1P#%\^ra*rPF[]b"EF9M#'OKG?%f9&!;g7#utT(H\Z54J<^7:rlEm;(KmS]=QrCDc`'LZ@$<(9)!;p)FPDMJpB2PrBP<\Y'HH]:q6",K91W#Zk(9+s]"2oug&X1G]H!W.0UKN:mIT#*N)8M2p1C1M78,m/rset\PSSjCd5h^#HjJK2oi:U%@sV@I78ni-8L\Z=m#hVL`:e@/CeHOD2%GEtmh]lO%sOHNE^qW$oGc=MBYG27U>1r;RSd1bq!"o'c_4-B:)p1%KiD#IH@5L")@sWWRsJ!q\@Q:14:4$&:kuNJS^&_YGYL^>pU3@q`@jtMmoB9VaO7dqA,Sd^6WQrK`JL3l'(Rf@fL?LqS*^4Xq="o9C#e1^5,`BAh'n*-e*WM2#(C*h[_c9G7=XM=bYWT@RE>dgWgNBAupc1Kc#,q&)1ufc4f@,/GFm\kNYC6nLseS\WKl5h0O!o\RLB7OD5uoOQL&5:8->(6".[DJtlS!XdK:12^S01Njfi$43W?K[#@-)a4?`hhtqsr22?dJ#/Zl-'1]6bmkRR$986Qb&/]Fl*+YrF*AA.!_$*:LU)p%:D=%2b#>2pEWNXk!@0[@A^F3!H;\N!]6@qUY8@O4f0e,?6l.=?h&ES5G@/Fr=^9WO9$)fA:hXL)lkco)%-f[17U>1dJmOuQ#"bBU.J2#:6#gG(EA7bF<*NS[HGOaL/cVVCu;S'&a[=Jse'nB^7?@)H)YR;B!E-lC%_'G0W%$8=m9PmQI`V1QOm;qd)bt4(`No(\ngf6.jhOSVi<937d\sNAZ/kl"&W5?%DHE*$[mV%u"HkV,fR1E/Oku/pu56sTVh=`7k)FBNF]DA8t.IP1gkjeB/M4\kdG5fds2/RVYh`&&0Fe%Rc[DlfKf.V-.*J8ls"HXr4(i0eh7)G8a`MNTcmjI&u_)$>emHuDH_ghu,JNU68-HiU2H>B1p]7SMC6T/%9?'1(oe@Ej'k,9,PO>"]*g16dFjp1U-$;`OK6-n"#Fe5kMVZ1['F`(IR+W8ktl`_&rXdj7oN.5462&JSfTHdE)4Jj76NQ(lcg#(.8XK"Hoq0%Qamr3kGO_q@O]EMbK[jTb)S+k=cXWSG$_`2@XGYM>=I'ja[N>:SV$U,cN]21,3*j-X)LL3-=0.>@(;p6^J]NQLVT3'%cn[M,>Yo]?49it!flW2#m*F\aO*7/>aQj"D\7B>f:_%S>l3hG[8?MV=JM0%rANE-4KF7h/W>$f,]?[0pK&qnnob^ja)$>B4"WF^YM[)Sd`g_Dj3,u(Y>b$C9\7,o8I`XiX\KO9af(rc/ZH-N:s\Yh/R-!9kIBed/,t9lOM8dWWLu=lRH.WD:J;Lg9Oft+&`KFDuM.GPtOtQ51jhD;MEXjq)ffiqEE,;3gEi7\Igbu7!k>/l\dCF)paG&1-sp>F7Cj7fquR(Jp%9[aJV0k+ML!5cPl,sn#qBtf5,#esHa9Ng8jhFXGUMD]e3fmFjY4-p`mIGuYi04[C4=Zf_mXVu:rjc1H`T=rPpkN77g.p04)u_R9b4J=5&4AQS,hKf#.dXmo)E/7J^E"eO`VJkcIKqCc,]&%W'Q'E_r--^rBZ)RkX/=L/'^O/P?3)UD2_d24%dHgUI3\/NhI@_4sFUU#E1c/%N+UKn,P">pj1dRm)RZO6-l.2p%?m(])j`"c(k@'GQ&2^r!$9[m0N1H]c0XM3F/S0`hW(Ol'^X<'/\lV=N%;`b!hqTZQ*oNV*=o#DdpiEG.FrE]d@594*VqK,4VbFhh8:.nIk_o(.p/kof#QBo$BgNukcP5*2:rL0+_p4+J$<*3TTpFA9J^h`^[7[X#h[?UWm,aSYV`-;UPdTf:*5`HZho/e=(DHg!J))kR0[6go+e#*e3'jMeqFJ#W2nqNJaq[e0,%X0A>Tr+JP5UgB,prETtP4QlH)X45;@%-IrsS3gKs[Qq;AR6eYKLqeGUMc0UiECJd:r8"=eRWNV2;24kQ&H$l3^@m,Z.t90OgE,s!hOglE<)MjJ^SEqE%Zb#BruSFF6Z^Bi@gU;_*!'s.b_Och/Yb;e,$/XV!pJV$S2KQgA08iiC1]Q1o6(6:)5-F5#-B*1Wp]u5&LR/IOO*TV8k2ph<[HHIW,NhfH3.SPooeA_V.Ab+-K]euLj``KC21_nd;NC"UFda78PK/!m)sXFF$bpE-Z1!UhG5JjJBJU75=$$>)oO>KmNuQ-ZI*Ndq\EJQF'45Fg*H1pWjChRZ.r6&Cc'>gTO5uc7r$9em_p9`i9^`'11hC3tWO+l?%G6J-Ap7X(^kPKFS300DI.'-(m&/Z(.h#c8L\FlY[F/M>6:,j=j.S0TD?job3`68&NWq@L6OP51]$Q2G\)/6BY*1&Cq;Hiu7-#afN:epZ$:+bRmNN5Zg9OG87DRT"VATImG"jKqI36cSA@jMT*%$G^4aQW!c7$PC;*H1WTAcjGau-eupMCnY6b1``B`rtm=T?u`2,T7Db9j&s&kupA:BD7n7IHeu\'f33m]%tU@g#ckjY-ado]`?D=SV8$_Kh&Lh1R+S[eOP28hi`V3r(R+2OTtm"2!a'_%slp'N.mc@gl%.Tl$ThKHju0g_[M1Vp*8UE=llsFNOiYRKYZkOU->mMKe`O=T,"B8J:5fC:Z_'9aJmL?aE0A9KaWqj+[%qIjQYlIg#RCSIg8#ILL,2R4)_*ZSl!q^!43h1%5&*=('hT(:c(j=7kl5665Mu?p\`9P6F02F15rBX(F:W1f5I]"`:f7c`rb,r]):lc9H2,+;>rCR=)n02"1BW0Kc;L,JEUkY>Vb$oF]$l4M0pe'@sO6)WhDL\C0EpH?!PZhOeGjUUNGKYNbV[j]H30YJK;ck?J`CMBZ\"Y=mTG3,L'+k\#^l^2LFVUbZ@jne8q4l6DL,'4V"N[/>U.#gN$rQh*dKM:$ps,_J)J5i9#+/Dqi<]Xl[H'B&&?n*If/5l)o=jX!@ERMXGH=Vodu;'Q%fq(5FF0NLnrh@Sp[9i1`Q9gT:[:SOge.o7jc[4`"\pZo&cW\Wf\s;TSV0c>c8h"uAW\H1n5^L,[O!>A`BB6>8Q]kDsgg^D;(hmhd%o&J-=7KM%VF@-ggNII^6VO#tWNWZo=_\LF"FVjA4e^NgtO`I'TC\DPKXnoDbZFa)'@EBdQf9YuQLV+`=uPAj/>d02:1/Pp;S&#,+@a^CCM>rA"]$@PEoGP%9Fs&k;AkD2;$kSs?[H0^HNRIZuYo$AE>0B(LtZ.*?@^mL,nmA*Z+MATe;F7XDi>:Es5f_&t+nhWW@b.;bt\bAqf8S:g".D]YbrEC+gs]1*'[uji%d:[NC,<1'Ugus,n\`#ZaQ+<:1u=7m6\,u^N/4c2XX;_ip8-4e^*_RrZ)cZ]64/&&;IG/:WsF,3aDh2ge+l)Z_qh?+D/jED/+.&&\eKBh9uMtC=/P`"7ZaE).-T0_DI%4tRdIPL)([1@pe"QHFZhIFK`H4SadLI.4$gR7h6AOg9lrmAI+.2p:.>jTf=':IUZ4SIF[>cU&g(84a[EK(_rbB;"sT!Bm9=i=9g_(9Qc!l>YpWb>&&2__-Dq\j-;kBu1HBC>DgpooU#4r6[!Z]/:70,'(LK^@qm-`.-rS';)5iC2oA,pnhtIHZ*]DNWH='PA*FROZAd1;P+L!_;E-I7bD4)nUl,\M8oMi$^3^lu((^j-sX"1=SJW/2mkX0;F:-BnP]mis8tS3GtV-Mn">aYN3(_lVlcY:1H>PbC8\PVGSO.a@rBY#%XP\0d^*.$3F+'P=gcBOe3):;**LTgKN^S8Qr'F&k<.W<[C0O7A\tfaD2-K0Mo-W#1X:iMNV/lKqT?<+Pbf,l!,F$EftV8R]d!%Z,Oom?/'r?R?S[*7O4l['L_W7'K,&@O=M"gYnumrHjqpal&rJ)YUtDL`+8Qj1j9![DVqMFNr>>`b>lPaPe5?NQbTsM>e]I+T2tVCfl$Lg:\.LI*QH'bV,?#pQMp[""+b2d/F35HCJkWU>@SY@6U61V6o[a.X0o1W&V;$h$fNGJH,CC6q^^]^;9U5#Bs>Xc2n%\Dr3_gSF=?nE$/Z>ID[NP3$O<7fC['rNdXAH*p4Hk+0F.nCOY5m1q)V;:N#`(5A^@c45a7?U:q34[>,jC\8r75FQLmbadWK.:NJ7bmen;JKP>:9-\N`8SMO0hUNT!ogJD1\cY'W1rT1s5LIA;+r\p(Oglp7&i@;k&YcUg,p2TE/3V=ID^%1$XoAJDL8:r1;e9V%2[$*d!AF_#5l!T)\q/lNlBeOpZ+^d7DA0rK>;/r_s.9$)^WKV"Y312',_b(<`1%e48s1J#[)lVE;@bUWiaD*dHJ#PX=kr-bGp`BI<)WFF;B24j.BgDAD!c\JB/@6Kj"-Ghgtam-i23HKsj(V>^t>kNYFG6"PaH6j9Y3]fc-D5'O8/ck\K3O5.dIfd0i&k$`dBZ,p-A+=mbFm2S;WheriTFM5ETT.q8WOrgo^KFB\S1M7=)JAj8C1e)rn:f>iBYXP]0L1l%6-UHnce,n\i3l>Yl_LY+bG.3hpEl8nF4;W7FEX5dNX_mJmiGok,dLLbQXIrh1_+Zb%^.r!Cr-=B4'Y\c[(V,OBL,kq.MkG+ZiNT]8gdoiq"F],h+Uj\1;VPma`+;-umSO.!F;*=2*#)f/q8^u(daNj?.n0^]4U(6AEN6Br4%p7@PKHKg$\B+\&WjVetj/ArH;K*7_3+JI$.&R8HE,nKQ&2`4sge3m'P@^'eK10.]+6>HB?#sXnF4\<9aBRpk]'?oVqW:R,8%gRI5.$C+C(8:lkqIkJef>o7j]i`j<3k:jR[`]:7FAd,Et"MT1EX1nCNl)s5T\[_f!C/])&_P[s/#N)&i@p3"i7;IT=hR@o`(uE'393m$hrh3=KEM6n^_NFqc+_9,?`nG3G=f#&^;:)FfFP7._$1>/&q_D&b0+3^Sh##_ist'bc1`PINb^=AaZ-f;A3t^V.][NWJVY"d#Fi[EbaDXVahGQp-I?'*)kI,r4YYPooZht>fcS*Fc9A?t29h(\'p\E9Abqng"6O%`H+n0-hU)52)hR""M?,E"(=(t8)`0CCCV+F.AUbQH59!YR0&=/A1Ouf;'MU`<4[5Cm7>X/+l)3HMZOcJBtPmWj.`!Q3f$r)`1NGs&rN\k_g(\,]&9hR5_*7Ql-3?c2-:er)+I>(gR&W*N=dg<[O'!0jQAn_)ikLFRpbU^/B94cZBlCT7\S@j$e?EGQ&QHD7:c#ajSfAQX^0<=_4qS)R]$]4sTl(,);^j&((&]qOk2Ek?+oCQ$^dKZ.V/8Be'q#VTp;&naOA6NjF78q8<+DuRQ[\C!Ap@bC346iLD@k*Ib@I[08^KI`kmln]lX.9?bG=gI]RRf#S$K*Qa,V\6p^r*jG)StF)BeAlk<1nM4$89'UrkC*LZ8U#66trD%GY\bs1*WJ)((UYq>uH,qu=pR+EAkbJh1GKBFDHB5!OUIc$Ve1YcEis:iV/=t.OJ2n%"$1^W8+V1N\n7J^e4:/.gY7^WP3cmSC0;5Xqdl/qAA:p!1)S9;Kjg[.fhe\"\Xq*1?OQ?dg"N-R:k?2(LIkk/Fnb:@q`MH>,-UCag!TO0I23j1q#?u,mE['qd-P(WWm7bsg$(V;SR2:9Z1FF.%D(>[5:Vb_d>3j>d2Er6<;FNLI@W(P'J-4P7G)VmQkI9(Skg&;hFH?9(+O'8YV_AV%,HjFk+_GF9Kd.6Si_sD.C]?Q&NhbsIOn!S)F+o(0R5*"0W5_PuC"HqRu&!(At3FNTk\!P87Xm*_*rklVNWrB`'KjGVrAWV=Zl@`tQ3Dr[$?E^60+,f8_??'hIlIShTl-d#P>g4q>^bNH]F6+?[WstA;,$S-2b!3$Ie9'jFftMrZHBlmpH.DXBQ%&lUG'XXpmA:\JFnF=U2U2(Kc+cKa%XPUaLV7k(N)\6f.OeW:(Is]NHGWe[:31Ae3Gi"`G7coaUnEfKl/a:U8mMBtg\R-`FS(WLgF5Y%kg)c7mB4%)UV[cq;Lc0QnqETlW]>8B(Rc4WR3FYPVq>BYn'K'=Y,'h_(Ju4Ol:.n*GgBTC_S$Q-B5G./T^]B4Y7F(jaG5N`BJ'Jbl.QTtOZ[=4Li[<:"JrT;gP;B*c0S#+0eQQH4;2#)4SL)PRE5`&'Y3HmMub8%8B_3(dta[Lb\=4i1u6&4@BZUA:3>_G$?g0rN@t5^EQCD#`,1AT!m^*)M,'kP=%a(X>LUhOj%F0;dqlV02^_XsC47rA!V;g?muoQ/@(^Gs:NT2lo:%843ka#gX(2:Cs<=r0n>[!:T>I(&$!rOoc2B"Vf7*homaI0OF?)cB5^!I$'>I5/mIaeP_F[n^JDsmF7fDpdOk;3E.R0shbU5B5>hou@-Ffh6?S@\@6.Bpm+1(ijcWQ&;#S;Mn#Y1eX4Pk<<4?^G4@;0KKj\,cp,W8NmO>!"V-MBetI(AHMM_'1e-scPbJ'CY$I6oE-2169DOki7)=8#k)NAp6O<[):O,njn47XjNUDYMc5LZ\KG2#DUe`l!Q0kKSL-i4Ee&hbgdcek;Uu1pJBL]hftj$U0g0P4UilJ3-i+kN,L?#BO2DYc9arWIZQ$MZQ2YKNbrSNNu76_``URSCpC1PDannNIbbkHq&WI@KHZZ+C.S6B64&"rLJG)kNnE!`k,=`2d+>)T9R9otXj01Q8&ceYCnFQJ.#HM"73nZLct/S`\YKJT0[kA=dd'I7fDLNYI2g=s?-rV>rKOK6iC<61P8Qp(>qcQ4dsG]RV\:3W2&d:GNE$`s;u/b(g0fCoS?V8DM]ob"H^]'cl/#+:;!Y(P8VE-O'..B/^>9M?9;AQ&Ub,0?3_Tn/ApKdV+EST*PsE_O9`R]E*D"?FbA?m,,U$d-?NRD/UI+7mE6"G_C@MQ.TMZbooeSKIRZI&DSceU6*!R9pBB=Zs%?$41Y;4"?\n,HH*_iM9U)?+5`LPmdt/cHT+cS"d[eu:d%e,Te-_Akdl7Fhd/.klE@ATHFr.?jXe)iDt<,Jlb!#Sdc'Tf7]q$FENV;B"cg5!gPgHDW9>Df^OcC_Um_Mh@q@dgUJJAeomTg5_/Z>YS%T.UCo"XlNgb%h>kmu.jf#peH>X>mWd"f&3XQjqLWB/d4Wh_jqS*!co[LHD,#['0pN-,$oX8T/Ia3g@I,iPfGG;]%]://-h93`F?I6^>c\BinO9^A8gX3R4b:9OO8aCn[#k:(!`SP7&^`N6.;:Z4*U@!-0_sjCW(E\a?r$>IB2`"YtmaMi\Pg2qs^$%hKW0#>*0)BDK$rF/H0m5\ur@EZ&4!#;2hYLXgn)kk]Jf5,`oOs3:=c]<(X$2shq.UAKF\Rjf^T1518HkLI]-N?$U?QFG>]F9Mq71&PqbTQ64NPQr0jgKr/_s:8Vh>@d[_"FFOo0G%^S]Ct1QHPS7r>pCfYSdD&$)MI^l*<>4hA^`^AD:,M:]LI3iad6P`H=PnN*_0c]ibS5C[PFAS7:R"br/=olS%\QgK3-_NN:jP"^(@NY))u3`G4^9@!lAlEa))^O*?T)^jJ!lKTdU.'/sq6je@#o+$oqVTcGbO<(eQRPh*X8;;-GHAeT@8B`uHUV/4M3q4J&S(X=^Cn#TG8%`D$"ugY/>5P/!9he\g@#"\h>Ci?&kG(ht'G"NM!=Nd-V'D_@*NoAjX_5X96eSHAW/YRk1cNJ..+D#.P>%`D7-^#hBYoUX"`UEc]!I#L-N^iHQr)FiLl=m)%]'U_(gL(XZinBR&6`4*AcH!-Gj:,BR4tPcisc8W6A-BF_cO>=DqEl1RbGA*6idmqIni?>$gqD5E93jN_lt,9_;)E_Q52hic-djRPe[Uqni?uG<<;>sU$Zu!&AE0)t"?Lt5J6]p%(#/HO9/nHX,A\b3=)-Ft:`sa[?c'UXQ=k[uW)hW2W\/B%=UVJd"Rqc=S0@K9QfZ^QT7APY3nbcu$/;?\Q>]0K=\E>U@r3iXV'k,[!#7\t'InO'%Y\EaElhcMEA0ao3K!ifnX7i)X-n\&gPft`ji]Uc;NOU6dgmR01D9R6Ephr5(@idO1V<%m()lZ:i?6XB+!='q/0SE9s\XGZ$+R/#RFOS^KP.@*7BF!I4jr=4s:O)9C#e8DmA!)$29MQ''F1>3)*V(jOel@EAH9*N]BTZNLH7U!TR%o!=uBmLGp_Q0(B@/<;imrEd]VJ#DU']D1r`TO9k?VD&b!u^NU1`!q87e"(4DfRp@$=BU3KZ%LIXPcl!S6[logAgFO]gRi-Z5m?#$UF'J$gZ%1`/HkEF]_FmG,d/Gi>/#C/(,jSWnu.)$+i0_[i-D%X7G,I/%\0`*!p"Z&1'QLdX=bJ_3G8EL:t@fnfPV=ZJVQk;Y0J@Mu4g3fr9$2E-_V&LBA+c%AX5iKTe.8gP`npDJgOa0,.r1W/R=m4,E[1W79P\uain307GO/qt@s\OM>\cA`=m:n6Sc\d35a$euHnd9s$mV-F?IB8FFVG.FjmeVlX"KMU#jLC+i;Kp%I!R6!P'>2*fM&l%i/==n]1-6%=3!)am[qdWN9&SUXuPY]3Fhjodi+`Ga!%=b.Bu^ntQo[iNOPhkGp(G.o?KmN&aJ8ES;if3n!F8Ft_+r7s"R(@3i81(g06rh7Jg6Bm%Y79ugdp)/<"Z8t_ZS4:$mXKW_A[`$I/?W-oiPGgW%"<5rsp70pZdgKshQ6(8Lf(VQ,OFM3mF%[TV2B*i!(-QIiN".`KO&h34fAQU6PPO&u.qu9M!$.IS$c]m$P((QAfgJel]9nn7DtfGkJm5=9.Lqjl^W`a#Y)Pl#G8W1HD&hJQ2gf"oLHc+TCL=@VOLSb0"rp$LcO+iF4o6hK`4_]Q`S%JMOY_n7$t"9W0BEJ0Dg/h50bDEX!uNF3OG'#.,a-3cU!FAA4UdR\6_:49/_5-^.*iVSa79&-A=O`AOH[8RG^3r4JGfG[]2<#JVaq\7%9l+:8^=t)QV4WV9XX6\G'62>Va8Z!jGu\2qcFLF=)Q+$)A<0S0CL`PUY/F)'6:i.)7/:EUOK.iT3BaiX:\s[=pHr9!d0-'_ILiHW,7tCZS\+C?4sni`eO:;#"XoSQn+?2:@OL&\Ti&qtoU-VC\:OXnh?(i&Lpg3V"@mk@f@*nalWY.jO(/&kp:I2i?@#T",X]At6;]%E"#6iO%Q(#t6t-i#'?S^$X9Db:B9rI,g%fXu4ih8-H!LM9oX$dF[Z@]r3j-ql1WV%$ip:GkZ?5mZia7A`k+R_s)gGh3GEYbfNc8ktu/g1d$F%oB?t.a.J\b33rj>mj+'&KOY30gCd>G*QE/8'J]ABi#n]Mj,W(oGs8PCKJH6A%n$),T)9/KnbM@eV!jZkc1BiNUYIa5U@L1a0UL2Z3@XP6NsNB,[fqOln-1;W<#\O_ffXLD$a::;`IglH_%j9R.r'&??Z#fLNS@DNu>:])6'J$NTohWY8-\H->-*6Yqp5c1m%>LTrU+RIlcK*iu+cRR+=-1gtIPEF*ki[&p>fnHMV`gXhWNQlf7T/"4XDY5&JQ/=$Q+mosgVcF&:@[A@CK3oK>UdT&aR9dGHuS1CTB^HZO`sR$aRYb>]!k[Ar)YqkoJ6?>V=6W"\i"gnc:NJE4p2TcT>pP(`KQECKX2=-^r=ZmR4P?>,;K7,KpkDAPCEdNo[b;m9&&Xg.?I@tTlk]IG8>_Ah.>IUN^32c>heC=q\p>Z&hm!:3.RlM`o:;[m0J?16\k%'ehc?]&Eo+;:@Y(9H,`OBO_88#RJn%4;g^?>gFLI+I(]".kEdiBkrNHNpV/%M6&m!V'3KR!=WY1B:0W@KQQNZS3UP9'>ur>*ZfL,r]F`BojTI6k:Z\+@*_%SnA6mO'Y:b<(.i#1<@A790s3'mqs'FWo#XB$kWRN0f3[:!ipY0gf*Tbu)W5IoTmj)fclEhIh$:*q2aOXUAf<0g4d@#V[c"0J1JY[m$uOeK_TXFr8@mFhR;"]NB_N3u:rY?FD\.\I1LqpV(fP?OL[(M,G^CQ(004C$I@.#"LYL!Y9[#as?JkUXb@"pkc8W^(5o@gGd(i`I.P*niFfFQ_[T$+t;PZ-Lm&gei`3g0B_'$5-+6.3pH8iQ.A9dK0g)>[\K:YP,i25>[_rnc#i-&^7Mjr9.'273T!JZI83aRo]7+qT&j2_54qqq..m#jP)N.PBaQjmh"bO(O!7:%(Y?9YD*,%K4`tfuRC7Ib8r5l8?9GN]0._62T%mld$F#5`NL3Ca`lo1EkuB<kk?dqOOG)/>unG:Dc>U5s-T5@F/CEJM+]t@i!/%2msDg0'%/RVH0k.#c-qu4LP*R6I5D_DKfUMsp@),oRuV4T$Q4s!][cDpUlA`YGZ_Y)EMVoEqWNKUPEoSE%f(i@r+];TMFTj_!3>qN)5pZKDVe\YKuX_!0-Q8e3CKle=Be5\U":p,MJk,uE/Wa+bV_DYnA.[oYo:$HtXlebt9;^[Kc*_&YYGqT'[l/0T2&&,b?EDrFKr/L7BC#N-gOCqQ#:Mh-qWCiEm'HKRI-j.4A&gVRTT=NajrYGL,^'&uUMMS;H1Pm!\kfb>tYs1C[BlH-KHXmAiT8T7tW4`pJ^_"JlNpFSNS\;PEpN3"ok(Aha4\r*d2ZQ2P:lGO$8R5::qCgnj/jc0;DPbfgE)SA37r4.:43WW,k(p9!?#B(Eof]&l\37X$0?54U#VUg-6D4d5br\UcBig=EjS)]c4sY-l(p^+h@DcM/HeoQDE404.t5'>8M@TiQ1u*+.05g%s]LJj2F080l;;p=)h5G/<^<21sp$N)UkZoHdi2p?qhhW*+?=@Jsj+`^m!>lp;`^Z-rCAI%Y!5/eAmZjA_\0=`ZpH6r8IEVJeiRhR`$3ReLiIhel6)-$a5eIanR;qSodH'Z,!@a7lRt?*3aHXr6P1F_N'_?[AHMA]7]^MKq[9?DBV.ej8=U]sO,*I/*6pj[XX=M>'Loce#fsT*b#8+l,J"AK#[<`;0E\V+qaK1k&\#]k=%!R8)@4K.uYWfa122_3jjjIj=@>K+6D"nSb`ppXreS*Br";^?E(i1_S]gRO>*:5$U,:7)sIWjkWCQQl?8&Sn5SeYBj1m4&d+f`?/T-k<=QA[p,jeR]i4@U\%P4j%`$hf\qn!7&7Jfe&gdtlf0RLNjibbE:;9%'j3kHNmFFV3C`nU(/d%_Akidl`l(_2R5$Wr"Nm5iWOUGTKhL?]iQA44es=b,S`="Bc>&mpSuoQTNphZHOgEJ'edNm,h,-A?m7X2E2B'B9'kuM2gScJ5.o%"Zs&.)c\eV-PFi'!el`tPSrF5i[0s))*bFlQe*]_$UHqlHWSZZ_GQ<)edj6dFGNUNVja;7#"J20M="Osr>+E6^NmW(b]-7J_5c,%'Z2\nk20-+T(M[9)_ad_&U@h%8k4J"*0".1Y'6oIG!A.784c;P<\?ZDptBj]5uVKF$gGQ'&S:]j4rH9+&(JpL+Co\b8W&7^W?!3Ws#"CYLEa'c>%aC9%9hB6KeZeX2Ss8)%0..D^(&a]ge#D7Z`Q#^T)dqKdTR54)[QiapATrKb%?>k@a1Vn=TY&oLiu1oQS<"`rSUam`:Me=o)#fa!Qf>[M!O0e9DIF_o`.CCdV<<\;-NrG]'f]'H?Xk>OnkXtNEd\K]6+U!?XOp/L)^'onSbZ*ld-o@DuG$L:o-g-\rDHHb?rr"[u7Uu_C1nZr,^(%8["e$#]dMp22Nq2_49m?6$s$Wo;VQ:'sk,0"Nm.u2tU4@hV'r6U2_rW8K<'*F>]K:dh@n+H$53tY%H-;BX)/?'sE;Z;geb6V\7/U3N?eN\t.L(se6gX($DO'EH_Z,[5$;[F4oZHS6J>q1$dcK)PO,p1'j!1JHGo>C#R%j>#*U28p]i)u>V!k1^,:hVoc=J8l:Tk3\O[Q;T)sr-Q)<'kZX$'Ls']g1.<]*ctqfJBUd8gRr:'OOXb+!$@,3n!%F%DX,CUrfH/#'Aa59RBl.][r'Ze$'[_[,XjNJ+h#+(Oi\Wsqg>SecOmV65hWgo\)E;X:7RHb?%IX\Au5&71c7Z9dt]ianC?CU06h:U?4K)M>BJ15!mi;OZQDU4agfMQif@ZL-,53pqXt40>'M9!'&<'q!U?UNg,].OW[SQ*>IS:<`[sb&5g9d+$nndH@jU:l.F"O]#Z.9POB!IVTB(K[WS4%.e`n(6E#,fR8C7j^GWf,.oTWE(#Hu!T>@O8HKs^i)'a9YYcDBP:Ynh?l6_pir37-VoicfE"bcVAr==)V[]",Je(hMbf"qbacD3>R8o_Y<[NZH.=0$SGLQGqK:%L+s.<7N3(!nTura,0HS`90ssDUkJ;a\N^S6/L.-&i.&QP>34GdFMk(U6ZXX'S+JABS[,R?pq\;(4>K"/h;&H3qLg*)9Q4%]293]92>0D=22aHKf)ejO%]pAo4s5#>gAP,sPu;5J\2D]-VCWO'PWKT->86b+i/o=%h@\EZC=Q?KZGq_k[RtPOQZdRF^$'NIg-['(\ML*uADem-^qh]m7`7=nU`W8@26WI;\9;j,JsIk2Ml3rUWdKOENNq0A9e7QQ&O1We5D?%T_IF;L#q"i1ZZ2MN2:+<,]_@<')8S'FJln95M0aH=r62%7oYQOMP[D;N+`'/#S1,d.gM/F1n$.kY?V#:"cT62(>,p^(c!e%`M3B4NaVT8o@Pj2Zjd2/M%1orl!bX2\2.40[/#dUu6&s+36eOacNfb@aUdC7!sf9MKl.'!<3:+=2KSA%'7h4[J:nQ+)cQ`]1g?cu[WtP&A/Rk:tl2kaJH+4hBY.flhYS4e3nTaeC9=bJc"*,#WZ`c6lcOs)K56X)1YMH*>Edd&0V2`B2$q+T3%f.s("tf/s#L"JtX[];8l>2fF>pW\f_$-5/`_o2T]>akC"u'n0k$A$AfpfRDHUs-64)suKI@g:W<@[A!Jco=Z'0N`jNDCnmj'Ml1GYLP:Vh'=;Whu(_.12eU(U9dk[#;ed@8cbQmb%Xt_-Ysk95@BZgu#a?5,N"jB:q(TQh)7]^QK3@Rr?D\Ac=!j@J)LcCQh!jpZbS\p=gp?[:Z>8V%/dh]bWA'IOuB0,;6O2?Ok;Vg_*rQn%M+TI8Ud+e$pt">:4nOc(7K-uJ:5]YWkS")-8>YKb)_*IHSY-3%:`J#LDJ`^d,GLhE&4nTu:k%1(1_RdA8<+$0!iDJUC_5n$*9rl.[Gp*qL7lm,^mXT@m9#PM>hD^QnuH1B!PN./.,/j\9B7aEM=RILCi??k7EJ.gr$uQ>tNjH]HG\:otY#t3TSSrRBsWs3t/!Y4rldj^rMX_#])cL7#D7m*O>pD;%>QEi%@DV)ts&7Tt2aJa!]VHD_T,)+&,6^Nh_(>1UX3Fe@IP&[AP2Wk#IfPE:co9a'?2G=6s]E(GY?,1T)F;kF/M?6:,l/Oc9nZqQ-`Q!f]@1D/Q]C_dCkqmn`94CKcAB:@>Xj7i9XsiS?),eqT!S\Bej^c=$f;iDI.2TYNe$28bLP0;JU=,,^82PRX>N":gMZl/+aA"0sQLA.H?]L2#9_#MLNE8jW73ZQC8O/mo=2X'HD'Z+6c\HVRWdR:77W\fenK$m9S?s#c"4KKQu3li*>V17487d&)ZN"I`VP(:PPlQFmA+.h=0F2&:oaC"NQHnG&_cG^J&eGoR<;:-V"o8:YP?S1?"kWP(eqd-\jVdOD_g):i*$(%dhnDB3RP8_u:6B^1#UW#$iTKRA]CTVQ\.2!"YJ?D^<"5Dc.!'=3[iDQ@E%$8_T0R%6)`nNX/V.mm2aRFnH"p`W*q,nEmVqj>ZF,S/,!cKuNE]M!]&A^6C4Q`g#7GB@+1[-dRfMasLQTKp9;k=YdY`qIM!.l4MG3jTsg;YEAD=aQ:=oMFeSVaC;[uW6d.s)oa!X%unD_f]H1$M-U)Vd+#:e&\^6jN[\o9JD&\,l?mYlH@*TV$E3odQ@HfJulo3%AnY,ccIY?sJ\9^+#=P!M^hb.9@o*kO1.h=l0T#:OHHjelEpRlsqibriN"aQHLpC;+O3H]%$>/DE.p7s/]+mjaL&)p(3VM0of/64VT7`8PSc@)Z\C]j)e87Wq+,6[R4pfu?)M(c1RM^+%F*iW/J"!48<(2*#B_S[;;=A/Z)MR-Q--gQetJoCost1-6[8GBr9jf=M^7XK-U-$dChA,XgZNri=Bl'O$2jjSLKrQUXAA]$h7`NR\:#U7>T%4k]UWQ7mVXeoBJaKR9X^t3abN+68'e,(.`\Ma*RXi!bK0jr&f9^RQqcchR2^!7%tU3rYkEpcJ,C%F.k0XCt0DnoOC^S@:h3OEu7FjaD9Hqh];(N;M$#>!Z*1fl+DR!r-*h_7.)Xa#"N_>C(&GEgdg_(=<23SXE,j^gNbC_KH7I"n;;PLi?iAtkIRj=?ZFOis&tVX^27]G0+W'TrWYe]B2VE3kmVi?j3ejsBq.[bS0r0J\_Y^_FuilJS>NciiB]C5`;CL8*ZG.o@27Rf+;@L/Q6B&-H$3'kKjdSW>72;&C92)!@r3[oF+;X?_Sn?F;?(_:SaQE/qKn^BgqQ)4n)ZEUn+]F0As66d?@AlMN07^%1`->iFW?DG4?Md%$e$,cRrWA%ga3P,^@MKZkV_U&U8.@MReu2Z4l/]bMIBur!ZD=8IWj#^!Q0D2Jpm$4Dh4\0CLN0YN.u>cgPN7/e&0@uR>]!fJ#og7&W9pSQh#ujl%$hm3)P*d@EPe):h^/fplIkPhdeTAT(CDARrS6pmNbe0L%0cZMU`c4_ft'J]o(PF1N+k\KlEJZQg,0WUPHQQ9"N9o3T([0_;0ecE^JFYLZ_MiohLRmjH^fiL&.sZNpgaiZ\5sr]Lr8BpUV-X$8U@6n5"$Js$to]HaiX>+$&H4:HqRE['k28+/<7C]1m$Dp&X\Z_b>\Hm]7lWckQ4S)\@Qr;l9A.84#JPTthI2+iqg+=W@T&gPC&=ehVRKU`>eWMJ_M6oU,13TQ\.AGm&MY=X4X%,_7'Z$0kBB't&\Z7M$(<9-lo>!uOF*I[$?B@In(C3sSW3TRMBTR6bDtbI['FK3fm6.%j#3b]AI(/i@n,B(9eD;L(5%I98c2LDaQX7L4Mg+&%hsQ&!<$:RG0]G=\ImYIR2!fBUd]7$knjr50MD=C"LPcA)#muo3"FIM)%@.6rE[qGeca7Fl0sACMU/mc9/Dr1*!HVaA`U".O0J>J_8MTW&C,`Q"F:;8`Oju;H&nR0%t@?o'S!FWd(DUF*aaVF2rudD2@=uh2n]QK^t&*)nQ#SW+m.u!2InB$'2I#@NfrP_]b$Pk(IkuAakKI%]=dR2pkC"h1sHor=p`EB10I@#elA>aXT=Da4'?fr-3W#^L?U^7GP(-ZDS#Y/[5=Cl\!7lA1D&\*5mt6N&T*/)0oh3%%'*uE.^oZ8S4OD.7F?^8Rk+4i:O>+lfhh'_08ISJA2cS'')YV-LQ5V2V)&@^"2gWoKZ6>bQZJaG)ct3h&IB266:<121_-8"2/o.O/82P!cO[oe<>&W(EKI`LTN&/dbke1FLr]n].U+:R\1E=G%C`3Mi9'I7?.VUi`6EKprP,fA`K%kNXSo(5(oL`I_7qCE@kYNe'4l>M5JWJ$1"6G7[\*MENHRoUI&5i@MC.1pQeZ%3d\@&$cgea&1)4<`%9E2UDaffGjeo^/PBD?ZNmI@/6+/![+noOSs3Uu!A>kN/:Zd-pbAdiSGVNXl[]?T[g0q5(JdgR8]0+kc,i_8;GR4#ug%"bpbr9cULEFLW(r/RnN<)nB9Bkj88`86m-'Zjgg/J;+K,,0O)2K"3DNq:H.j$URe(\;kJ%\4Z#^Ui*916_*Fk':CSph%OE;TGZ02HE$U;1]\akGc(O;Bq"9Ct04a96K"%$0FtCgN&iHLE``L'\UJaD\eMH.l2dj?#">&-"iT4B&aQ=NWS^:p8JnfJn,4jVPDL8!B0RF8\a1S5R*VH"G\g5Q2f$lQ%#\SpHp@qMQZtm/_T91LB^U;Gr_M:g?ZXNtHBVY($2m)5AZgC3`eI]!R!MW./cmF*6Um`-CAP3W3QKML3S/o'7rYAfKpVZ`ZrkHs4YDu-BWl,u0F`^(WH0#YaP79q#.>c&jIgBYkq7D(ord8bh:sX@S>AMF06#u'pL;I0HR7E3@5g;=m8%\\.&POF5O(&<'E/65Ma5aG,T$c)DRML'm3uNQ*Q5,EpJF$,hI*jd(D\rOc`\,]&)t6^;YDVIGf$uA2X[mU;aX.jGa9V,:Q<:!#p<+e6;:]a5C=K.2s1$C24Weh6j@$O&p1rdDFcW0!W\l^r?%B(q1%H[?etZFb%SHfc(3FV2R=Fmr_>#]rmUM3p2SOo[B4@k+7bP63`cbY8!eB)Kb"[;+W6K*]u9"<#,_:g4tm3PAr'h2i,*\)PPQj)'PYH1K*JR[DBVUoTk<2>OrcRD?48fNL`B7euTADC=^Z(I*RiSi-cRET.DKa6>#8dQdb..JLViC?df)Dq)/MA:3,sOZt#Y4aJD=77i4e/"Ms@S*:O#rYB^4O=1-k>%rKr&YB95e$H16(&aaEDYQ5F++u[`c:Xad+&=@3ViM9`\Kt[HVZJln;%cjSX'Keo5E7V2OncPN8%6niXct?9k"q+AF8.-'SYlD_6[':"fo.a/__EsT&jO,gdc8sf-^4GD!b(_L,19`N+02dH-125Y>>-dQ9\L$A=SU)2qdS(*nD9Zs*U\bJ]uqUT"]6Za.=)#8!,RS><1'rKKD=pNY]m9kWZg)4+d>=Vij4mh:N?W)%JH`UbuD%"sV0D)k##9L9ti+Y#%>t8H@(ehulj4*#`0=\%fX0rSE>uF2??gaSPcGgkG2-PT+j3<($X)h^uM>5/##NL9DVG1Rhhda)s=UfY$(5;^+=Y'f0?um!mt()raB`Fd)Z3$9oQCXSLuE9DHbZc]#+Go-'Un&BDm%C-;AOD-o4j9HR[a7Sr]tjg%]"!hp>rm?On\nOdesUKf$\$2Zcfp7C^DbL/>MUk1Q#YZ4N%9^8WBX,k`@ZYS_#+FF*2UNF?jbs\cruFPMCr9;$!sKZGQ5NC,"MX1B1=)0XZXu_)M0ZOP'-gI'43n4qmY%Zj#V`QEgI+XM1-.\NpE:"\P.kX1]$Ys]G?:Jjou^!nbgiFd3>!kVI,*T<%c,Tq>V*-_Cu+FC*+;#r/28VT,Q?pYjc?c/L&TWW(T+Z_'dRs6D:8lJtqOH_Bk\Z\mf(%A3:9g\;gSh:0^G^:-Xggmo)IL[g%_f1B-3+BFXbi5lKO_@/N4ZHB+Y$o]ecWVJs5#2DT8;>fLd7k7I9hrSumP'bgSom3[J?"2KbkUK"O`:lLK5OZ&i<\UD[^DA^iJ!MN<*Zt:1cEKK+>ahife.bq%2eKBtC=0+Ip[0mbDAt*AU.N&t_idT):66C280WqVOu%=YDU*`R#p^<3q(9`(mt5Ki?4k_X[jU+rU4R^t3D,lZ5T9OBt6d,)*3V&NSO3T/V.qT)4=I.31Y,c.>L!B+ScuSBO[d+lV-"nY1mJLGS4eCWS\Q6M,I[hN1t7I2l]/9b-R;:dAR?c?/7"qGujq\h!GYApi^`%@`sk6J''k?%O3<=8Z\nBC7/g;lKm8r#$"6%2l^p([%75q)VHosJ%j)YbY-cJP(.WM6KrrB11nOEB+'<)PEN7$ln!3"GA)NB'=VDdeN[PI.&$O:RRsq-AGsXd(Y2*aJ1mVK%]P,SS0%^^Y9A2TE57a:Zf,e#6Pk*34*?Iopo9]Z6H?h[e?7dn&bnWG[,pPg>6c+X#^&2.EGj9IFH"Jh_rR2_K]p"_#k;MYGkfTSF:6>"iFPaRPb`-V;@0X.V$NO:Y6;rc4=Pp8mW68ak0X^16H?qTH#`@ZN\lsKeZb/faWf/l^SfdRZl"9kOLhS:p#>'ZFh8cZ[k:IRo8/T.R.k0^LAnU^[J`[iSQY;]RE4,^IT:(=;SDcA(f9?&&`':q)T0CM@h2::ojVNJ#Wlq2VQ)=Y`QtWRfjI)Z7`:3_(#HH(VIJMFB/!oj,U1/s"iX(ql"qg'N<0$a&,F![m/IT8.m3D"[l'To^R=epd`B5:sc]!.Yha:^?FO#Fa)!I?e^!"F#>)k5'eq)]JA,kKA8?5E7LKb!Vc!M:fDpI]Skt7#<#>#5X@d)nW'5Wr86UD..!'1\_S2U]!k8:W*OPf070C$VC,RC'%fLe$5HJqEA8AeaKO@Qg$[=OH19*HMWg7o657T;SlfF+7Rp9JL9hWDl%oCB!A4"5c@@s:_%G/PFARs1sWdU9%`<,7b7[Hn@Ya6W&`Ni;Do(,]=AI`15dE-_8g:8C1fpsFOYR$FIOplTsUhrX)[K+Mpsd_;O,2UbSOFL)Z[Z$dY(5IcSq]#n&cVe]4PqG7MV."F^$,j*2^.'rjTI-<.sltg0HU#^rF?Fj(@;OS?DXm:/rK(\Om"l$0E;f2>##%OCoBH%XbJ3VE!&5dQCbn=='#]Qd4*9.UT*-='3G*[ZmaTGj*Ta7MYc^$"j%mkVW74H%+=A%>gUJ9fJ<#SEYFl*]+C#4<*KPQ+?fO*#%KrSlB,XO4i3(@OKFl!?V$[QAfCIc@tf/:2Yi4*n`4EQ#NS)LMR`K%C:?gV;'=)+%>@2k3LH,:Z'/[NS]#T?RkiR"iJs'E7TtA#>D4_-#5;3,BXMG17^N(OQ$jTGLQ(Mb]GIRj7&X&p?6]_&DT/Y>XoQ``6/Drd,E!3i_Z,OF0I?T`3t9Q'bG,T`MuY->Ne9JNA5Sc6=X\e;2u.9#r.^[GPnNfP%o9&[u['6[Oi8)i\>>0$iM4&]UV-jRf%>/$X9O#q+:V`B-Q&*e[hGF/-#a`R1p,aW0g;]C`MrmP-AL.Rs+cT:fVBj?lg$dmNbFL_RINRPuam)-@4CooI(m=]gZgSpCRc[K"]QT3lX`TE.P\)KYP7_Z_et.]!dp&*1O=E5\RB(mmKCeg"bUW.0h],4pAH!6BX(ugIn*b-,W%nY#+si),M&S6"fTn/fHQl@`t[0QZ6)\)LU=8CS)b2g3QfJn#O-&T(O3bG_Hr8*P>YLLJ>TA;E(A>;b*fNk;r[IQFQj':-bAoH-p=SVugE4k[.&TbS6fUN@oar^k"W6>R&[abP%j%)\J?SPdR*$p.VfUUhjaB^U(so@7N<^nm]/lcZg*$Dqa2KR&'qtHrE@A8]Q63P3qY8m3^3k+$'-sW&#G=.l_Sc')qL]dZnpU9kds\pa2?,r233F/s(ajY"GAsCmc[g!pFe5TJqW8`[86=kt@)d<5YK"AWVacYpDst3^7?rNULm0&^P:rf;l"NrMM@,7h5(bU@;QGDH('eChY7/ge,^<3pVJ*%g=Lm!h\XSrcsGYA7m"KOJk2P^D+r4O)Fus&XKYpLT$I"4*\K@(FMp#%%GIt,_?:\$;aZ5,hAEY92o48?,ZW8$^,R=V0nr"E=Z4EShk!>kh>Mt";;u[mF@1rlp.LhPo$_[md<1;F?(Pf)TbUi*l'=sg-!,dN-'2kHbi:Q@C[KdMU.tkrof17IGfZE<8&Lg[:(!QZ9diD.k$AqFG2kNn1tLhESE'.[-^m;hh8GJ+%=[./G2jfdAXGL[-\8KtbTrce^)OM%%8boZ_r@fqfk%FBP]k.;T3_(g&\,t%/X@=5bUQnM3R.,)@eOdl(!HDYgC6ku/]BEo+PKQM)F+&Qd@hC;KikNk]=2?R[)X#g.mY&=bGK9I5<EjUblb17V%)h:j+NqepG7"DgCdL#M`!*./#Qtcqb`kdq--?4b[FM9^Zk@g;o6;],nT5ar2YV=c=Akro:gekU^QH,NKerUnN/RPiKVP*<%uQX^aOF!H4)0I,STB@BLr,UM@C5.'pf:9/U1[AM>?9pJkr)^^#J6ZmI,^JLHU)S6,5[\I''_"O3U1[!Pd!P%eK1kiO/.oX$rKNNi;"G_;Z1=s3%"L`alV9;h50cj>97)%'1,DaKENkeVSFS>:0LOc*bMM!dKS2qSe15J^ARf[Xt=e[qTeSUokeo:\d2C[Pu94!OY5c>9JNHDFY-,%Y::pN=N(+@I@<^[?cPk+Wk("a![#!bp8]a';5r741`WY-H)[MSa]XU-K7-E4oHK!9T[8`PCbiceNGXm%ChRQA7gnIh=kB2f$U!F>?>+s8KC9@'&>G7Lp=qS#Or4sr,"O)2fTLO'6XD($p1h9GP,[.fD>:N)Y3LdL`X9<&=Gd26+PbPK:@C)[Klj!jZmoM)0")RXD?#]ijpB]FX:.[,KRZ%=d=WbEE\b_Ebb'mBi/Tq1V@Oh[Xu;E7;;be^8(`?5O^S)/eDmr0-F>NXT3-$(-U_`W06O+]%&&ea'98Ao.5nQp_I\q=b[AqkGNS`?W`VD"QUT/r8E=CCE@1LQ=SQ%W43D"A->#3A\E2--/M,.=S:ZbX@!1P[@+(8H(YEb@rWQI5KU2o(3Bl(00%gZUVWlUOT9Fsf?Cj'FO1[ZUjW2Ua4ZfeE2&Y4mjlP7q8pROsnd+;>H&*lZl99r4p7Ap5tMrO)W?1a0(@TeFeESSeipYs_kl>7RDJID;E,"+]Vi+ej:=BMV:`WMe%[r7nm\Oe4@'8$8_7oBO4Q$58`Xn'R^!KnW?FsF;WV,(R.-*aj_5W;Y#;hbZuRSn;I7c3R;Jg!C^fuhKZXh&W;qLo6gS1h#qsV2gTQQF/bX6T;Yt_u7i&MBD.jNn?C*O]m+e@B>g)]9:PIVS/m[u0W.P?9D3U;mYQjiOD,("B7CCJ82uN0`IqcgPr'O_uI\4nMjO'hlo)nn;npXB-9R`?'oX]=S#P98:Rt4r(%#OhQcs!Fsp$C$oe:ufk'3@/a[(U_2TtE8uBSYa3Xu-aN6Su%$!MH&jr5%<@7cJoo;ZB^]rZh_X&iCZq_6b[0N*7cK&3_i"kGc)YLNFCa*1AkjOpMEj:\m8H"k80nPLU-:s%p1Rm^@h>b-&QW0Ht6ig*sT)PGLeom>+dYI!M1uU@r,`j/p_G#"R:jP1c3?PD61D9TrYN7'1'H-'GW.,.'RreLDsom!%qA@Bcr7^;:ChAXGb\2bO*%RS'e%08l(5fj%`d[6XoN("2Z@G4_!]l/du^`iF_j<1#2pB-2!!Lm30Den!HU"uI!U!65^r9_qCSQWsM;">Ug:%1AYE/rOKK#kabRPMtoQQBkUQ=[USUXU,sas$^0@R_Z;JdFjL+/k>N+1T0[<.C\'n"ehVC^jI:B*mRNk1WTm=P#@\PJkV,mlS-7Oop6Q:KXFLCLPm8<)aCWNq"aJf[A#S4Mh9'#`U3T\p'\%k3CEI32k!\$%p@c!]sZ-j@5`s/e5Z$$I2!bN0&W%uW:or-7j)D?ojm(M"S.ofP"+aPdZemP]Y@7(nX)_%6eVQC2RDQ>MfU$'.!bn&O$YGV-s7\.`Zdg66`6!fkS%gM^ol#Lod#]EeSA;kj[ge[K%8opU`hZ$UPPFAS6`*ch>^o+[F_5m35#D_@6s0_TcE/KHT1B>Xc66-n5e"Qo2<8+dg(b)m$o2OJf2UW&5\;_$]F\*0NBtVr(]2s/A\2F1n[#dI1SYq(GeH/j2aHhY+ugBZ(T'EHWYX>G2?(5n[$k8ML&Hp2K/pB%9\l@'NYf-(bg*+`5$Q*j*+>?XQ7bHHH7:?JYt'`84;i:HW1W1pah`%4_D]Uq7g"?!qFPmZ9pc-VClXp.sZNO@kMAHBu&`n(jO,ciH8\-[*&5iZ"3f@(=r>-21J8SAYqPsaMqQ617b)U*!T:Ob8P.#^RBGXdGZLJLlJFZ+X+fdHmj.7'dC#EntC!-%gCS91K>2$q(FN^8s9=,6n@pnq??m=%,7(O:ndDl)AQ&hsG!UjI2bR\Rqao/,hG2aGm%H`5lr41b)H$]8r#&_;[>bm:XD=KseMeqaQJ-H5=S);98O)^I1)Z)Ke]]Y"L;#q8=;IqRp@&UIe[CX53-h=l@H!!!%"uEAJlgQlilWq:te7H8;+3L`r?(&Fc7KKI$'g'-!oJ162j$OcpRicX)Q[7WFkQr1r_]\!rr?8!<3-pn&7FZOB;;NaY:nXKX*sea?!#EqNm^pbegQR%P>TK=s3q4lYRNA3?Z47Q$.@=GCG$0HgY%P$[*/l\$qLkb$\YgUNL$BQWln>8S(`*mEeheq0$Kc":0_R68rULJ(JV7))`,BD;#Cs0qF`XlB>6`2hPtqn\N(G/#B8WGf'pPa-YNWo=KE>\NU3TnV%R8Qp.dmL8&4Q9oKomoRDoHj4GbRe8?X3-le*?2!([/hBMSE)=A*H+gHXmaU/(k&f6:(/or_gb&_!^L40_r>BKNo;4ABm7pSuL;NouXMX_$,Anki:V5*m_cO:0G='fR9lI(\R@bIBCR2QqP;mi2WZ*d'Q+&jAO/i%J&G!h=;PGL3_X14LlX+d2+7MQmaW`Y4_AdY//P#>jf7K9i:f9[h,ZQlCYI+Lnj&>UEZ-\=-rgI`"H;5sag4T^j1.5pRCDJB+4:a?sQ`O<*+r`uXnZ;[.WI@'jYCmC..l-[.]Qi7G8":R1tH!`;DgddH[#!,dAO;_50T%QAhY0;N6&E\Q-a8j9TU^PdFt'$46e$#g.F*0dgaX=-cI`XD3K(-:h[7.eo;sht=F4rpHSKUCJWf@E/=;E,o^G23[@Sjd_0^B7%')%JsJrGPf=Ei>`688NNTl3D`cG5"$k]7:n*r!N\"SYEH`\X-X4T:p[d>V:NGT99P!f$Q,SrZ+s2sN@T"`lNnNBg["3r/nA=jD54WI3Wd3tB2P#3I%TNbRr.L*6qh`"rH6j.sjs@/>T\^e-@hWE']@%lDTZA?sg(3j\\15BE=Eg3@g*b;u#"#C-ar0RlV%1n-\Q\X,N'Yj+;B'QB#R_+l-d&;-\c-@]cWg:]\ZLCGLJfteqq6DPcFQkWA^%G`j/BCRaL1Y[fio-+C'FpI?gcsmN2)B49Q$iUI^KIKst]05>+b'W,6oOr]j*=9uhe6Sj<1iV\1j/"rR?+LJP#HW]6g*f6*(((o)C-i&R^lup\&DVLL1`fAQSj;0I/K-%\gd2W!O>-M!Kg"!jAX0"$p&%Uhp3tULC5gUc+O-2G^P.+Gcd,slIU.)AE%J1`'JQabgH[UtVKk(>1]raB&g[_f4*4ncfd^K>aE%\aoCgBZLkuRKIml/rc9J)O2Bht9JOe=rW,E[(K0j^j"6M0j)0ua&:k-5Lo3WDlo2^3CWU^\mr6mJBq8(f*l-">d(l>j&@g3i2Z`RPmIl7%m27,j[K(J!RnWO:='0b>rk-R!!'[Ke3Ob*a^KM;I%$K)+f5AOhrr*Sg?H5E5(+lL%>1pp"#;;E6Q)@m;Rag.]kh_R(Wob,cEd\f(0=$)+m:2g7E<<,Q7(p!3>C+P"uJgZY9=VLNXTnJL6\eG0B,bcEJ)BblqYEQl?r&D7&2$,!baB1ue.Vaur@!+"2H==;VES(;gJ:e5QJ=1kFq]%S"T_!_g2Dk;X-YCHqGRDM+/U:`;2R4IP01R.aLV-eE=,/Ms=F)b!9l(`1?n&09UC5ZR,6184D?H3(,g2YH11gP,e^PkS<+0)oPGN`ERd@O?='[;+6]&AZ,_C3_4HHL@mH3lXVL0LW++cfLk+Aqt\[<`tWGi2rW`A_?RHE,>_-rA/]:#A:.];U1),JgF#O+BXG5I8q9R7DBl6$?Ulou5+$u+>l.b;UfRn!"Hi$V2ZlU([3&;K\'NbN]&o'l,XrXIb4853(b_%s`TS-81(%,#D>(.lCld2]g::Eeqol,9;NpX!fk%g@K1$;(GHo*lr:i%m\!D$F/!XJojAf_&?p\W9D:T)8Kg4jARk%!I2abq8i%uae[72eC4Idp%Y(E8AGBkjU"++WSd`V\!%Qk[;H)[B>C7>,pU,1.7b+/=>1;GX0nq1:;^A-bMu(s,MI4R:re@T;`MRT'C/"5iaB[a1Eh[7@UujSD[5+b2!YUeiRZ5X'm=V%C(0EW&963AWs$.`bir7mkr%s"+&f\E(>/V3js6JP"ulfC/?D#,jipGUBCQqG]PDXQ.kc:CnI,L0R2XFqQ'/XkA=R8%d!$5S1M'P9Th^(Bq8+_@6LZ1mp^>:,b12qLc?@0opt7?Z:Xb48V+OLn!K/U-P`!M+!5W-C7>7>;6^F_5+@YK5i/E@A,*&L]h+i+QoHXF0`H;=)?A$m19Boq1kOBXupa&D%]4^jdqk:.\j(Y2Zc6O&a`Pj:SS`XVuu)f:IjstZaBDO8+f*#".?!LpL&5d$L=eRWMaITGc"pe`W&8AFD&j/Zhi9hc6)&,9=6\2ec!VbBliR'[VF8W4n+TGq_mR@UrE^Ue62S$[\s@A/?c;Kpq7-b+R6[T@U$*V2;agXc4]u1-EZ8'H:bHC#q?o$.@O@BWHlro3FNC^2E@Tu6T57HDJM"iB*VmI-INd&F'8Nj\1aXt.aYb-#a8Hn>"?=2"&-bZn=Tf8!+a0!Y(Y7'BYs/X[g'r?0:M5aV>'omhDr7R-$P,(eP9k21;Ee9)/Gkhi+X&+80V+2o3B/ZKbGXEAQo$1pr^8W$<*9]DXPm_fpH.!#\3rhtWe?3o<=!Z\%m4#AY3_R^\';)AXJS&K`'M5f,B^69\1&s%VQfcG=*7%<@a9(r9KV8d(6jU!RQ]#)]0?jc1r@ESXjpnDigM3M5M&NC-7_d0q5p#Ds%nL1or0*+R56=?^)@Z=NY,Y8;_IaCM7m0N[l>6&?Y@?q&sfI'q=L1^-Z(\AJ%hRfoKd(9uKNdh.>f7gs\M!E_,,.$)4E;i2m]BSWGarS?e>R=niZ8k4S;nD'_'$,=RKWDdSPl$["m.OXnqWP]`FRH`t9^;HW$)U+/M=Gb=)*6&YMBn-[`9mO&3PY,\:2"!KcLPbs^HHSNfDU]Pm?_%.]b+H^6o)eViq.N(ir1SHOk5BR]0VC:m8;;Sg7q1.Gj_)kmu%,>MtoH2Ou;b]^,i2tZbjdk^Hsg.>u;aRLSQ,WA\CMJYJ!'QS)3;?8Qu,j-Wq-;3nG/rQnM-p_*l,(``1h9,KT]:XSP$df_#!U,"H919th5Uk6Z2k&MusW]/JdEmeS)9C>-`%^h`>j!`O?lh)k1dlKM'(Us:>]jmTbsm>8D*2eAQLAj6/]e.AQCB`;pdpLc[GV=p7_/pa!gd!hccJWlC6h,/%^g::qRbnMMSQs$%0%,DV;8s%Q;EX=/9q,"L>l(fY:S+J6S3*2X/gR(_FBiA0L^LYut#@eSbDf2X&)dU2q?]CH"MI'//FRuBZ7Y2+ba:RrdEL]X*D+Z_=5tp#hPIjC9/S$YD:i0*h-%/4gm[lAoD0*\LeS1W1%,c<'&^lh9iPH*H;Y8^DY89`r=luqZA%u(%XT*/[iI>Jr]33A1*mfGohJ(+[;p4et,j:I:=7E@cOjDWYR-d-PAAOs'm^"DlhDi%q_Re2V@4+Ii56TgmW/e$F4>3^J72`gZB$.EUA=rlsbdDd2a4r@W0%$OH-;.hY7NL,caoupG)':8[3Yoo5I9o`+h92c/f3J98G"5JF$.nhYXHF`#E"AqG/p.Jou?]P&m))[47(^Rh94\lL:L``h+Fe2W-*_+@!kiZ)'g0cP0E9:$\+!Y^8D5M2RHheb9LQ3Pe/c9,0s,LX*`^J[Pnpn+'7WIld8XjiQR:iOg>Bm)FRS5I>Mb.2B,n7WcFn(FK$X6crj/JT",Wsr2_sk@;Oh;bW$@"R<0OqJq\T4ZAI*!I.IUX\M/m8$03-r:f0g)KBbPTBW4769G\G'Y3uHHct=F$6(&-?!mD7nnBgsW[V>?(/>?4p8f'ce"J4M+ho#(?lUdR3j\:kr3gb#U;I$ac@dRdUMD+2!69lN"@"qkk'5IF_CoCeJ_*AuVD-!WMk(*;3Ph\YGS]jp?P]8H:\baM[&#Rc-*=7`(9`XIMOF!G'(B;;Wqqs+X)g##7bhXs)dA?lX`C0'5h09-$fRmnZ3u!s^'7:82WY=PY5nIiGc*hjY3TMP8[10T1.\#]meK-%fY4_p,bSk_RSp@5U`7F%?M5H-Ir-*i!eP.S*4e0+p6f",QAu1_)bd/uB&1SXRE4O>pTeob/1][,8=0,1o.id]3aZ;,%ZCBTA6!6+%A%h:8\O6V-=Q83p=JT2K).H->j(bCc1l>EHAn3fW+=./r;OU8e\2N)l/2g`/4[nW!-r8u8^p#eE\]LG)W0M([\XL,^$>6Aom+LG:&YQbRE1l25$'[_%)#/12,aWW05Y_SL("!r*q5rN1_Uql8L_Ea;Mid,hF*bN7XJ84RaTjd4C$#.GbO^peAgp<@[49aoT1?e[Y7N%OcCkSnoEs^.^%;P/::LCa'rpd[oHPID"XB$3WTl=F%6ZgLD[d:N.#R,e@lNmQENX!prh`f7rars4A0h!#li3tf`JT!Dkd*eAhBjt7Rk'A-:H[N.I7)A@[lBRO\P,']?.:sEMo:IJbaDg3''O.C0&@5AmFM+3B"s9Z;08)3R+ahRKCS.:[hqW;Z4g?4;BH7:V;%f7e`e02/nk4ON6?6CS.GnoL^km0LiJM%6kNl9FVmObZM2@R)B]lGFIK(s<2-7_%?Q%ma3RZkGP9Y`KDW6]&])WMJc2NVScZLqF^RG-5AHdYLGdaFR-=DY$UN.Q`SOc!<1&q`X6=O-[K-=?"QZ]\o)^+U^lZ/]_.@DtX"!@0re@2KR;\_\%AdipLhm<(/GEuorYM?`S,Y^ndu+W-]_J[s^09`qGrF;!mZeloea!kD^AL0:-68DD(?264lT017dTSOFVnr$"T"O:fJ\kJT.+]OEU>8F!N,KT($Dc:*E<%9ej/O`$"6LZ?SE=a@&!IkLgeS=MhUi3-:^<)BGJJ"226ZN9;'&ZY"gIeIdOjL(h,PFpAX#O(TgeMm]WKFY&1O)i%BL<,Ib"#68GhMKTpW8I6VhHe.q0D1%s%;T1_c,jZ7oH%tZp8hAe\F0k0o1LX-"Tl7dQo*gJ0o3CCU20ZY".I(0of8>V)uQHPgCQ',SW%7kB$_1a_b.2+\X@PZt.Q&i$k[#WnS<_L-F+^paT0OT22TdZSYZAT&,<,]?tM%VA10?X;tMqk]?Lp(i&H*+(GkT,"S)-$l_PBZGUaHFRCeK_R\$I'HTV6Uf-3X+M8?:i.bE/!^PbdK(UgL*$&%Da;34&gY;'rWX%rdJ3RCd(ZZ$1?NK?ai53Z)6ns*I8PZ]H!PbX-Xh4cA'k`eW;C-!Y@nu]r%k2XR@P.3j-r_\%Mf:g`JB>+M)d=9(/s"&qN&5I0\APlqO@OKBBr*]Yb.Pa0bq&Fq%)(#p[CX.n+VIR:RGB,!B.sN/83Z(G"0WOqIq?FHn^FjZH%)uMVqu#[AMa7/8Fm)0LN#+,_s!p(HkR1gWcS+&D)sjF1'87q/bB_J,fW=X+A1JP`d'^M-N!SY=?B6ZAE8A)f0kDqeJ<AQQ:V+QPi)+p\>$jP!1--R`!o!PK:`kL4"_QM[?-f8\[Kg,\j>:(T(`.bgb1q6a5A8.RS7WLBa.I["SW(H\FG2Z%?;8LR&p-c:L9]m!q7VD4Bm@/`4%[<4b;R%N:q%pK39GFDkb3ofM,+2XARo'^m8VDIpe`.G6s-(m\Tml/fbBQZTq)-)[BTRP%pS30nZtN>g3\6TIn_Rs8Ll20p]Gk[YEP,<'p)@N6c(IQ'Ks09nh;fZHt->P]!%*c*,ek@HL.1RR%l+)RB#l,0%d"ObHB.MU#ch6%_"gCS2s9BPU?l*3/:#Z4#k?@HWmjr$XVA3s3UatD,,RP4Wi_a*fJ:kBC.k&'n+:P[4+JNncFc#`6E4trQjNYg@`&l*[""U)_L!gnj=-5BbL^*ccX%=[ide1U!T!XSbu'd9KqmC%^T7Y;)i1q[VJE_3R],%qg=Y,EJn!s.b3b5?"TOp.e`SLa:<[7*p?^\!HSToVDsjG63<*t6CC_C#S8p9o'Z/&?JTM.=\9fY!(E>=JcU0M8f7Ulj7KR)YMtH_Go25JTSRdXUR*`[!mjme_F31VPffIE%B5Z4RbQY6nu>aD%aPNj+%YDT%0tef!H9>*"*FUc)&+5>73Mk(%t,L0l3$Rp:C2c&q2g&iM2+n7FK*a5]e2[6K+)1L!,GAf88q%@0;::K;?>[PFZG7QYa!Q[EEL:6JAB(CdT(9ItlSORd9_oR#C@#t@hcRKj=Id*jI3+pODAC!pU-8/QW*bmIGJj?\t6-Vl[jg(Rn`@?GMp^p_OT-719/Q>)n!<2\^&p,0[#+g\-@)'[DVlOVdq5W(.KL8!Q.TTAE]6RRJ9A4Zt@;B;atKujOo#+"2/58$4DN^=Sg8/&g+`887.p4o!4Ui7'fKJn^WJg_Y[F7e`%g\IQen.:+)-N2*.W"kCI[%t6"q'r<_HYD93Vu@+FULjcEQ(HGBTq^fOg#9j.iP?q0mfu.aDT%36mH60KLYa_SHKRZmB^TI/p@Q-Np2qP[-*o=G@-6K@WIcBSJXpZe)PBjcIr]ODlii'Dn#X)2uYY;uVq35o>)$C.oIPeDi%n3R'RPj^@;k9gU+57RAN`O\X0e\uk43lE?u/UOInS6)me]!D'Y$U$tC1Ys>-M=jnR>BH*rV5nN_)+Z^.(L6Ec#LYDt>M=58d>=DF=@#R.G!JHS6M8UR%S.Nu7J@^Q>Dm36e/4.>2"]LR\(a8(qo@d^;'-ZK^&;27TA0h9;n"2`,Y%(\<"TpJK620*I\,TbA*0O,u3j)kq4r(r+`HlfmeT_hq6Usn4a5^j#q.hmO<@H>jT)).7!>,V/CUtZ/rj6pA1BfZI-gSro]nB(m?s=Z3W&j38Ij+):4Gf`=JaG_VRnBHi>j6Tqi5=':.\s\5<*OA#^^$I8J?cS3hEFs%"6%0+);]\WZh*,_h8$a6p1ej#,6YkX/IK7&;3@!!]nDZ+NOV,Likc*N(?2V7RduC8#>D!+S2UH)?A[8pd[WU&$1iYc7To&Y/hCTH>GIS*OXmPf_sJIOtm2@,9h6F%#/2d#\($ZnF+d(eZ"S8\#2Tj`p5\I$Ui>bg#LB36FWuH/8^QT)`).b=f0h>XP1q$WKsehBIOJm5!Mt\OUU`@.!sM?!%6JOOAmJ*HF02cNp)LW:?=SKUl/[SDQBJtH"'6p8tqc4?`C!>c`K+@0B=7*2unEc!0]5WpO%#R7AU8&6"8XaK3JmQP"Hq;!2,P)$:Q+mH0P;L1[fd?T5Rf1TW,oW6"`rd1,.9k4BpPn$_pCMSZ^R7?)KQ4"(K9k&4m:p0oeMV>!Q-K;)!_fTLDiT6Tf8U2$MQW\k!b0k9>5RqececpLCbGiB]F+@%(O,Y4S=]n20-(nbp5Ic21rkh,GQT"4%*VK:o62nY'Sa)8llB=W2/"/*g>P9`rcSo0]Ft3(iAmH5(CV^k._a,6%Be+s@b['E\5S6lLrp,3kbEIUn7e]SI+AN$?=u,_3=p6p)X$m(/8aP!4+PlaQ-2$@%M)*K"CKE%V=[8#\SGoqZmO.2ph4c?VSn7ghL@k4*kurG_ZGLPZX1*@/B#UPGm>$77X/qqMq8LWgpp*!Pj:AQ0K[o.pVF_5]:F@XTX@?.`>!7"nN*"<'G>p%8#hVX!_X"^VcBbCLPmln<`b_1ECV^-"!VA?iuu'h2[F+in$krP4UK2Q!45XX_;)QIYI#gZE<]*6qfi\A(A4KcJl2BrF;:4u\*93\9K1CU\_+8nSB?e0Hq:X'H\Rh:1rE2L.)\$rG4s,s9NY5tAEjdfCWQ91=,ql"bT;_Y-ZZ,1DI+J1'_TGsH8Rg<_6^]@6UfVq.p'%k+m>Ju/Rh%)@3'+[83EpTlY`ruciA8:Yi_T$H7\J0-]l^ENF>OcfGa[ZpehjuX3A5:4,UclPR8OAHVpQM[$q-*D&(gM<%>Y#WD*lO:?2Y?$;rO6=rK44Xkf(dVZ-+%PQ)MPPqIKZDZmSF@4k<"34RH0[h@-dJ\6k7f-b=TnotLT.i(X%P/3*V#k[Vpnt?CX9"0i8bB'0\5D"5R6p@=0^mgd5gjoZ/19uJoDm),oXW7&l`D(pre<'5o]',:QcRbt0ck1f%_Je:#H?4[n"]5Yn@BOHC#6d_nc(I:fQ(g:HDs&WKI/A\3+[_Ibn:`Kea+Dl=gqW$.!lQp4,gHb3`TiP@A>;()k%Qc]582Sgj0/ETU$QZ9_C:QJE-C/M\uPtcugLeo7=WiC1K(r)9r2N`Z;&mkZaD&C*qqQ;;M+oOR6^57!M0`M9s2:89sFE:]S\'n&J,;EdG^'Uu;IV`aWf+NBbnK!0=DI1GYbKSl83]=_;*/Xb0lfja=:JJ,h"0DPQa'a;*8Ot5bH$F#/$'k$e.ci6KS4//-rZE+-dRe^;<>96kup`K66m_b>[]VA2L-(Rcoc0%np#M$$MfeD24+EVo([J`PV[@(lCDi^)LNm4%7!?Q`:O6H&kT&4$BLf'rnM8^\[T5Pc*K5nQu^M7+o//7!Do4/OKLD5J#jS?P#rnW,"'_oQC_P,+m)_G1EUSLU:W,gY:7DPYJ[us1cY1&DqXCVoV]&ZqrmPAT#gOGckUVDf3jq]1K;#]d`'^u1o6YjX*HOc_:tp#&o&^ln@b4A*!WMIT[lV;N]m%\/LXd>MP@,N#,rm#"pDt\cu71Vjer;Q-]uGU@CUI.DGCPVJP8(4lODg\=/'ngh;jttr@%inn+Y]$4>+^A&>UHMTVtha7R4D9)M4]6VO5M$mpP)Ih$j\"5d'&4d:IWGW^/TO)$qC)k;O5'H?g8*JZ$&090<%A]IqOL6=rgI8Y"UmH-S1U"Y&#n^5#=`<7*Z)!m-EYh?XjMn>Bu;O2%k)uL+!,Qa4N#RPP4#RQo<;@X9^OWiohD$pjAicq#FOWFa,%M3.`U+&n[h,N/IkFEqecgp%@r%k$k+S8jTXrFm\m@%$A#G(._8dOq;__YL!f#LNq0f10;l"h'L'oB&>p66unKbcp,?,.-LnXG\)Uq82[Kb7S&jXp`&_(oZr=.7ba#4>\*](aM@tJG]+$A=Ct.#D;EI];,9!4-R(V#..s]C-b5[ir:$IJ!$9U8gm,9msOXK#]OG7q[',?)m6B&%-*PKbc0+NRkhlJo7`N%VM#:!9SG@sf?]H^[pg!dl9gUTXoc1'W+B-Zg_N/r'lm2SM/VH1Gthh&h%C`_JIR6s@8$Ela8,,h7A*=J`/_S$B0]]_;:L77!!VA;G0rBj/Lkh).3F8JWVpNcA.N.DmKC=r1KFW6&aT,".Yj/D=#XY@8Y8/`-C4%RTREOYJrql8@R*l.-lQ%0+JfPcC^.egUNBYLi!3)q%DpRH"VXN6aJsB;G_;uU3h2f/0n=&5A$9cRBcoj%ar:f0a,(:?gOf"i"U9qG"2&.Yg1W6r,LDo!L;R"uh^BWgkFPNV0;)6qsi$K08#(D1_pUL)O*/3D;%Y64fDq\Va_8n!9n<6E*3Y>7@Je8J$N/^CEH?cPBn^M:oP_j$CkOE?cF$H`#tTo&Cct9c?\Z_O3CJVmh1l*?]:UC=hCEY:.FPf9''"<8XS?Q&?A.WiD_lR*]B.?I\;kg5j[Dk>DW7M#%8KF#ENC?@$V%G6(YH!SY,4RX4eP/"7-Y\[;8UgVK$4Xg)oXqAd.c[F2TqCOT&\M**6p_Nn[=OG-@FA\XgILIic?!KraEcfKaU[t2UfLSsj^'W;GAN7:a>2$VK%]:D#f)eR*,[G;RUBkF+kgVpiiDXft;2Icc,LD0=mpR1D4B0a_l:PWmM`^-Za8ET.Vkf+5^$\k$&8)a,))XY=Ld!f0T1If:hNYfj\33Tja3S5DeRd?fF6M2bg\YBu]Ikg&*63bYnI.On=eMCqH=/S.2+!@Jn/`n9$$-Z:DeOg0U*BJ-)b^KZCNrJ?q6oRaeP?*tUQoL_pcHV4CJ[".4B+>oIe[L_<"^2kGU*KOA8V^qP$6urnHe12T@g40=r&M[$Ih+liKp86V>tc>+ZP2ui7,(5CGg(<`KdYiD`dPscjJ)B/rm)an@)'V,:*r[hZfd.0+qY0$9/\eKDVK0mni\WO.^"*n`qgiD)4jL\eS)C17`7t;JqtUWBE7AjF/KgbC&;_)aYF1eTI#dqV$4A@e=T^>TNr43+m`u4_(be(G4Kr=o$tOmo6`(TcLIhj4GnGN`5nk`XQq`f2%`TAi'Y&K4BFlJk21_p.j)kH*SLJLuc)#>e*_3Ku3ThWI_'8c5rjlRu/dSlStX(Z+EqsQnLX`qEVNL8/G-TZm0mhD6X)?duH(h\bdlm@BI,Y8OWg*G)N\[=e6R>qX!N]kb/W6"Ptj-7r:3g0_n:Jqt6BJeW]Pn,VJ/=MjFQ/p)D7/CBW30\r+*<_W`[1,\F%.EnoH;2[]Vh)b,a%fkC4g!0YBnWCgX0\nC@Z0dX^6F!_LT]'=HRA>_,76'174++-8_em['RL43cL(#.S>;h]-\Dk2"Q-Z3_`]jhJGkX[GepI/-#Rak[ICh^NHW4Q`+%N8(P\+:HoZd8&/d)*17U6\53Hu8(.0^8m.[!`j0upt`rCNRliQ5/#Mir;6jn_S]-9QDYn]U;AY;R\YLG`^!2E::8ip%&sgnnQ,6e_Zt)l$Sj(EiPuEL+[NQ&Tn(o()^H,B,TTu#WPaM\6]^9"T&moH*Q(VlIrp;KOGni`^bXT:qb@DVH@:-V@#bPDhU1!]dK^*u6`>[unA>I3[#nKgU3XYf!D$%_ba#F^lRgh-]Z)!k=!)cR\?;Ode--?'UT,c&d_WoEg9cVn$jQ]Te#ZB4H^3dh(3^cl4XJW1h.YAKI!%7a=25"l^J0sEF(i1cV$&Cmm-kQ+1JsZ^BJ-r@Vaka]iUVleNOM7<=`M9e5?\`bKJn4%"q[8]pD(HRp%L9Mp??4$k(lc2Cg,I:`Ve9`8g!#CfE(h[7:T\%E>aOq"1n66^Vjc-ih5\=,6qQE.(Bpm&;#gX/W3^:p",1K-1d"rW^ndVXkU+uL9JU1k6ner1Fnf?>C7CY5BVk2#os=J`!I^[.C&!t^Q@t>B&oO?W8bD+c$#R)e5MOW&WA4hXBFioa.VSJ2AmSBaHKD+\#XrMMr`A>2D@+*Pq!20n5_J::1=_T:Gf->cDgToE)FUC)It#CI`&OlVq>8;m3r(cM$arn1]j43CM(MJG\.IC10FBnl"E,a3^Q;5h%53P^+_N_%s0:sPLrGhq*?D6lE&^M1@@co\n/[5_;gC)N(bX13>HLHb&d%LIq2m1-G5'#'JoVnNQl\RKhg%&U4mi%&Q(@1%JD(:kXX;:gnkmfPIG7Mt.@h<-'te^FO^`GHqd%NXlj1#CINI(M#H3*Y^n$]@5H(M(9$Kb=>7IMaXU'$TDl;[qs&+e&cja'Mb7t?ppk-&THaSh0stoN!?6);HeB6\,D!*:mNdkL?aIK=fM?F.M4)r%P)T-h8HENS7&q[qJK\eVb%Vl?0^P73'26E^$]C,=^GLl9'Tf]h:#<[%>g-$*B\7=Xt+eN@ufTIdkn.#dSGXCCG-!mV"uMTBr&,s]r2b1LES0]CY47n=@FBd_@d5RlLp2g_,=jibWdRUF?n3`e)>);k>B]MfJqHW75XgJe?`'SS.94L#Ra[`D'jAKf\u?V1S8JfIX7[o$+-L%[9=@VR*'-B>HqF*N1/'!eMbA4,>JcNA^\`:ms&^+65"2=LINomn6)TP46_=9@tTWVY>#/R1e&7T^EWfRS.YA!NBKHbkK3ji1!8J5,,I=1cS+nM;Ui0.6._4]]iQl05GFa&$2V=T,l\-)1QlZJPPIl886Z7/Kpc)r@&@[TNSE,Ih+R6UZbeG7-\i=,-^r@%]McI3F_e?i;+eBd\RZ(:ml1h0in_*#UP6iube#*]/7ch:7a(@:H(tWH@OhY&HRa3sTK;^jJI3/nW,b=T9=aj105>]c;=*5[ekQc+P!)3(T@4MfD_dQt.I&ql`Kd(>XfJXgcuAnp?h6LB0%nCdqW;(EoR_"PVOTiSr)LKGWr]BeWMBP/.*Sr)"lntRGZ?2Va,CfWSU+.n)mmUIrH_"-I#_#[pu44j`/rchQOQ[35mN!hpYN1aRa!i"h,)3%-eg4:`+WIIjCT&j_(PGsSdC'B7E&EFGf&%U:Qnj!MclbJ7$b->%^3#Cb@=j,A^pL@;2W9^NGXS40TTqYGE_)GVeANN[@GU'J`;9E>S>kl&CI@XZ+i"rp!u2!gQCLVf;N1LQfHIH@:;7FnJJD6*3pS<_%/Oe6TUQ+E2U-rN73jad27382G&%n9nXcWX`H;p1aW?mm/`Y;5HSA39mo\7%6$R;b.tT)!P[Mq`LRM4<`0CaB8Fl;&H?h#oKYo"pN0VEORiOnX"OYNi6[?ZV97/'>"-A1F3L:=L-BpG;A:k+E4D9HOp'u_m13rR&1es'>_b>rnO,T)l(<2AZ['\f#hNP\B4hC,sZaA4=QkWrHJp#s2n)j"b?Y/\OcWeuoioLgadiAga3Nbhp8Wt?OkXgZmB811NGdcVq0LI-D27bcf(h(aO)]WYL`=lmbaZ43!CO7E\F"8!O=!JlWX;NLUa4rs5h"]Z'.eT:kC%*Q-Mb.Q`][IN3=rC+\U1ifq8RZ9BkHZQl([/3H3qkigk5&'89*6eB0l2Wj;LeZbbO&E'KDDE+gVo@:Fk'6s27\&H`2O-#=kJaAYQAgY_tO_gl^7!E6)(Q4+1q<'?WUTFpn(\/Kb59uqrC+\L.5.HD0T!X><#7a]?-%@"pNbU4i'!)e+7mS:iI<^]qf<('SccNdb^:`tY;U*^tJ(3kDE@,]HkZ*Rpai>W$;3kDh?RPL]&e-RDTPa'm>&E`7@(on)QfnROg-(9UOt#Rka2_\FQ"AgT^`L=?'XDkBfMLcB4F4QOWF'c@qdjJ5u%Cf'FdM="eb4UU6W,TknJW=8?%*:GR&^PU7(Wd$m_$F<##Qc5`F3#0IFb=BL&g)^EBs,Z)9_WrO!:gTesUN9.Ul3(.f!EA.\m:A[%9C=;DQB)p0T5.&X@c-u$[VndqA3h;J_Y2F7/N>s.gh5YC9.T&EP(ZIMmcY*nFcO`ne9AEqC'EH9g(6eL8j+Z":_herhHcM7%bR_tGe-5mQHgB_nZX.X*BpDe0a9>+7ZSGF3^_b6:+bL;Z1NigEDGj=<,;R)t8jQmI`\WDpsZ>/=&i#)[Xf[f4+3"p?i?:p%[8LH5U\`p\GL\;MGO9$UM^M-g;m""[@)qM>_X=(K/K)[O)cIa_@47SihlXmNNaMi-'asK!,1cp!YM>e:90e]81Dj_Z2*7>",_IR'H`!#QZE7SP"pHk403M$%,XrV^(G-]:9J?6h*q?YNW#lT'o,:ep#X3VRJaTfNf5qX0s=i1b?)!X_&7t1'%l>`Z1$qL_iT+'(%%Ws8dhOCCsDhV+I@oc<.'L[a.K-3%b4-0GYnK;s.&3lrA-hCd&c--FD)N*uB$X1UI+I0lkK$o>F&8Vi:E'm\\:9\&]jFJH#_N*'2h/C%t/pSjeMT!V=WhObf110JTY`g(P$V_1KM-X9E&tETlTk>e/<]KA`8]rZOJ4Ii%l!DGDo7-t8GI-TS!k&nt*O[)=$bJjuc4<#Un0;?VeW7HlM)@lk%lrQtW*O#MgXk"-'`E,shTn;N;p1=8sX&Mi=-8lF]#>-eT))]Jp;.#]!nLp0_m+BVYFRkmH#*D.RiBk?rNoeY;-MFB%;g_bZIj&d>]q*0W=o`$+nNE^XnrT#SlA&`P^g]qLd-YTR4D4q]=7V\M:Xkhk7?u(9Xn1nrZahY+,#K/^#fm9G4;0g*Xd+*"nT17Um*/BcFg/,of2:!"84f05rGKH@h8-ppA6N4i[30`hdi9Sf?UDW0!ErT&^F[pJL0GFTf[t.._nm\Q28JZ>LWCI?!4^^(O[pF@_\437m/o@B(B_#_Z)ZGq6`4Z,C!%qJJNQ7L)X'=2:usH3i1]*6E'X8^-C6V-P-a$I_eOs3A_cm*ZSu_SRMa(UfnN'$-N/R0'7b$=(1:Yae1;Wq/HrJE+BbdS_J)%#8_R&JV?7IPAQK8T4#iqDG%3TPm%<:bY[KH;5fJOtLR2%360Fpb&3?OV1)1J8Lil(pS]6?kW>FLne^B*&ke%&F:"7PJlq`43Ae$>:*,E1QlM`ilocV@qj"ONNn@AoJ7PRB"WfJ7c]?;ha=Sl7H=AjHaF-`H'JaX$/20E'(h*M7mO,%E9*n!T,BWP2K-jT[E`/'QX&dSJ`W;SS12/dQsI&G8YF_Nr2>:"!m"sk+N>7W'%&]pGhUBne;d>DbNGl!8jO^H`FF&WMhJoB)DG4g1+psV7$bK]V&.NnA90X58GUTIEqjsKhO4q]8I.*cn$^,RmbMDCmd1.5krTi)MGMc_F&'=>_!C8..Y(p7r34SR(ff\q-+N5SRPfJeP'$T2`OaNkhW#\hNoCr#!u1G"-4AIh3B,D#?HQ>mS)Mqa:'>eO("6p]f".8]l-eqJ?Hk`h?*:=Z;f`*utI15XtGBW;=O3eL)Hbs8oZ[$7^%/M_05h\P[i]91AHYAlrnHhf`c\h[P8_rp/>X='jN1s^Fb*L!d,>XOLi]qfM)XapK`0fhP__2V^H`W,HTPD.;?i+kQ%2sPcj55T#$;RJYn-tn,XNal6t8.X:j*3XfB4OblnC8H*sR%=W2hC6AF@lk8QgoSM>+g@1)gTg1[a)aW<0&W.n$8kR?C`G;HI>k(:Hh-Aj[Fj`.H`365E'"PT\D)@RDSQ&H`V8qVr-OLRVUQ[\G+E[V]]@C<9MAB!Z?OTs1qm-)L=LfAc8&>NFZX[=so^_eq\p])(64_VqFU`tI)748.8rgW1C49HELk;H./SsXUP^iCVM,CdHj_:!X;okJGM'BRg-((S,p#/UUH#S"id?PnBC@1S^h=[%>DMiA]B7OBhIr51?G@D!o0b1]0R#nd(VmKW:MnI*t;P&)X$Q\:%3"[Grt8>h7d;^b!N'Z:?oZO7rTUrF%5^edo['.KurOk4'EQ5D9Q"EPsdZ@<6s4Z1S.h8X"j@XeA.?8L-CLNmTBdha)Z_/`]F;d^2r:sanA@1Y.1oS8(m1"jT%dR&!obIq)4q;d1oOK[3_GhOV3cGE$[9G'2PX'eC0X/SL$.m^AeE0J`STmd^7opZ_eIX9:&,g"5/iMjBMB.:[PHU4u98B8Y9Kh0^kKlEKVOMYODY:-!+mT!c>=;Fu+I=C==H)Cs=Mp9l%4BVPT_uU70Lf2V=8;j6NrsA[H0[C'L.V.9TY,2XsiXVR;kZ[rm[q8g`*Wdd9_mH?H\gCDDZ*O(Ulh?\Y]7_:n3!br.#Jg.P#;f#`e$Das-MdL'`'VTLgRH0:?dMF]%"Wp:t=(8\DieQ*t"ZjuZ4H2HagaX-6G`M-4[JDQc>5!WkXn.`9/bph0:"F0j1S:@PI#nm)DQo>""UYAbPpmD'E$f)htI85uUaJRt/h>Yq+VbA3>Z1FUg/4]lQ7=69q!D'.YBWW3l<46X>R]b5lFFfouB!GL@;/L4ffiuO#.B&-J[4Q,Oe?hpsK4Mr\"XZ"LUt[5!W,3h"/+o*,Zs.4O's$)#1&dl(3]3BN+GN#'n7SY+?B`0OEt0l.CfGX='*Q[%$OH8K\Eo1,"c>S359m$uqnDp4(B0hUXHqWZMcHF1,B:aQ9U.raInDPl)X:I+>$Qcg-0[gP.FLaTn3gS&rME;HKePiqmp(iG;d%3O>81Js`:*pQ`_i;$2Lr/#'\F1\;K2]$QibaH43r2_E4X$279EZQ2]8-33Q6@ItisZ'AM\<@P(k@(OMZXSX8N#("5fOHK0QE15qWTjOiQ>)`jqJuWS3mJdKk.O`(EM8$;oE;cE#O9aAdlL3PgE8WG0Y4Xs4j[FhWb@LCMu57=>6/ftEl#Ir.te_8'Rk!$FXUV-JJK7MJNj/$U;F-W];FijOL^3H;jH2c8qg8EpRB2-Vg-gbV!;RsUn/][+qUMI_N_8Y2:I_'G2ecB+6;Jd(/@X5>7"HlmUHY5]qao6\%_"j.6/"i&Ic_CLTU+'iEM^L&4FQVC+O]G#>uHZ(.:6AdkM,m86VP.jj;:^\XY+GI6rE&d0/sl7-5A,cGr0j2"*-WCU9C:k"LMtpjgKY:h38[E9#4l'EjU73__Aol(Sg[#FG%+4K"iVB;NKr9C7-IKE7>e:L7;3W+_;)ET'V4lO5c"VQtc:O"Q0&8bW)fIQ*q/hquFEnt)E$2mej$&Ys4XkMgo=:[P'gAZ4ZpA,7)D7J),RAI3iT]^#R]fC65t%Mk[na/k_k#NC"=]PY-K>$GLsQCD0TdFUDH=pfC@.LR840g/WL=WbjkGmg^sW5"$^TPOYlB\JL!k:997b&>eceA,q+V,fHA]=R.4%*tp23W_u]qTS9\b];MC/NL?&>]b:Rd]8_-plI?+A2T,F=aeJU;@%aNL2-q9>97[!@h@?e]/o"B]%`B[*4#D+GC$9hW[b$Lm+MiA.A#hId*cUDK:PB)a,Qq)Rj-RTRnHd\CTG-t$7/TpC+Y>j=uA4];/6Kt4>u9aKgkd(;qSj7k&)@O?ltOELklBA.4E?'l=$UjRo,RVT*9i-m&7Pn+co(5YgN0+d_iR22!crcaW3@qm;pog;;bHBLmdA[_l(2:)%g=j.6$'M3Y="gQc)H,l9]Qj7(]-r)PTl@.2FE>QIMn$"Ta.Y,>>RlD`-J]Q-s2A8s?oo"Mg^eiW,/L@TdX_b6.NiPRW^umIZ0/Xi$=s(2Q&rD7^8"!^m]tIWT_E20#XrWiE)!Wi]At-ui5<2b=_2+n`4qBeB2?K8F6p_Mf3F0`C`$TZIIIRLeGiH=45bfn7/^2BWch&p;k8XuiJ'[S#Yh9ZkITm^Ud]\iZ`\k3>TDSP%#&gobGS>3<)ik2(C<62D7N+,`+9!uOh;E*%`TM;('0&r7*-+XBBP*PkI6LjcqcX?5e;mZ[<_%XjmB8tq

_''>Vi_$7OJ9`oegcmPg[RE`B[E\S&KiPCk:dM""YZbr0Rb7-IkREG5[1A?E$U*gUUCIOJ:.=2*PHTpGO"q>NAsA_\"n#Ri:hX0rAjJZGb-X0*NHYn_FVe9n-$r;aYtte_B(BcPL-%KrUd^=iS7T8Zgdd(?BO)),nDH\H;KL18J:bba:98%b`ACVe3JqrkRg[@"k&+L#.EiTM5(:4N*a#YWiCZUZb'CLccT:IfjZh)\J?+$#:FJsM9VS\C4@k1QP^@88r3j37gB@[:=GIIRb%Ws(Zp2GT:e^_m2q5]!7IMZ<"TX?61f^3!<2Ue;@usJMC&p+jYY=aG*]i#"/(Ql_<\PHTU%ue,U%fe%8;F'*iE!5LE8,@KT(lAXoerm64tC]11`U=_"#.P]dMj'.jiW-^eP8:.;(`Sg/5mMIC_%%@W+r*$`qL4^ZgXG2LTl/Fl.B61a5pG8NGlDScf/?&j[N]btTFq6bB-h3C*0>\O:U/:)CskkYUKQ5`#a_!_E$8=rf%tL2;V:R6b6mN#u:83>$oE`,"ZnA](h<`C$`$Me3[.E;kg2d@l--:p1+['3SKSdFEao#UfeW:aWKBM/9;:QRoGjU4UHpBbVq2PPb/D3haPeSS6t9TsA-YNQ.)T8ZXcZp:R\OfIXIn3FH;($pa8?RMj3rCo&$%JQ]rsgl`S@"&P0oFHERiKNKZ;R_UEW,S;M4Sn6UZA/6`\$A:!4U9/_n?:u2r(u3^(]J>/-lO8Rt+q_s:_f?7>m9#@97NgL'g+oOPF_L33F4MCBNQ1-+cY1mb^+09D'h+gc7n/I_o>4aa78l-bEitu1pEE@O:D(;(L9ho1n>Z(CEA9Ck9pnj6i(i5CScKVqAtH7JOF=37R/@MTnoC15XZ#,W=ah:?qUN.;.3#3^_A*oJAAP5Vs+(]\!E\N#GhD-8J^>0dObi;'_$^@fjc3P#bEc&W@,`$A@/r7Q51RCFe"HD)SQNWblU6]j/Y?!>#XaM+MnWFWmUS:!Qjno,3Amhp2krE/1OUAZ7/WX'>dQcY`0!C."N7M8+s>8Jq,7?N#GR#;+WrCdQ+TA^s`=a,_EoClJ`sq6d_\?_Ml94f,\@CL4)3kVc-<)^Y&1=YBhMg@Q)5iO3/H'PKG"E4m51-G[8dCi`1f^sb_-H.U*TuJC*nQ:EY(LA!HBP2QspP5J]0BX*3S9_Z7$jt)Il5D5R="qA=oGAR!3DD:82>4E,J]3_#4-;m_JC:#iu'^^G4OGp=8SYBCbZ1%chlC?gTF/pkTtmr5J8a<>e.nGPL[<`/RMV')Zulp"(L>7:uQVV5DP!:>81ao&j=!GqR%Z^584++qY7rrI7U+RFdJ%V9[j)A!S*+G'4*^"W7tsIrm`i%Vf8.9pE&:7"G>7c\q/b0TTt;(VG+C'@pA2+T'8J+m/7#%kl-C=JJnRenYu!Pd)-$1t4smU=RSW.5P*>2J%ulM.FdeHbU`sR@A/3q@a>m[jNE]E%GT`h%Q-d(sPN6:ni!4NF]-OrHC(^UDS#_na[L,M\]k@QDd?[2U1+'F"aF$*%-#b3XBe9grotRFR%^WPfP(Z&Z]L/C?kOa!QTKfARqXHr;\'f^0md:gY2W1g^F8I'5'Q`Hh:\ndk1tsD`AbiuGSHD!b..LjN=M;Yh%P?uPI'`A9./D#d:iV^'ja,7^lanOsQa#=)^*0[@K^C-IEJ?,Vj":OAI:C0`EBEeBrp+s\_97X2^-KLX4oS-n))O^KA[!.C+&_NY*Ag76g,F/P%M9H]KUr>cONP38+MoYS4`?$-mX]V3\$oDX1$mf=&n@uK1]j4NNu#h)Ic[)1,d9J2?qm`'5],OVc:f@%?4'hR5Cm[9r2q^-'=okZYF'Ke?q-aCmJd.>01NC,#,,\^%^[@kkH9^k4_)i`?PrM[m1\%bX5cmJG\D!%:n&D9j;;=Z;mjX;OIg+'TbXG\ig(/VEuh6:>eW9?B2ZI9YqM*c%u[":t8NJV^YktlC",:nSFZmc^qR(rgu#M9O06r/SPkC.9M)Ae9d8)6Xnefh;L"=d*#]e>Rto'g9]9<>j4%_K6r[SHFDkj`sLUd1HqJ"UU:Rg\SMB%]"Z_(n/f7F0dMCe#22OSlWJ]VLieB>!?cSm],&&Y0gI7>2Se$m"=K=1uHJImIlKlH?9*36W=+U'eU'dsb?Xr7q'!gLS(Pp.r5"BSe>3q[[plJ$qiedInj6=B*HmUr2\(RQiCbPGZ.R\4pH$0<9@,D)@pSNgHqk>.d4JN/8O1`EA*US(?aE0+ToAO,P](nu.i;g:,rG7,o=NPTZHfC9_t8gl`:3QN0\gOI5Wf!,@Oj0MAtBO@m6e2cdP@3i1V,?3?V#K8A=\TVdp:'p]S7>ClHWeKp%ilUnG@m;"#^:H5oDO)";l\(OnZZ.fGL2_9fk[bD4@AW0&Xoo(*_t*X2#aslq*T\/_k@T%2,N%p>[aQu:P^+1o_ZbGmN%KupZp%[N4sA7*jF2IRF=j3gEB<4]]a0&F!Hl97\(Z*q3Z!D!ZcEkULUX_jI@nQZ4fhsW"/58Fem6:A9l45FQO.(QYmY2>/=-14s?@A^A`Eg);b[4n\HqKN,:_;LR^;h%`;'H-GGHJ2hrgI`e10@96VO&5!7F'Fss,68#(`.`EK=K@<\04\qFVB]I:[;l:-lX@5,ZT8jpH5!fS]W_+GqDJs3Fh&Bhg_:GLhj"ps)pTip^kS5^LGH9)J!/(mdO*DHir=)heGp)++-7.lnCt]-!,u4;XV"@P3#rt+tH8a/L\VTC<9mQ1>TtX]$7gl[r/S-[o/]T9!J<-0M'8,i38!8SY\pEW`$oA:_!Wt$jkjFa<[noU]+ao.3n4q+DW/KYfT@+LjMP.:aB*=u[^t?jB3bC1`Y+V_n1D+55.?<%9_Y?IYdT0:]E.p91'dMpI"RUHI:/P@6:?nZlBP2Ea[B-'ZoIXP60!`^V-PaMng#57c:T/3keO\5@%,k;u/fVR^bcDHA\4g`[KGd!2%X<2?>S"K3^"P`gM0Tl`Z]I9sQ`<)K8QKeP%/1mE_+_[U.5nW1$#6FR7Z;3nDcIIfp;\0sPXgU&GhZ:.rXqe-io)bt_8j@(IETkLXX?e+;fO;IGbW/MmcR3;i&*`DM;0+,r31bMGBP8\3#_Wj[F?'@D8`L'/t(b,"XTt&I1\_6aGE:FKl[ue5/;#0Og?a\?BtnfAh\D^LLrPbjIck:25F:dZIR'AF]QB7hHnJPcTa*4dbZ*hiBUZ%[NqBMhDujCO7l#QSbU.rO/dBPPE'p=7=i7qp.D18g8MeqPOeYL7!1m!86n5`sM5/=m=OK_q[Xgl1A]9ThI[S?1r*d*G2Xa7*u=r9]CFf0ae+&s!JMI4gNj_1G(C=,\6R!,iD$pCY_A?EN+r_+k\CYcR7V@,OX*Zq&/L-(l@2HnqW!6\^jd,KF93>Cq5/>f47!<\c[5l:GWEM"TJP*Pum;L^t7TY5^InL)hW\Mlc[j3.^NSE-kt8F0`0Q0W*inpBA$\D:o,rZjJoaO*B./5jn_W6a]F6pg2g?D82XPb=h>#qD^7UFHJKHHOp;Y?A9.WE%r5^fB@;-a_**UgMfhs#uluM#q.IC;W6k+E/"^QI9VE2FQBt'SB"8PVp%N[ZO4jgik7\7)m%)2/EF*MtA`77=Bq^l;@joX-b.EA4n&#!;V#V7ReDr9_:?bOH<$8Ad-&/d*+'C;8S`_P8PMm#UmDc?reS\.T$KY&-r=D$P9K_c99Q#mjH!:Q;S6g]F?7\8IS9]VC/)1KdXq7;thQr(=_?[-MrTr&HR]o7Ic6+&5pR,lO3o)_hf3B%IuOC91mBiemYp/oNu:O#>,l/f1n9XZHkG5&OfT*T0Fgarr=s029n#)9L-N:Uh5O8p20PlgM=EoYeIIr=oHcJBW,&l1d:9$PJLc`"`#kqq6i8pXTSB^]gEI(4cP./M'1Y&1LN[-?N\MCGrfYSP,_HhfJVmMWRNFWSt[30K5U8/]if/]VG!6Z7]p@=BnJ&q.AO3f@I]YK%HEdC=R:p:/4*].iKg:mI#d-sm?[]G,9V,D6&0Yn"+s$tgHt(a#F2C5L3FL-BWq$4m=ogg?KP+9h=>1(abuiY2T)SAGP!ks4!;5Qbsj0Fkt_N:QRh\1hrScLkaFg_;6]=lObhYchT]lPgn*1_sZ,%Tq*ue,8:HI3@MtlI0ZZkag!0shP__*7XToL?EKLu^cK"=V0h#(eUe>6PHY%Q?\UK36D-R,-(Xkb_I(q/nG2BW/[F+\4I%RI64c3Z:aL1GK/I;RQnf*6]A/08np9+K5JX29S[XX/<#D[]^mU:dQmq!!Ai-a9,!6j/^S:b'V4q(P)U`WT$#I6256+gW0O[`:*:pBRiMq0@7uc"RaUJ3hU;gWZS$2#^C:!BWnr,@"\pZL_)ft5]Bdbe!,rDS0a;ohlu"OrWPr)a)m5aFXa=]duRTq*+28MVXE8I-,$qu"O!!>E9dIaa*\mSRXm:b,DU')S-cW;0V:#$bn*n,G/Luu\^#ZAr30lAQK>F$[qu[^Z#*3JVr">n+&Ed_TE+H=r2(>*Y_76?m?q=H+4>_gA(6_Q%+RP<6rq?Clg(G=sg4V#)s`^8Brmt+.*<6F-:`XJIR>F;/WIc8^%pG,gBdt+pfBL-[\7=\h&Q"'q[=p!AX>+(nY:_!X!eBeYE+U`Qp`,ZUC!JH5VH/OWlbX&4`81Qjqe+JTpP_\OQTM,3\@Qq+eRS4`^nfM2$m_71;_2,NDS2.FuQu[."o$`'QE-dUjoVcV]*%I@B1&>P-TV&YS,T12VbbaO<=)iZU1?k#D+-nUs)BG@&jP,YUDJ.[bD64BgU.Fm#p?O]cJ/%hO,TQ,3]^aTRm93;$%/c>q;I)Asl8S.GNP=R[,K.1;]7'Q;*b/!e@?tWCg(UUrtV.<1@B32Oc7#.:u2:MDe(CNAS%K]'nbQ=Tb2M"4.EV(>@a@MqgpG3"HfZRJa*QqLsCFrd)$r-+\4e,sS>BaMKQOGt#Z1[QSFJ:#K<@mff4'pVDH,!a.-=r9aB*QJ)au1VP=Z/`\2b[j0o?;`\lf$T8f1qM6l:_r/Rmqd9OUg+,AMn+mD);5UaRr5,h*2)**/$RAWnr@AMrFk)$(0h`2=$=$n)lcYbHq',7LIRK?@s2n_8"R@AaBpEi]q01RfgEVOPf"P2V)>-R"XQT2mtb9?J9)MAb!M6qaEXq'I-`^u(.XB?>mQ)P+<&R!oHhA.C;p!hC%1+s@<=\u:GG,4*b_R<%B&/squ9E;25eOX?c5V20tG$]ra,d>&!u@7%Ag.3-YNFig8nRAP\('^N0+KHc)m8C>:k/Q`053^GiEE>$>kOjabeBE5lY#I$KuM1K<4aTEbRmLG80#_OH)Vofhj9G*sHV_8$*)*GdXgrWP.Nh>>::gF/-:rgfT&Lr1d6>%.Ni;T.rLjQL&?N5/7U9qqnT<"`[^`Be+bK?,<[Nu<rNt02>t*E3Y!DokrDD8<2_*>;8b9h[R:P#`'9UQ;+XUNaYVGb$fP%Zr;9/uSMu`q`9IDL*og]80+/5q0ZiMDP.LHgL!)H"p_m;]L>=A/DH,n(=Bu\``Jk";p^!J/"7>ZGW#bao]mfQ(_Hf9m4"6XMc:3uqmbn3j)W4*f7O6K'k`lRIScY4fEj%cL=,L1&3GVfh6?0c'Wge^WF\T[/*H+eWnQ.fTBi$gU0]#Z$&k.J4=h90pC-%Y"[;*h!0F8I\;1;*I@d]aU:O&'i+qu'b+VN&V,F6&JtLE3#"jb(:FpM\RAAQR$.On`3PXR"JuOV6C*i]A5Y<%!n>TR\lRpeg@;/K=,jZY!5Shh#f<5@R=H,D6:IC57G=$=F-b%5J@1Mpc+_l^6Xco&j;EKgj`-FZZ>?Vu)fs:78/u2p[\\XS@g+HXUpA]I81Y$sZ&JcnN!^sU&M6KLM'Aa]J7'i;d`09(A-3t\XLP>59jM&,9$;0S,&\"qagg0jaSM:"i6\mkY(U,D9Mu-c.EhLh`:p,ems3",Dt)#3r/i^Z?o)^)sY+k$lgn]4LtfFImf_[a+d5CtLueLo4WoJClq_\b-O9"OZ'jDP&5Qq)lX_-b:RPgOi'Q9*rX"nD4:6.?cL6mI$P44V4C0=&4Gb*Z=BNZV:5]S;YTj6>shW8O<>EKk@D0&4'1'GE]#]tbk&u:dq`Y1qek)qe4-5i!f2+^JV"+D0pI?9apR,B&L*=qb;(%gLrg#aN$ZJ1_G\HKaoc+T$B\dCQ^L2YOg>Bm?-:Aj0Ju7B+DmE^3ALZQ@gQ8Kd1J*e^tE[DPE'2]&V+XFM3+M[jK(%$*/7T]OWq;%dBKI5&Ju4B<$90e`0`+\WAR3U-:/Ug"V!lB2m"]!U/Y+=Mu]k-,gAcO7Yj`j9s1\)f2b9;p.p>%=0J7bp5bm]j?tdf8%fFZ]:L=QePcl\#TC=?e2i:5W!#4,V'mFs/6IuWjc]k"GRkaps2bBFc]ffE8'X=)VENf5E>6B>pi>j%QI0"-c8c0;>in'4oU86Vb=g_;b/"/_WRk936+$WHE4`*()'bX%?B\k[V1\V@ll4k32]QY2*qBMi.N35&,QcFK9_!'Ud(=O=Kga(^j82:7m/dl^M'E>HJWY?m7b\+g7*S$M&-rN]J\FIu`b$s6?S[0")L9F.ofYZto?]Z_ThkC#P!q`pr+g^tp?AD*N+O@_Z'A3EZEf0PHWGA.jtQ#W*h5(FmpP>>1ecaXO3)`\s#uF!g:5VGX[:'[nde8qe*1IsN7lg.@qD&V;/-!i?6("\>:-NQGjT&O:hM"nYNHEDn]T5nF*VuC0g<8&RE_.FEKSP()HBg2CN+=eG8Y4ut"p_>l'C4fko8\qkKK>.;!f#WqJHACH84!kTW"2^%!A>Q`l6.@IU'Ule2h[#\@nr[oPOe`hcd%,-ntTam70[U%s_2&gppgJJ9MD=ZAHZUBF.Vc-8)$aJ9f_:Mn=-,`<,>&l$PiKTO/Be=*H*WuGgK)Y@SjhO+L=:_A93n0eMIktF`'Alm]>RN%J?boh?9!7XI6C6E,ZU$O0;R&YSo!"D4p6iq!HYE8Z(IVPL+oMt=Zq)7,(X]hUH[\*tBC9qVc9jjH*D)H`fRrT\"%)b@h`HZi%=[<&W&G4T[F?$$BeRKHNHrXJJMp85>.5]ccnU6JkId^,86aXoukR33H5G0G?0IsXO#3+&ZjR7PP\8IV+6=1n<+P-`7%X:NVl(ne+io5eBTb`>"KqARL[8f0VWd!`65V0olns==Vu]^UrUpfSB$(jM,*O&p#mcK@D3MjD1/dp>Z(,7H(6U.&C0AoRWVgnn#0XrI8/ea(*>VET5cGCbPVXYP&`E[kj"sPL1ta3`G*'dBuE>@Q1<"/m=p`[T=4^lDT:e;6E)u*9[Z@8kB&*<]QCYL0BRTpi>6cVkb$NeFWgrdr(E5I!!s%*;iI4)$:^Xeo&4J%iqVD6C,#ae1?TOGNe8#CVTsXM"?Sk"=GW,1^Y"DAcLM:HUH&2TM87@Zal0l,__DbE6o:B*+Q=\5,FSUTAMiK0;1KaH"pslfG,d^=>*I]nclM;IgW["fM35(+h*L?C4NI!q"-;?s`jj'oqelgGGVN/A['*gf!A8FM2DhmC'J1G#;-3GP*qFm.7D[#dXg7k*CED>8AiH(q$<:3&J^370QG2l+ur14<:=haZ:PN>)ga!\gE/0GHe%R^+;>)8mdc^4@?`>G^A"D+33nq<37*Ch0V6+"N^6qKQ0HkCDP+r2$p"I@UH8o7O^V#^2;(<(rW-G03Cf&LMlB88ahN$He!$8&Ah=F)@$nB&RmegY_ouLgD5("Z>C]jmfLnEJM>NHio)t0V#690XVcNehYbCAePF.c1DOdR17\o/NK&bc^%V0jQB:JK=Fdc)3d_Fu>J)3/J]bsXFc3cPH^:K]LuI]"brSTF+^n!Q&0k)Ki^dZ6@stpllK<3\@o]E:[K^ZtG1r4(k58Q#\X>nhF@^"mkBhQ)I,^;6(,*ZO#se]'H&)3]#D,'knAtAIYOJcA7*ku9WtBe8!^WK_^MdCsJ:8ONGB;JKZ%+fW]EgfoOpT1#`00JucPGRHV"[?,F"(1r@*k'#5q$leqZgi!c*N&!.#j-+/dZNpgc-7Z:$BU7=Z<\Gk/4/p:q1i^G?UD4c=P>+]\o+3$Q!#[%Ih%s3e7FD?.O1_^gX46:IJda]!IEa-gWf,%WHN(fm'Rbj&hb55;SHnDs_kTA**aLpT)Q^#qJ]>Vk&OJ`RZ9M/uNJOb$#V7o&TlOPJ0ce7C`mF*3+!%,kje.f8r\@%Rj,&46n7M0#5&fm6r?6:i2$aqSr#aViQ5V6j/Ef=6CcaOOZs`Y:_rA4,:o+6t>ZX6!Mh,h#oe.;ANaH:6k;n(/X#)s.Q[Q[o,`3.mP*cfT,Tmfb,Q.i0HGn-4=u"&IZS+#?+/n8nWe-cD2qDptW53[ieb:ud91=7h>>pW]PMu>`@\Z^1o-TQ[,@JX/\6rtV%3jh7ZmJI3KZ3q2CqAfnjsCD9Sd/iq_LGMTGh:=-Y*-`LWd;@I:PEmPFAfXaeUBH$T^SXD9eqTj2`jfMET@g+%'#2*Q&-h5T3ca5-ZCi^!DQ$_NAfe4hdX7Sq-!mgb=#k][`e5!Ba>]sd5.mgI[]PhU+eio@;3/"r0p>]R;Jg:7BC@:Ct7nR0F>/[:kjt'I@]?aA"jJACD6F2=$$r.oH;Ak'!k?psBj!\/F6'IY&2[/;K%IeC=\(chI7=QXOGA_l$(U**:l93%RWDe^-Sh6^eQbLEEcLWtn@rXn&;e6jd-($M@%k^#-Vb3L(')+4^E`1ecN$Erdga`nS;Q``iu:_A#H_"CboNG9k@BWX&_qKg;@>bo7pj9+C=3YE&J.C_r`V2QHro9SAL7msG10ddE$Be4q"U](\`,=s&O>$p7ZLm@Tq;0GZJ^XqsHL<^`,Jbm/OjpjaF-OU;LtAD-E$7[P8Vmct(5#1t(ec5i",!H!?&_Gl*&sTsL>%TN8?%I^6@jt[k!?HaCHuF#">nN;bn.#Z=>24?KgMY?:s=QY'ICmaZNb6-PnRn/ZK>2u%,1kn9OPjGmAcJRjeA"f0PR8#8OPdq`L,A(4Em12:*lMn*X-VuaDhV>l=Qo7'4[q619WusV?s`&U'Tjc@0S!1.-r.Sl.XBUaJhSqQ`gVWc+:Deh71,ZG0QeG1G*M^]<_ZOYc"DZ6_OSdGT,]Oh%"TroGD`V;MSN&K4U._^qlLS&njtlRQQCd&WADO-(2t'-OlN4abEJ%Ec,q,jk_3s8!m+n)dF`k0G(O@=Z&V(=R+T6%-\)'iAaaI%:g._`1Wjd1NnP)$h_EW.BsXOGpE^S:)^LCSES?-Qm"LmL9O(?FMr-2"P+HV!\g]>[a!cAi$;E:S)[6t(.W,h%oiLfZV!ui8r%;g[ZV-g&uH+GW/Sf#F1$XD?pQ8p$973)FrD?RL`V0pJB9i\83K>+DPK+#gn!D]4i4$>U^FE2]<\:[mQC8A:4URDT;%sRhh3mHtSbGg\]%Nu)>-Q3"!7O(rYQLBNA1QRH4!7*;&=?u>@^8:N#XFK78_@gpV)Y@oNc#0=GM%-io+0,\?f-'O`rU0%/#M>4$.%=Z^!us4K3"c$88@J@6,58jj;];a+H%A<7#Du%!47!$&.nAiPbKXG[gm@N_?!8@$`<9tOPUnMdbMX'NKV@]XI**E99$;d%SXqpJd=og#$Y4[2MkR/Q*bD';/I(a.Yo4(6^]*+5GbY,_?f*T=-k%e^A#KJ--SP9;GD/+bW%aguOd(2RR79R!]EpO.UqR9C+g]N1FcJE>**O5#sotmhILKe)_%SINaT*+pSck"`qe@*u%YFol'&?N1)fJ6UD&K!)3e7WUH,q$uLhW!'Iq)"#YIJ2^*Nd4BX'oqn.r?OT)"Y&k,OBWb=9]bhkRtVIl#pN2,V(gEdJ4'fK)>1mp*kC2GfL"6(.EDiuGT<%r>hb?a31WaK?NQrK'^I/Ln/L6q_g*+3"f[=OVA;)XdlM/?M_c-n:S;]c5n-+'#pMi0H%Qh%9P]57"1!0uOJV7.'J:Lp"HMPE-F6ODls7h0VW$?9DhRheJ[rnY\HpUe'orER+],5:Q4\/T.Gah$*Akhm12A2V"YD2Ons7+&=YeXJ&H?m,1.<,*\"1Od\ne/tUomoj\8!t'='g$[41;[fZmMM5VdR*!R^LmqsS(eY^G0N:I2LTl/(I$kEk1oJ?5NXJ18+bIppKT*P-@V-422Ep0F!;_Hnc3j$mE-RDKMGD'5e@&csBcU)(^5.2:_GK$3)lONCp#rL5/#+fWpU+mOUE6l$'"+r\Ag$3:bZJ?5?YC,YMq.O!X#@e(BqJfSnY+E$1*K.'a>/c("Kn$QR+_LWkRc?(qPM37&.$T:/Tn\n-nuJ2B2P:kpMm:3T2.l%b'#V=3aPIsHp4*,eU]SPRsI:7%t?FeR.&W[DrF$D!L,k]MIBdr)58HS*23jN!EDNiK^l7TVLmRND-4JS.&("SgNL'6VM]o.7KS.)Bg"_sep`/EEX'8$5UX;o"s4t=&K58V[lrH5s(Z?j57<#npTY/6YCUDl%W3l-VVTm3$5.-comb6UHJ?O?nea,2Pb"M]>:",b(g@ClErr)F>0+6tlut%mu409slrpV>h.h'Dd/<,\#UnT';dQQ6o^.1C@A1>h"5t+&:oAT+cKcM.s:<9.=jJeCm.3`*K4=D>a/8=a*2&0u0PP6b;^0ALWFHM\CisqtloTo:J2?qX5kD=gtK9*D`DEE<+ujas#q^-U[ELQ7)u0p-V%"C142F8/dDKJ^-*F&]kW`j%(2\NEV[d]8t"68#MS0`>TE3+G%)oMrY>S`0*G0^-Q%Qgh)_86lbXi]=cjg%n+,9:hNh%jIdg8SO-&'r&$4H="pYD-a!Dji&eEfp5S"<17_';,n,\_0R4AS]p!;,p(>W1&N5&nnA2`_!?g]>>nkoOhKP(=]7W-Q>lpkO,uOjNDUI.QIYS4U\ipm-@X)='EH]2Q8T>CcNk0VZISqCfR?5'ouLRI^0E)M9C^3:R+\`[3g6eR)Er#t*^qitb)Ei^BC2NV+^BO38@XS3S@FGu"<8;#>'D*h96*6(\,(7PgB#7#dCdUWqG2-PAah_P'C[]kXKB'6#9V40mJ`=JB&;hd#1&SgeFP46nj?iI(LNbYGhZ2BaG]6"hs)$%dpS(a?g=V+OcKWgI\/#l!lC-6;r/`p9upp4dhNb>'KUlI@BFle!sq87=(]`eeD>8n4N%JkR.'NRn`36?^LodsisK^o"+<[q*3Jg;bo2_RP'5At(s>XGUZ\GuOIN3[>DK2/Sh30_'kR"!lD`kjXn0-d00Z*U*rL*[Kkg[>0\dAOO.p[^YN>6Y-K_S\SZ*Un+msU2]jE`NE?S33^o"KL+]Y<#$b#G*c4mU/gX>RUS?BP+h\2;1pMH\@3>Cht=8&#:N!ummEWn1*i][_gQGZ'M:>*p!W]CBQ'E4+ERNo7f)j6@o[0C@;C<`:*g)O0/UQZH`,*GaA1M9%l@tLE8_]H[1:@[ae]IkTRt`.B[pb5p*kfVZ&W`V81ZiXZY%N)gM&4a?,B$ZO:s!b/q#-*NitB*78=K>F9rIV*SF_#%n&sF]S#>,G*fER[I,(H%GjJ`5(Va:Q@&qXKWmu5QnQp9mpN:_FedJk8f-bt6!dk@l8g!4+:`+MWh)4ceKi]c[dbLX&5Bd,*/l7#h0!e'&k#0M8J;Xa'^Xr02utoOd1&b3Y+.NM2W&PK\o8/E3C2bPIssV#=r#'Za)(D2;N0fmd+B>fcC>e^#2!)%.d8P:6(;#FC(/\XY8O+/*p=U$o^Y@I!,ijm,[nQA7q6Z\&A.4[F:,!&kB_)m[b^C]:_SFX--L"$]B/*B8F2+e_FrVu1*1nUpeCGnm-p3'K;Ttj*(*Lm?6u:CG>f(@[%EcXgu,Hr2AFIVcS%IaI*kPajXqWiQaU4BoQd>pYk88nKQZeF.JaP,7?efPhcUJNXQpq:$,$+BLr5J2%q@"2rP/fP(K\t50Z=k"IWPr[a$(o"0RHFp7/2Z$JVq.9G9`j&c$=-$FY[W;rW%X6fB32[i:Vj<(*6USAL%k=HZIA$4&-;rV>3$+C;H\K!NZL%],-V"O^->KF^aU79qEYHbf6rH'-X"#8Vh?7FYk=:moOkL"_iX2$fl@rtHbRWBSU2ep$._VC24c+bR?20`hFPOc6I,lN`.4!="qOoNukbt#7DIG&oo+GAW]2`*S1>V&qD^7?[C/pm(3Fsde/jq;/UIGjAOS,sbZ]f7OikiN#58De;3M]]d-#c'WO*:gBNLbM9FP^8Io$odnL8!m"Br,T"Mg1e7#u"FsbRLXl@u:qPT/+*`.Le'5jb?M>0f*S,+^FL#@H2DZ%:qtfZ3MtFVscE8l%T)IGK5^i8s*/'^H-[^gfY'LT%cr5*>DLO$MI"rB%o+m-:bMB['eh@@Tk1:K+3ML`+'&_+:MdMAS*LLg-no,:#PX,o]*9'EVaO-EL3&e5`q8Y&1Su8Hd.[5gBqXo&,Q^jE[#nSuKc;1d@uEU-Y1\R=T!n72aZ=T[XJh!HGUa$].7S"[e"(B&H1(BIP-dYp%jH8FU"I0n.74XqOYZ6ubIPY?6GU&=Pr/W%6'+3fng?a9OAhfc72B?Q#kt-J`&VAWMb??))n/RG]S7!TCTQO2BF7YZ%cEO-9+M];QsR=XV7-3;,u!p>43C5UcSDu9Y"25D"V_qm(Dmi2,)Y(*KS.ZW+mJ"]jPp`;DY3[eF-c.'b[[p6Gb-oKPIXA>@TZK`V5fI0`ssJieno>n_\JQfQ>t`WZCI.KN6?ph9Xld]$Qtu-LK_iBiKJ9u.&H.i@.VfhJO=..9B)MfWM7<]8\f&-=\CX(B%?i`Fj:to3SZ1;"2!U!L>1QkV4k$aYeH0MjFr@Ai#NIVS9P)QD_99QR;GT#D8%j)Pk3Jbe7FTlVO/(GJ-VlEQlrO?FS6hGX.Bj)D0WeqRN!V;M$3SkW)AnqkDl+;V0VQ#7jX`]U"nl.tXc9.]0G1IucFPbn&ahKr_B%'jo1_@s@PT!N-NG58S,ct)n:A\hpu.gAR>5?&GSh9/'W%?so:(OA.eM\^C[ra(53REDUu+2Zqa_ukM't>B[&e(Ij_uo:X*[).\*IphRD+:85FX("UD"Gk,q?q!0KRmN*GntA:d/nj,_UD.#ncn3EcMC'q2EGJN%sD5-TH6.B>a0:Tpu`oQoVr?_Ea1g6%g)8n%*J@c\A*.V^-iOI(finPhA?pO<6:;g+4V(8kg2)LH;.l(jgQ8P_DpM/s$P`\5b8Gf@LohMnC3c9@I(X265>IT2O5u9iSMW;BQb^!2^m87RTMk+t;i]QhL9e8(#5l0\Q[=$.$E(DcHBa!?ap&&j\@C`?qD1`7--];G!W!fr!26,__F/#g-^O$n7Fk%?4mPul?A.kmt9'R"JO*+o\4*SN2-nD:u\J4Tn7]:X%Y]uoUIS5Lf!+bM^da6Vu`gY*^&JAXXn0?hlSO'Nsg-o_^h&ZF99-RlVCN@'-'J&5\>-h**6*0UR\E.0ZtP!UN#Vc>amh4-+-)d(sjc7&GqQl0u?+s]*V8HKN=)aT7_\37_W\)o\/9gFYd1YlrD6-D\s+(;8BVFE>^X.mMNnU\8e,_ia?7;iCoh>%/gc2eaqA=,nXHSu&nZaKGfhk,uT0uTV."0g@46>_u&#d6UZ,GV&.;W4*!Cm2[/IL5LuSddId"jG];9]o>!RhboeC3?tdgceF5i=`5,Tm+i&&?@&R0b%H`E=([#&E7S1!)7HLr2DDal=0K`1s+ZQNO2Q4e#'UX#"$#Z/#$+E<@";l]a'bL\/Yc6dN'fje"(QHV3`BoT$uWnF<76Z>=mDo#*DAZ>'YFS^]ES1$&#^RFIU"h\X=1.>m?/$!)A<(Y3N%;>+Vmc/@'oc)D"HoTAPRAJ[9nHU>a+,hJ,?28-oDU-=QJ`Tg=H-#P:e>HT:*G$!aSO*a+YG>,+LGTGl>`KT2i6m;U(eP@^JG=H+Z>'Sab[;@u%1.(a%1Z$K*ZYQ4"YrG2FbjcL`^ZORa-;fcMrB=NM:2p(-qG+[9Fh<-X:Tuf[`Zsed)3lV)<-3I+EStllQpkk1VBW/KMR&>cMU9T)W*H'T#5fs)?+,(qpPa9H][;h#_\4[U'1Z,OSiP4AhYWL4Q73)ZrUtVS\!q.3]f7>=4Odjku#WHUQs'$pi^;-=m$2DkaQ^657Z!XPGKjB#+R1rOQ'jTcisZqn7=klBNn&^2b:r,:AO0H<=rEojijU,Z^QW7T13hW)Y8Pb0[QgR\7DdUI-\&qEHeJgiNlu!D^=]87Dp4@2%563VFuhjLEsfD2rceU"Vc)@nOW3cSX2&PUf]p@=ceJ'>Uc`6BmFbTO^mMGSj3;$Z,sb8BZDpK_Bg(XOGTp5ce,K`^k`AQVY@h1k"cS3RZk#.'a,Z*Q7/cM4<8:5`8%HG2e<#qRflc8+YlN[t//I[[JZY\":^p+d?sN&5"[EBes_.8t1T[Eft73O'@16=\_#6;(XjLrI.Gp4q)t0S25"/,VP[(+N2tB8ierXitQES5go&(m?/d3fpotd7Wrq5\e@bSV^94e$].8^9C'-Ma(p,b(6RuGBst.%@k%L:(qQcarPVh;qSg&Ck4?Tg"RUn[*rP1%LmLf4e\8jk;p/N3k]maM28$7K54^(f^(Eu3$^15!K`I&UiF<8fm(GWJL@PIo4Rf7MtK.e"sU-'$0:mJVnMTI,CF=GZL/lmW*>lFQ-Y4.FUpj7"d!`m.`(GZg^6a[7*q?u_Am&p31dX9C1b*'fpbPi*[8fp$'.Q;Kp2Fq-2s*Do1/QH!6)WT9C\OY`[r6,=-C*sR3L%0o/K@W*sc)SD&f5fOsY].I,\.s[JXLS@R3Z\Hf1r2S,OBr'sNiVNqQ.PNqm\PWNlaqCq!LI\;,C4/8fULfp=?#Vj_LFaa,oVc2S4.pBp%GYBBQqeub$T32pg!hGh63,@M,=$K8R8.?DU+Cn-,$MiPL>grZlBma*#u2u&(.lk.NiZ#ZPO*Fh7,3#LM[V!l0]7Tci=,o<#XH?U8Wf.A,9S4oZ#te_V/cjOed"K0LU!0+(GL^`^bk8.I)Vc&$m6O!`PG0DTLL)/)ifIPJRsq)_XU5+*F09-aD%;4JD-D2"X/OV8/df`gluXUor8K%Rg-]=6tVhmaU+CPc3:/pLr<'i:OsW:7K(9or4ObUbXK:)K<\leN^WflR\+4PP:m1/0/T>I!-n2Tm]Mm/c4pEtcm>*[T7kEN]0j4rPXDC*Lk.Z23]GuEOe8Q#X'rj"D\J3eNYSg1+t9Fp`8GWTe_9Wf&mgf*aJ>;%h-HZc4iKQ4(fQIV3)'R;*\WlSbVcBBnoO;'9$O=.$QK3."f%l))jO-.h0J%\UABK(,n5uFO<',NPc]`(c%Y>h\<)7%a!2oAu!Us.<]uH4F6GufplA]o=,`'4Wlb&YPEG^N5"3T6uCZ?btciuc@nK:KFDlm/An(s+A)1#5#R9:O^kfK,29:K12&JhW&1=:'bZOq8Ps206Z3nSDS>G7P@b)W6Y%lJd:S;L>cOg(XKjflV`"Gl5l$'=08g*7o>n3h;u,=]SaH7a5IYn0W=Re.iRZ64[=bWnfeQ)p;s"2Q,9hZ0CZdrd?HoC]GoP"5i?6pWoT#.o_*BL28PA\D9J['-1#dFY&DSN7:'*b^q&/s5CNaJ=C#*$G[^Y)gmpPjF_%4&PK=&%nYkL\!Ob47fLlt?0.kR6!$)/#h!jS/,`:,]8,fYC/R4Xtq;JB8_]X=SPc.A5(f!6]-7958ljnP]H;lCSVMOS&JK6iqs,U$%$4EtI0Wm9]a+^5o2UK2Q:Nhd6.i2#-M/n),rdo"t:Y&k*Co=M&-UeTBIHVQ=3;_9Ii^nd&2oBXB>[aDJ%*K-VEn&5e%_k%=c2RhDW=d^[1JEB^BPMdaU++J&/$Zt7?LZ#IXU[4EiM7'3d%2o?gSDU!)aCBnT6a;4TeBG?G3>l;iV*dlM5o!=GWWjdJ4b#If5m$302El^oWDM.D&6DY.DeUdak;;/XD5sk>pa-]_QL.UI>Gh,*Y;_GAMcrJke4/c^u!c7hCPMXUa0R"6(1)2iu#(4^V+Ail'AqX@?-/(i,K*3C-8N/CfG')QeDYNh@6"eh2fP\bu)+_jp];D9%GSI?bHk.M[YED_O[Fq7jT,XN#!jUmp!\V[q#H4tP#4R!GB=R,G3<7Y=nV^078SXZ6OgJ&#]if?id*Bts'!8XDho*Pu^CMi6MHkiTFUoQ4$g/4QE@jOI'[Sn,CCb1CW/.t?R'qtq2lo5W&H8h"*P:g\s+M4gVcq;&1EmX0N@^lhC/XeD96o!og3n]cZn)IUKXqlK9UPuX8[//LV^n3FNoa\M)B^8)O")7?OTGt]>o(33Br9,>f#^_^2V$S=7OUC(b+A&1qmV%C-0F`6Gb!D.Q)JopAKL=t3JToXUQ]aQ*E$P$Mh-9]LR+Xpf$uh;h$:<&p2i'<&i0Jsp\JFN(9l%0`Z6KM0tZ_FdRMOE?5%BaK8%u@TgZ7Sqh4nr"Zmtd+ja$f7>O#"tLD:ks2)oIaf`.01jLa5^>GaM>6,l;m$oc/Th6Y>`-/mT2[+pS"0d5I;UY++?\%f]3q,*Zb,&fuNB4l:=@*WhgJfLc8tScf7T9K\H[>=ET+%kg1RKF/OXQ2U5`od0^MRj!?$Q@?LN2qXT(eQn5*>^6[M2,dD+p?+QI&`k9Vdta"d;i#e*epWQZ^mKW+a=V/\/57Man''c#%`<[;aE=_I53<=9-V0pJ1U5/G.8=*G5$:L*B_#I31Y^f!aJ)MPAOR`Mo*TV.9RY!@A'1iTL[)W]Hq!)[mKZ+P`63/j,HoK/M]8Kr@oFuFA%V->OY;3;\pU4>X@!WgtG3oVK:Lp8f;EjZG-O:B(-rHRWl8.V;Q8YZ05Maq6iJHK'3"uo+^q-)Jd+a1^D>V#2s]tl5BoL=kfm6V)?N-bWsqK6mpWNNL`i,_Dj'\6TgRSA5:3=">j3S76$@Ssm@2/f`q)jck2^,\Q1Vpq&?Lge+*Y-EN[S8Jnp\%qh^$=jMD0tXqZ][:,n\L4IdeX>7RS(t@rZWT["5j(e"922J=kX/l`;1;`&3FW_KM%L2'M504a[A.3UF)h9BW=\>).%T16:Qg$&Oju=gE`mfRV&m)HK"b]N[h:W+OGrccVf_GF:\r\eDP9Lhp(mY1ih3R4NYe]T;okm,-a]b@0Ft]e`gqP<,G+'WKim>!FucJ!P%9o]DM0llJ"bLCR+ncoYD445S98289Y$4VK:#`'1t-!@XKod,,u(2`5`.lW,!imb:_8667(q2in\nE/OSC;Dd,D0%L[^.oM$`\s9cXPP!3aD,/Lc9E(d@Xg$j8ee&7kUB*/U5N]/iWIg)M,lSb=A>CNht7X..Y2IutfX9Un6uc#Kho&N^:qj5Y,)PDfmRIJ^4hZpmhXL'/"4OucI[M(h9"&m%LL1pg*>-d;42AU`5lQDM(M?qd]jAe6:TidrLT1Rgg4\C19q1/f,l8SEX56caY9/pcm)(a)l,Uf])VO=XlO2No"3$qmo\IFQdP5!1Ak:O+QdqX5ohg5G1T.ik?.#e36\?Yrk:b3g_u9&&5=>B=5f1F='7KaG!/c4%d\$-<\E-J1>tjQR5&.ki4U#fn0aX,SfZnY=)-78K/><*TF%Tsj&sq!bi@lY^tbZ.Y-mQla@WN1N-$j@oVgkBbuNjB/b\Jb.M+_%H[GcL^@u"GA%L@mitH<=0qdQrn0:HWd;N"(X/\JIk(Q+I.H]8?r+))%^3fJ:9/6+W]a(TbKtXY)U1TmK8(cBF,2kbQV)+YIp?.FVX!N)-9a3P12,M+ZNG^!G_ar>]OefE]+<6(R68oP0b`Q=]?mFpr!ou]SG&Ypo(CbJ%i'FF7S4cF[&ijg:4C5'3bcFW0@^D=q\IG!dg\a7:)LVr2bkY'MWsCeh*4tiJFsaAV.hP!mj88_(4rm(R:o:6`l5Ip!XER5ffIiaF0%_`l/6@#:Ha1:Pqp`_F2:V5aSNaM&i<+X4EU,X3Se9B48\NG]*=kjQt-X\L8DSM4=Z.;GrcG&ELXYX@qkbdjWd]DhbHYq6+_!?T7M3&J1*\84bR0rZjE.=r'?%06gVpWn(t]01Y6's17UI3!(9D:[$E2C?4dCJVu(*@U_cVJ%N*+"?(T)`@/KR7s4lHSp>0V"r=S)R-%%Y[C.A*;7W*W-"WQkUTZ0R?ntEt[HE2c17DocTCU5KfG"7#S9R@$#_.1lJ:Aqhgj_TsZq@b2$#`6E@bUqjHN3C3`i8AiHqBn#T-g_&s*ptLN"fPH@RKB9JrdAN2^j%;8gfDi525o2Lb'oZ<`(Ms=F8LQcC$R-3OCu-F$oB]7N=uq@ufPD&Ipm[b\P?,+7W36YE'epTQHOP=ZX0[>H7kWh1U]&Uue3P7Un$$0CYiYi8f:\p-7]K()jQgX--I$+blEOH(+<$@"BmS$MLI%G1,8rp^B9W;!mg[:=%pe,Z\5@M4f9Mg-722Wg,/9=SsRtCbm2o6)Hgj)*I;??#2_TbSrd]N8aVin61HDY3PT^*([F_3CD,cd6#fWo8Cec>"ruY,RaHo.8\]^qB'OjFbr"r$/bA-"&ClnAoMFj"Q?ht;a?BUil-X0kEfa[PoFKI'i87e9C`pQrZ9eON9Yc`rfN#^Y'I3[g+])*R"ZO7jU76[&++qn&=I*R[&Rh:*.=iWPP+qudVX%Y)j>>9m$>BM.!^C?"?jI*Y;D(KJNEkC(+[("rl&bSs8Vc?Rb6U/HR2jB35&FcU"N`HI:-nl(UQ(7FNF^b4CF_8V.oiFf#Cn?>O?d4gOaoi@j%=f'`+\`D*WZ]?&.Xj7JJJ5P.Plp3iNOS)rBk_31"a>JiLrgF!'`cKqX_0V+Q,CK!<5.A+%/mmOA#DMrJ1NrL"uh"c7THe6G'N+qOe5l\6&-2ItYT,:!ilH&,4eA0Df*!SU7+Kj=gE14kpc&m;:0H!lR_]S(TWXMRm@)*e-XcF/BNKali@;no=g+GUJQg8pqWe5OEAUAoE8W9G0V;>t>gdLB!a77=m^K9j.M<:g:S>.?M6rllFXVoB$"!j8[.k";1tr](nqtjVTC8?1*4,P5jL`WAjgVj8Zg3QHd)BA,h=@O'(\BP\4ku=3iP:X Date: Wed, 9 Jul 2008 17:31:37 +0100 Subject: [PATCH 148/495] Redirect the stderr of pybindgen to a log file (ns3modulegen.log). --- bindings/python/wscript | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bindings/python/wscript b/bindings/python/wscript index 503de4823..3d600b1b8 100644 --- a/bindings/python/wscript +++ b/bindings/python/wscript @@ -316,9 +316,9 @@ def build(bld): if env['ENABLE_PYTHON_BINDINGS']: bindgen = bld.create_obj('command-output') bindgen.name = 'pybindgen' - bindgen.command = env['PYTHON'] bindgen.command_is_external = True + bindgen.stderr = 'ns3modulegen.log' bindgen.argv = [ bindgen.input_file("ns3modulegen.py"), bindgen.output_file("ns3module.cc"), From a6ccafbed75fc57714793fbfc634042e90417912 Mon Sep 17 00:00:00 2001 From: "Gustavo J. A. M. Carneiro" Date: Wed, 9 Jul 2008 18:33:16 +0100 Subject: [PATCH 149/495] Fix a problem with callback proxies with zero or one parameters. --- bindings/python/ns3modulegen_core_customizations.py | 2 +- bindings/python/wscript | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/bindings/python/ns3modulegen_core_customizations.py b/bindings/python/ns3modulegen_core_customizations.py index 2a23e48b8..95721c5f4 100644 --- a/bindings/python/ns3modulegen_core_customizations.py +++ b/bindings/python/ns3modulegen_core_customizations.py @@ -145,7 +145,7 @@ class CallbackImplProxyMethod(typehandlers.ReverseWrapperBase): def generate_python_call(self): """code to call the python method""" - build_params = self.build_params.get_parameters() + build_params = self.build_params.get_parameters(force_tuple_creation=True) if build_params[0][0] == '"': build_params[0] = '(char *) ' + build_params[0] args = self.before_call.declare_variable('PyObject*', 'args') diff --git a/bindings/python/wscript b/bindings/python/wscript index 3d600b1b8..d13ebeeba 100644 --- a/bindings/python/wscript +++ b/bindings/python/wscript @@ -21,7 +21,7 @@ else: os.environ['PYTHONPATH'] = LOCAL_PYBINDGEN_PATH ## https://launchpad.net/pybindgen/ -REQUIRED_PYBINDGEN_VERSION = (0, 8, 0, 475) +REQUIRED_PYBINDGEN_VERSION = (0, 8, 0, 479) REQUIRED_PYGCCXML_VERSION = (0, 9, 5) From 5f9b651ba845d389b2218df26c5f9ed708012dcd Mon Sep 17 00:00:00 2001 From: "Gustavo J. A. M. Carneiro" Date: Wed, 9 Jul 2008 18:34:42 +0100 Subject: [PATCH 150/495] Don't re-declare pure virtual methods from the parent Socket class. Fixes bug #249. --- src/node/tcp-socket.h | 17 ----------------- src/node/udp-socket.h | 16 ---------------- 2 files changed, 33 deletions(-) diff --git a/src/node/tcp-socket.h b/src/node/tcp-socket.h index 0a813b76b..413d87f62 100644 --- a/src/node/tcp-socket.h +++ b/src/node/tcp-socket.h @@ -51,23 +51,6 @@ public: TcpSocket (void); virtual ~TcpSocket (void); - virtual enum Socket::SocketErrno GetErrno (void) const = 0; - virtual Ptr GetNode (void) const = 0; - virtual int Bind () = 0; - virtual int Close (void) = 0; - virtual int ShutdownSend (void) = 0; - virtual int ShutdownRecv (void) = 0; - virtual int Connect (const Address &address) = 0; - virtual uint32_t GetTxAvailable (void) const = 0; - virtual int Send (Ptr p, uint32_t flags) = 0; - virtual int SendTo (Ptr p, uint32_t flags, - const Address &toAddress) = 0; - virtual uint32_t GetRxAvailable (void) const = 0; - virtual Ptr Recv (uint32_t maxSize, uint32_t flags) = 0; - virtual Ptr RecvFrom (uint32_t maxSize, uint32_t flags, - Address &fromAddress) = 0; - - private: // Indirect the attribute setting and getting through private virtual methods virtual void SetSndBufSize (uint32_t size) = 0; diff --git a/src/node/udp-socket.h b/src/node/udp-socket.h index fa20b885d..afe17774e 100644 --- a/src/node/udp-socket.h +++ b/src/node/udp-socket.h @@ -50,22 +50,6 @@ public: UdpSocket (void); virtual ~UdpSocket (void); - virtual enum Socket::SocketErrno GetErrno (void) const = 0; - virtual Ptr GetNode (void) const = 0; - virtual int Bind () = 0; - virtual int Close (void) = 0; - virtual int ShutdownSend (void) = 0; - virtual int ShutdownRecv (void) = 0; - virtual int Connect (const Address &address) = 0; - virtual uint32_t GetTxAvailable (void) const = 0; - virtual int Send (Ptr p, uint32_t flags) = 0; - virtual int SendTo (Ptr p, uint32_t flags, - const Address &toAddress) = 0; - virtual uint32_t GetRxAvailable (void) const = 0; - virtual Ptr Recv (uint32_t maxSize, uint32_t flags) = 0; - virtual Ptr RecvFrom (uint32_t maxSize, uint32_t flags, - Address &fromAddress) = 0; - private: // Indirect the attribute setting and getting through private virtual methods virtual void SetRcvBufSize (uint32_t size) = 0; From ee19e57741f6d5292832ec22a29da0bc125da28a Mon Sep 17 00:00:00 2001 From: "Gustavo J. A. M. Carneiro" Date: Wed, 9 Jul 2008 18:50:28 +0100 Subject: [PATCH 151/495] Rescan API; fix and enable the socket unit test, as it now works. --- bindings/python/ns3_module_node.py | 52 ------------------------------ bindings/python/ns3_module_wifi.py | 6 ++++ utils/python-unit-tests.py | 32 +++++++++--------- 3 files changed, 21 insertions(+), 69 deletions(-) diff --git a/bindings/python/ns3_module_node.py b/bindings/python/ns3_module_node.py index a8aa6a8b4..6368edc57 100644 --- a/bindings/python/ns3_module_node.py +++ b/bindings/python/ns3_module_node.py @@ -800,32 +800,6 @@ def register_Ns3UdpSocket_methods(root_module, cls): cls.add_method('GetTypeId', 'ns3::TypeId', [], is_static=True) ## udp-socket.h: ns3::UdpSocket::UdpSocket() [constructor] cls.add_constructor([], visibility='public') - ## udp-socket.h: ns3::Socket::SocketErrno ns3::UdpSocket::GetErrno() const [member function] - cls.add_method('GetErrno', 'ns3::Socket::SocketErrno', [], is_pure_virtual=True, is_const=True, is_virtual=True) - ## udp-socket.h: ns3::Ptr ns3::UdpSocket::GetNode() const [member function] - cls.add_method('GetNode', 'ns3::Ptr< ns3::Node >', [], is_pure_virtual=True, is_const=True, is_virtual=True) - ## udp-socket.h: int ns3::UdpSocket::Bind() [member function] - cls.add_method('Bind', 'int', [], is_pure_virtual=True, is_virtual=True) - ## udp-socket.h: int ns3::UdpSocket::Close() [member function] - cls.add_method('Close', 'int', [], is_pure_virtual=True, is_virtual=True) - ## udp-socket.h: int ns3::UdpSocket::ShutdownSend() [member function] - cls.add_method('ShutdownSend', 'int', [], is_pure_virtual=True, is_virtual=True) - ## udp-socket.h: int ns3::UdpSocket::ShutdownRecv() [member function] - cls.add_method('ShutdownRecv', 'int', [], is_pure_virtual=True, is_virtual=True) - ## udp-socket.h: int ns3::UdpSocket::Connect(ns3::Address const & address) [member function] - cls.add_method('Connect', 'int', [param('ns3::Address&', 'address', is_const=True)], is_pure_virtual=True, is_virtual=True) - ## udp-socket.h: uint32_t ns3::UdpSocket::GetTxAvailable() const [member function] - cls.add_method('GetTxAvailable', 'uint32_t', [], is_pure_virtual=True, is_const=True, is_virtual=True) - ## udp-socket.h: int ns3::UdpSocket::Send(ns3::Ptr p, uint32_t flags) [member function] - cls.add_method('Send', 'int', [param('ns3::Ptr< ns3::Packet >', 'p'), param('uint32_t', 'flags')], is_pure_virtual=True, is_virtual=True) - ## udp-socket.h: int ns3::UdpSocket::SendTo(ns3::Ptr p, uint32_t flags, ns3::Address const & toAddress) [member function] - cls.add_method('SendTo', 'int', [param('ns3::Ptr< ns3::Packet >', 'p'), param('uint32_t', 'flags'), param('ns3::Address&', 'toAddress', is_const=True)], is_pure_virtual=True, is_virtual=True) - ## udp-socket.h: uint32_t ns3::UdpSocket::GetRxAvailable() const [member function] - cls.add_method('GetRxAvailable', 'uint32_t', [], is_pure_virtual=True, is_const=True, is_virtual=True) - ## udp-socket.h: ns3::Ptr ns3::UdpSocket::Recv(uint32_t maxSize, uint32_t flags) [member function] - cls.add_method('Recv', 'ns3::Ptr< ns3::Packet >', [param('uint32_t', 'maxSize'), param('uint32_t', 'flags')], is_pure_virtual=True, is_virtual=True) - ## udp-socket.h: ns3::Ptr ns3::UdpSocket::RecvFrom(uint32_t maxSize, uint32_t flags, ns3::Address & fromAddress) [member function] - cls.add_method('RecvFrom', 'ns3::Ptr< ns3::Packet >', [param('uint32_t', 'maxSize'), param('uint32_t', 'flags'), param('ns3::Address&', 'fromAddress')], is_pure_virtual=True, is_virtual=True) ## udp-socket.h: void ns3::UdpSocket::SetRcvBufSize(uint32_t size) [member function] cls.add_method('SetRcvBufSize', 'void', [param('uint32_t', 'size')], is_pure_virtual=True, visibility='private', is_virtual=True) ## udp-socket.h: uint32_t ns3::UdpSocket::GetRcvBufSize() const [member function] @@ -977,32 +951,6 @@ def register_Ns3TcpSocket_methods(root_module, cls): cls.add_method('GetTypeId', 'ns3::TypeId', [], is_static=True) ## tcp-socket.h: ns3::TcpSocket::TcpSocket() [constructor] cls.add_constructor([], visibility='public') - ## tcp-socket.h: ns3::Socket::SocketErrno ns3::TcpSocket::GetErrno() const [member function] - cls.add_method('GetErrno', 'ns3::Socket::SocketErrno', [], is_pure_virtual=True, is_const=True, is_virtual=True) - ## tcp-socket.h: ns3::Ptr ns3::TcpSocket::GetNode() const [member function] - cls.add_method('GetNode', 'ns3::Ptr< ns3::Node >', [], is_pure_virtual=True, is_const=True, is_virtual=True) - ## tcp-socket.h: int ns3::TcpSocket::Bind() [member function] - cls.add_method('Bind', 'int', [], is_pure_virtual=True, is_virtual=True) - ## tcp-socket.h: int ns3::TcpSocket::Close() [member function] - cls.add_method('Close', 'int', [], is_pure_virtual=True, is_virtual=True) - ## tcp-socket.h: int ns3::TcpSocket::ShutdownSend() [member function] - cls.add_method('ShutdownSend', 'int', [], is_pure_virtual=True, is_virtual=True) - ## tcp-socket.h: int ns3::TcpSocket::ShutdownRecv() [member function] - cls.add_method('ShutdownRecv', 'int', [], is_pure_virtual=True, is_virtual=True) - ## tcp-socket.h: int ns3::TcpSocket::Connect(ns3::Address const & address) [member function] - cls.add_method('Connect', 'int', [param('ns3::Address&', 'address', is_const=True)], is_pure_virtual=True, is_virtual=True) - ## tcp-socket.h: uint32_t ns3::TcpSocket::GetTxAvailable() const [member function] - cls.add_method('GetTxAvailable', 'uint32_t', [], is_pure_virtual=True, is_const=True, is_virtual=True) - ## tcp-socket.h: int ns3::TcpSocket::Send(ns3::Ptr p, uint32_t flags) [member function] - cls.add_method('Send', 'int', [param('ns3::Ptr< ns3::Packet >', 'p'), param('uint32_t', 'flags')], is_pure_virtual=True, is_virtual=True) - ## tcp-socket.h: int ns3::TcpSocket::SendTo(ns3::Ptr p, uint32_t flags, ns3::Address const & toAddress) [member function] - cls.add_method('SendTo', 'int', [param('ns3::Ptr< ns3::Packet >', 'p'), param('uint32_t', 'flags'), param('ns3::Address&', 'toAddress', is_const=True)], is_pure_virtual=True, is_virtual=True) - ## tcp-socket.h: uint32_t ns3::TcpSocket::GetRxAvailable() const [member function] - cls.add_method('GetRxAvailable', 'uint32_t', [], is_pure_virtual=True, is_const=True, is_virtual=True) - ## tcp-socket.h: ns3::Ptr ns3::TcpSocket::Recv(uint32_t maxSize, uint32_t flags) [member function] - cls.add_method('Recv', 'ns3::Ptr< ns3::Packet >', [param('uint32_t', 'maxSize'), param('uint32_t', 'flags')], is_pure_virtual=True, is_virtual=True) - ## tcp-socket.h: ns3::Ptr ns3::TcpSocket::RecvFrom(uint32_t maxSize, uint32_t flags, ns3::Address & fromAddress) [member function] - cls.add_method('RecvFrom', 'ns3::Ptr< ns3::Packet >', [param('uint32_t', 'maxSize'), param('uint32_t', 'flags'), param('ns3::Address&', 'fromAddress')], is_pure_virtual=True, is_virtual=True) ## tcp-socket.h: void ns3::TcpSocket::SetSndBufSize(uint32_t size) [member function] cls.add_method('SetSndBufSize', 'void', [param('uint32_t', 'size')], is_pure_virtual=True, visibility='private', is_virtual=True) ## tcp-socket.h: uint32_t ns3::TcpSocket::GetSndBufSize() const [member function] diff --git a/bindings/python/ns3_module_wifi.py b/bindings/python/ns3_module_wifi.py index 5809ba692..4348d8129 100644 --- a/bindings/python/ns3_module_wifi.py +++ b/bindings/python/ns3_module_wifi.py @@ -658,6 +658,8 @@ def register_Ns3NqapWifiMac_methods(root_module, cls): cls.add_method('SetSsid', 'void', [param('ns3::Ssid', 'ssid')], is_virtual=True) ## nqap-wifi-mac.h: void ns3::NqapWifiMac::SetBeaconInterval(ns3::Time interval) [member function] cls.add_method('SetBeaconInterval', 'void', [param('ns3::Time', 'interval')]) + ## nqap-wifi-mac.h: ns3::Time ns3::NqapWifiMac::GetBeaconInterval() const [member function] + cls.add_method('GetBeaconInterval', 'ns3::Time', [], is_const=True) ## nqap-wifi-mac.h: void ns3::NqapWifiMac::StartBeaconing() [member function] cls.add_method('StartBeaconing', 'void', []) ## nqap-wifi-mac.h: void ns3::NqapWifiMac::DoDispose() [member function] @@ -713,6 +715,10 @@ def register_Ns3FriisPropagationLossModel_methods(root_module, cls): cls.add_method('SetLambda', 'void', [param('double', 'lambda')]) ## propagation-loss-model.h: void ns3::FriisPropagationLossModel::SetSystemLoss(double systemLoss) [member function] cls.add_method('SetSystemLoss', 'void', [param('double', 'systemLoss')]) + ## propagation-loss-model.h: void ns3::FriisPropagationLossModel::SetMinDistance(double minDistance) [member function] + cls.add_method('SetMinDistance', 'void', [param('double', 'minDistance')]) + ## propagation-loss-model.h: double ns3::FriisPropagationLossModel::GetMinDistance() const [member function] + cls.add_method('GetMinDistance', 'double', [], is_const=True) ## propagation-loss-model.h: double ns3::FriisPropagationLossModel::GetLambda() const [member function] cls.add_method('GetLambda', 'double', [], is_const=True) ## propagation-loss-model.h: double ns3::FriisPropagationLossModel::GetSystemLoss() const [member function] diff --git a/utils/python-unit-tests.py b/utils/python-unit-tests.py index f84f05bf8..a513f9a7f 100644 --- a/utils/python-unit-tests.py +++ b/utils/python-unit-tests.py @@ -59,27 +59,25 @@ class TestSimulator(unittest.TestCase): ns3.Config.SetDefault("ns3::OnOffApplication::PacketSize", ns3.UintegerValue(123)) # hm.. no Config.Get? - if 0: - # not yet: https://bugs.launchpad.net/pybindgen/+bug/246069 - def testSocket(self): - node = ns3.Node() - ns3.AddInternetStack(node) - self._received_packet = None + def testSocket(self): + node = ns3.Node() + ns3.AddInternetStack(node) + self._received_packet = None - def rx_callback(socket): - assert self._received_packet is None - self._received_packet = socket.Recv() + def rx_callback(socket): + assert self._received_packet is None + self._received_packet = socket.Recv() - sink = ns3.Socket.CreateSocket(node, ns3.TypeId.LookupByName("ns3::UdpSocketFactory")) - sink.Bind(ns3.InetSocketAddress(ns3.Ipv4Address.GetAny(), 80)) - sink.SetRecvCallback(rx_callback) + sink = ns3.Socket.CreateSocket(node, ns3.TypeId.LookupByName("ns3::UdpSocketFactory")) + sink.Bind(ns3.InetSocketAddress(ns3.Ipv4Address.GetAny(), 80)) + sink.SetRecvCallback(rx_callback) - source = ns3.Socket.CreateSocket(node, ns3.TypeId.LookupByName("ns3::UdpSocketFactory")) - source.SendTo(ns3.InetSocketAddress(ns3.Ipv4Address.GetAny(), 80), ns3.Packet(19)) + source = ns3.Socket.CreateSocket(node, ns3.TypeId.LookupByName("ns3::UdpSocketFactory")) + source.SendTo(ns3.Packet(19), 0, ns3.InetSocketAddress(ns3.Ipv4Address("127.0.0.1"), 80)) - ns3.Simulator.Run() - self.assert_(self._received_packet is not None) - self.assertEqual(self._received_packet.GetSize(), 19) + ns3.Simulator.Run() + self.assert_(self._received_packet is not None) + self.assertEqual(self._received_packet.GetSize(), 19) if __name__ == '__main__': From be9e5ced393ba448a407d7e13bef3f38eb46a588 Mon Sep 17 00:00:00 2001 From: Raj Bhattacharjea Date: Wed, 9 Jul 2008 14:10:18 -0400 Subject: [PATCH 152/495] Add some additional TCP dox about RFC compliance --- src/internet-stack/tcp-socket-impl.h | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/internet-stack/tcp-socket-impl.h b/src/internet-stack/tcp-socket-impl.h index bc65706a0..3817a28c1 100644 --- a/src/internet-stack/tcp-socket-impl.h +++ b/src/internet-stack/tcp-socket-impl.h @@ -50,7 +50,13 @@ class TcpHeader; * This class contains an implementation of TCP Tahoe, as well as a sockets * interface for talking to TCP. Features include connection orientation, * reliability through cumulative acknowledgements, congestion and flow - * control. Finite send/receive buffer semantics are modeled. + * control. Finite send buffer semantics are modeled, but as of yet, finite + * receive buffer modelling is unimplemented. + * + * The closedown of these sockets is as of yet not compliant with the relevent + * RFCs, i.e. the FIN handshaking isn't correct. While this is visible at the + * PCAP tracing level, it has no effect on the statistics users are interested + * in, i.e. throughput, delay, etc. of actual payload data. * * Asynchronous callbacks to provide notifications to higher layers that a * protocol event has occured, such as space freeing up in the send buffer From c3a8ec555549e1299754a2cb298c50451542c2a9 Mon Sep 17 00:00:00 2001 From: Raj Bhattacharjea Date: Wed, 9 Jul 2008 17:04:29 -0400 Subject: [PATCH 153/495] Add David Evensky's tcp-2way regression test --- examples/tcp-2way.cc | 785 ++++++++++++++++++++++++++++++ examples/wscript | 4 + regression/tests/test-tcp-2way.py | 13 + 3 files changed, 802 insertions(+) create mode 100644 examples/tcp-2way.cc create mode 100644 regression/tests/test-tcp-2way.py diff --git a/examples/tcp-2way.cc b/examples/tcp-2way.cc new file mode 100644 index 000000000..196f1ef3d --- /dev/null +++ b/examples/tcp-2way.cc @@ -0,0 +1,785 @@ +/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ +/* + * Copyright 2007 University of Washington + * Copyright 2007 Georgia Tech Research Corporation + * Copyright 2008 Sandia Corporation + * + * 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 + * + * + * Sandia is a multiprogram laboratory operated by Sandia + * Corporation, a Lockheed Martin Company, for the United States + * Department of Energy's National Nuclear Security Administration + * under Contract DE-AC04-94AL85000. + * + * Author: David Evensky, Sandia National Labs + * + * includes GPL'ed ns-3-dev code from: + * udp-echo, // ??, (c) U. Wash. 2007 + * tcp-large-transfer // ?? + * packet-sink // Tom Henderson, (c) U. Wash. 2007 + * onoff // George F. Riley, (c) GT Res Corp. 2007 + */ + + +/* NOTE +This isn't really an example file, so don't look to closely at it as a starting +script. It is here for validation of the TCP model. +*/ + +#include +#include +#include +#include +#include +#include + +#include "ns3/core-module.h" +#include "ns3/helper-module.h" +#include "ns3/node-module.h" +#include "ns3/global-route-manager.h" +#include "ns3/simulator-module.h" +#include "ns3/log.h" + +using namespace ns3; + +NS_LOG_COMPONENT_DEFINE ("tcp-2way"); + +//----------defines------------------------------------------------------------- +//define to print more debugging info. +#define VERBOSE_TESTING + +/* define to die because Socket::Recv() is told to + * only read an "undesired" number of bytes + * fails NS_ASSERT in HandleRead because rx_addr_tag + * tag isn't there. + */ +//#define TOO_SMALL_BUG + +//define to print this pointer in NS_LOG_FUNCTION +//#define PRINT_THIS + +/*define to print packet info in HandleRead + *expected output is of the form: + *536:P{536} *bytes from 10.1.0.2 [02-06-0a:01:00:02:20:00] <0|536|884018> + * ^ ^ ^ ^ ^ ^ ^ ^ + * | | | | | | | | + * | | | | | | | +bytes left + * | | | | | | | to read in + * | | | | | | | sent buffer + * | | | | | | +bytes read in + * | | | | | | this packet if + * | | | | | | header read, + * | | | | | | prints size + * | | | | | | in () + * | | | | | +bytes cur. packet + * | | | | | left to process + * | | | | +mac addr of sender + * | | | +IP addr of sender + * | | +print '*' while processing first chunk in a received packet. + * | | if there are multiple small sent packets, these can appear in + * | | a single packet, and are processed by a do {} while() loop. + * | +rle output of packet::PeekData(), in this case filled with 536 bytes + * | filled with the letter 'P' (brought to you by the letter 'Q' and the + * | number '9' :-)) + * + packet::GetSize() + * + * If there is a header it will look more like: + * 536:N{317}@B.{6}HELLOP{206} *bytes from 10.1.0.2 [02-06-0a:01:00:02:20:00]\ + * <219|317|0> + * 536:N{317}@B.{6}HELLOP{206} bytes from 10.1.0.2 [02-06-0a:01:00:02:20:00]\ + * <0|206(13)|999794> (ArchHeader=HELLO:1000000) + * where you can see that this first packet includes 317 bytes from the + * previous send packet (filled with N) and 13 bytes of header before the 206 + * bytes of payload (filled with P). + */ + +#define RECV_PRINT + +// dcl non-method functions.... +std::string rle(const uint8_t *, int ); +std::ofstream fileOut("tcp-2way.out"); + +//----------class ArchHeader dcl and definition--------------------------------- +/* + * ArchHeader: A toy header that holds a string + * and a uint32_t. The string is an abitrary label + * and the int is used as the length of the payload. + */ + +class ArchHeader : public Header { +public: + virtual uint32_t GetSerializedSize (void) const; + virtual void Serialize (Buffer::Iterator) const; + virtual uint32_t Deserialize (Buffer::Iterator); + virtual void Print (std::ostream &) const; + static TypeId GetTypeId (void); + virtual TypeId GetInstanceTypeId (void) const; + + // accessor functions..... + void SetIntValue (uint32_t); + uint32_t GetIntValue (void) const; + void SetStrValue (const std::string &s); + std::string GetStrValue (void) const; +private: + uint32_t int_value; + std::string str_value; +}; + + +TypeId +ArchHeader::GetTypeId (void) +{ + static TypeId tid = TypeId ("ns3::ArchHeader") + .AddConstructor () // NOTE: Required for ???? + .SetParent

() // ditto + ; + return tid; +} + +TypeId +ArchHeader::GetInstanceTypeId (void) const +{ + return GetTypeId (); +} + +uint32_t +ArchHeader::GetSerializedSize (void) const +{ + return 2*sizeof (uint32_t) + str_value.size (); // int, str len & bytes +} + +void +ArchHeader::Serialize (Buffer::Iterator i) const +{ + i.WriteU32 (int_value); + uint32_t str_len = str_value.size (); + i.WriteU32 (str_len); + for (uint32_t j = 0; j < str_value.size (); j++) + i.WriteU8 (str_value[j]); +} + +uint32_t +ArchHeader::Deserialize (Buffer::Iterator i) +{ + int_value = i.ReadU32 (); + uint32_t str_len = i.ReadU32 (); + str_value.reserve (str_len); + for (uint32_t j = 0; j < str_len; j++) { + char v = i.ReadU8 (); + str_value.push_back (v); + } + return 2*sizeof (uint32_t) + str_value.size (); +} + + +void +ArchHeader::SetIntValue (uint32_t v_) +{ + int_value = v_; +} + +uint32_t +ArchHeader::GetIntValue (void) const +{ + return int_value; +} + +void +ArchHeader::SetStrValue (const std::string &s) +{ + str_value = s; +} + +std::string +ArchHeader::GetStrValue (void) const +{ + return str_value; +} + +void +ArchHeader::Print (std::ostream &os) const +{ + os << "(ArchHeader=" << str_value << ":" << int_value << ")"; +} + +//----------class TalkerApp dcl and definition---------------------------------- +/* + * TalkerApp: + * An an Application that can serve as both Rx and Tx side. + * and is configured by ConfRecv/ConfSend and driven by + * ScheduleSendPacket. Becareful not to try to send a packet + * from the Rx side to the Tx side (back channel) before the + * connection is setup, which has to be from the Tx to the Rx + * (the forward channel). + */ + +class TalkerApp : public Application { +public: + TalkerApp (); + virtual ~TalkerApp (); + void ConfRecv (Ptr,const Address &); + void ConfSend (Ptr,const Address &); + void ScheduleSendPacket(const Time ,const char , const uint32_t size ); + +protected: + virtual void DoDispose (void); +private: + virtual void StartApplication (void); + virtual void StopApplication (void); + + void StartApplicationRecv (void); + void StartApplicationSend (void); + + void HandleRead (Ptr); + void SendPacket (std::string,char,uint32_t); + + void CloseConnection (Ptr socket); + void ConnectionSucceeded (Ptr); + void ConnectionFailed (Ptr); + bool ConnectionRequested (Ptr, const Address &); + void ConnectionCreated (Ptr, const Address &); + + + bool verbose; + Ptr m_socket; + Ptr m_servsocket; + Address m_local; + Address m_remote; + int i_am_listener; + typedef std::map, uint32_t>::iterator left_to_read_iterator_type; + std::map, uint32_t> m_left_to_read; +}; + +class TalkerApp_sub : public TalkerApp { +public: + int foo(void); +}; + +int +TalkerApp_sub::foo(void) {return 0;} + +TalkerApp::TalkerApp () : + verbose (false), + m_socket (0), + m_servsocket (0), + i_am_listener (0) +{} + +TalkerApp::~TalkerApp () +{} + +void +TalkerApp::DoDispose (void) +{ + m_socket = 0; + m_servsocket = 0; + Application::DoDispose (); +} + + +void +TalkerApp::CloseConnection (Ptr sock) +{ + NS_LOG_FUNCTION ((i_am_listener ? "Server|" : "Client|") +#ifdef PRINT_THIS + << this +#endif + << sock + ); + sock->Close (); +} + +void +TalkerApp::ConnectionSucceeded (Ptr sock) +{ + NS_LOG_FUNCTION ((i_am_listener ? "Server|" : "Client|") +#ifdef PRINT_THIS + << this +#endif + << sock + + ); +} + +void +TalkerApp::ConnectionFailed (Ptr sock) +{ + NS_LOG_FUNCTION ((i_am_listener ? "Server|" : "Client|") +#ifdef PRINT_THIS + << this +#endif + << sock + ); +} + +bool +TalkerApp::ConnectionRequested (Ptr sock, const Address &addr) +{ + NS_LOG_FUNCTION ((i_am_listener ? "Server|" : "Client|") +#ifdef PRINT_THIS + << this +#endif + << sock + << addr + ); + return true; +} + +void +TalkerApp::ConnectionCreated (Ptr sock, const Address &addr) +{ + NS_LOG_FUNCTION ((i_am_listener ? "Server|" : "Client|") +#ifdef PRINT_THIS + << this +#endif + << sock + << addr + ); + m_socket = sock; + m_socket->SetRecvCallback(MakeCallback (&TalkerApp::HandleRead, this)); +} + +void +TalkerApp::ScheduleSendPacket (const Time dt,const char fill, + const uint32_t size) +{ + NS_LOG_FUNCTION ((i_am_listener ? "Server|" : "Client|") +#ifdef PRINT_THIS + << this +#endif + << dt + << fill + << size + ); + Simulator::Schedule(dt,&TalkerApp::SendPacket, this, + std::string("HELLO"),fill,size); +} + + +void +TalkerApp::StartApplication () +{ + NS_LOG_FUNCTION ((i_am_listener ? "Server|" : "Client|") +#ifdef PRINT_THIS + << this +#endif + ); + if (i_am_listener) + StartApplicationRecv (); + else + StartApplicationSend (); +} + +void +TalkerApp::StartApplicationSend () +{ + NS_LOG_FUNCTION ((i_am_listener ? "Server|" : "Client|") +#ifdef PRINT_THIS + << this +#endif + ); + + if (!m_socket) { + m_socket = Socket::CreateSocket (GetNode (), + TcpSocketFactory::GetTypeId ()); + m_socket->Bind (); + } + + m_socket->Connect (m_remote); + m_socket->SetConnectCallback + ( + MakeCallback (&TalkerApp::ConnectionSucceeded,this), + MakeCallback (&TalkerApp::ConnectionFailed,this) + ); + m_socket->SetRecvCallback (MakeCallback (&TalkerApp::HandleRead, this)); +} + +void +TalkerApp::StartApplicationRecv () +{ + NS_LOG_FUNCTION ((i_am_listener ? "Server|" : "Client|") +#ifdef PRINT_THIS + << this +#endif + ); + if (!m_servsocket) { + m_servsocket = Socket::CreateSocket (GetNode (), + TcpSocketFactory::GetTypeId ()); + m_servsocket->Bind (m_local); + m_servsocket->Listen (0); + } + + m_servsocket->SetAcceptCallback + ( + MakeCallback (&TalkerApp::ConnectionRequested,this), + MakeCallback (&TalkerApp::ConnectionCreated,this) + ); +} + +void +TalkerApp::ConfRecv (Ptr node, const Address &addr) +{ + i_am_listener = 1; + NS_LOG_FUNCTION ((i_am_listener ? "Server|" : "Client|") +#ifdef PRINT_THIS + << this +#endif + << node + << addr + ); + m_local = addr; + node->AddApplication (this); +} + +void +TalkerApp::ConfSend (Ptr node, const Address &addr) +{ + i_am_listener = 0; + NS_LOG_FUNCTION ((i_am_listener ? "Server|" : "Client|") +#ifdef PRINT_THIS + << this +#endif + << node + << addr + ); + m_remote = addr; + node->AddApplication (this); +} + + +void +TalkerApp::SendPacket (std::string label,char fill,uint32_t payloadsize) +{ + NS_LOG_FUNCTION ((i_am_listener ? "Server|" : "Client|") +#ifdef PRINT_THIS + << this +#endif + << label + << fill + << payloadsize + ); + +#if 0 + Ptr p = Create (payloadsize); // zero byte filled packet. +#else + uint8_t *buf = (uint8_t *) malloc(payloadsize*sizeof(uint8_t)); + memset(buf,fill,payloadsize); + Ptr p = Create (buf,payloadsize); // filled packet. + free(buf); +#endif + if (verbose) { + p->Print (fileOut << "Before Marking|"); + fileOut << std::endl; + } + + ArchHeader hdr; + hdr.SetStrValue (label); + hdr.SetIntValue (p->GetSize()); + p->AddHeader (hdr); + if (verbose) { + p->Print(fileOut << "After Header Marking|"); + fileOut << std::endl; + } + + m_socket->Send (p); +} + +void +TalkerApp::StopApplication () +{ + NS_LOG_FUNCTION ((i_am_listener ? "Server|" : "Client|") +#ifdef PRINT_THIS + << this +#endif + ); + if (m_socket) + m_socket->SetRecvCallback (MakeNullCallback > ()); +} + +void +TalkerApp::HandleRead (Ptr socket) +{ + left_to_read_iterator_type iter = m_left_to_read.find (socket); + if (iter == m_left_to_read.end ()) + m_left_to_read[socket] = 0; + + std::ostringstream pretty; + pretty << (i_am_listener ? "Server" : "Client") + << (iter == m_left_to_read.end () ? + "(new)" : "(old)") + << "|"; + + NS_LOG_FUNCTION ( pretty.str () +#ifdef PRINT_THIS + << this +#endif + << socket + ); + /* + * NOTE: I can crash with the # bytes == 500 rather than 536 + * which seems to be the default MTU + */ + +#ifdef TOO_SMALL_BUG + const uint32_t number_of_bytes_willing_to_read = 500; +#else + const uint32_t number_of_bytes_willing_to_read = 536; +#endif + const uint32_t unused_flags = 0; + + Ptr packet; + while (packet = socket->Recv (number_of_bytes_willing_to_read, + unused_flags) ){ + std::string raw_rle = rle(packet->PeekData(), + packet->GetSize()); + SocketAddressTag rx_addr_tag; + bool found; + found = packet->FindFirstMatchingTag (rx_addr_tag); + NS_ASSERT (found); + Address from = rx_addr_tag.GetAddress (); + // XXX packet->RemoveTag (tag); + if (InetSocketAddress::IsMatchingType (from)) { + InetSocketAddress address = InetSocketAddress::ConvertFrom (from); + +#ifdef VERBOSE_TESTING + packet->Print (fileOut << "Packet Dump: "); + fileOut << std::endl; +#endif + + + bool freshly_in_the_loop = true; + do { +#if defined(RECV_PRINT) + fileOut + << raw_rle // :PeekBuffer> + << (freshly_in_the_loop ? " *" : " ") /* used to see if the do while + * does anything */ + << "bytes from " + << address.GetIpv4 () << " [" << address << "] "; +#endif + freshly_in_the_loop = false; + int header_bytes = 0; + ArchHeader* hdr = 0; // sadly, can't be a Ptr<> + if ( + (m_left_to_read[socket] == 0) + ) { + hdr = new ArchHeader; + if (packet->RemoveHeader (*hdr)) { + m_left_to_read[socket] = hdr->GetIntValue (); + header_bytes = hdr->GetSerializedSize (); + } else { + ; // never get here, ns3 dumps if no header is there. + } + } + uint32_t num_bytes_processed = 0; + if (m_left_to_read[socket] <= packet->GetSize ()) { + packet->RemoveAtStart (m_left_to_read[socket]); + num_bytes_processed = m_left_to_read[socket]; + m_left_to_read[socket] = 0; + + } else { + m_left_to_read[socket] -= packet->GetSize (); + num_bytes_processed = packet->GetSize (); + packet->RemoveAtStart (packet->GetSize ()); + } + +#if defined(RECV_PRINT) + fileOut + << "<" + << packet->GetSize () + << "|" + << num_bytes_processed + ; + if (header_bytes) + fileOut + << "(" + << header_bytes + << ")" + ; + fileOut + << "|" + << m_left_to_read[socket] + << ">"; +#ifdef VERBOSE_TESTING + if (hdr) + hdr->Print(fileOut << " "); +#endif + fileOut << std::endl; +#endif + if (hdr) + delete hdr; // free what we new.... + } while ( + packet->GetSize () + ); + } else { + fileOut << "not a match in HandleRead" << std::endl; + } + + } +} + +//---------------Non-member functions------------------------------------------- +/* + * returns a string containing the length of the buffer, + * followed by an run length encoded version of the buffer + * un-printables are represented by '.' (i.e. special_marker + * const). + */ +std::string rle(const uint8_t *buf, int buflen) { + + int justify = 5; + std::ostringstream o; + const uint8_t min_rep = 3; + uint8_t cur_char = 0; + const uint8_t special_marker = '.'; + int cur_cnt = 0; + if (justify) { + o << std::setw(justify) << std::right << buflen << ":"; + } else { + o << buflen << ":"; + } + + for (int i = 0; i < buflen; i++) { + if ( + (!isprint(buf[i]) && cur_char == special_marker) || + (buf[i] == cur_char) + ) + cur_cnt++; + else { + if (cur_cnt >= min_rep) + o << (isprint(cur_char) ? static_cast(cur_char) : '.') << "{" + << cur_cnt << "}"; + else + for (int irep=0; irep < cur_cnt; irep++) + o << (isprint(cur_char) ? static_cast(cur_char) : '.'); + if (isprint(buf[i])) + cur_char = buf[i]; + else + cur_char = special_marker; + cur_cnt = 1; + } + } + if (cur_cnt >= min_rep) + o << (isprint(cur_char) ? static_cast(cur_char) : '.') << "{" + << cur_cnt << "}"; + else + for (int irep=0; irep < cur_cnt; irep++) + o << (isprint(cur_char) ? static_cast(cur_char) : '.'); + return o.str(); +} + +//---------------Main----------------------------------------------------------- +int +main (int argc, char *argv[]) { + + std::clog.rdbuf (fileOut.rdbuf ()); /* till we can do this in ns3::log + * without this ns3 logging messages + * are far away from normal output + */ + +#ifdef VERBOSE_TESTING + LogComponentEnable ("tcp-2way",LOG_LEVEL_ALL); +#endif + + RandomVariable::UseGlobalSeed (1, 1, 2, 3, 5, 8); + Packet::EnableMetadata (); + + // boilerplate: "c0[0]" is Tx, "c0[1]" is Rx. + NodeContainer c0; + c0.Create (2); + + // We create the channels first without any IP addressing information + PointToPointHelper p2p; + p2p.SetDeviceAttribute ("DataRate",DataRateValue (DataRate (10000000))); + p2p.SetChannelAttribute ("Delay",TimeValue (MilliSeconds (10))); + NetDeviceContainer dev0 = p2p.Install (c0); + + // add ip/tcp stack to nodes. + InternetStackHelper internet; + internet.Install (c0); + + // Later, we add IP addresses. + Ipv4AddressHelper ipv4; + ipv4.SetBase ("10.1.0.0", "255.255.255.0"); + Ipv4InterfaceContainer ifaces = ipv4.Assign (dev0); + + // Configure the apps. + uint16_t servPort = 32; + + + // setup Rx side using ns3::Node "c0[1]" to listen for ANY:servPort + Ptr sink = CreateObject(); + sink->ConfRecv (c0.Get (1), + InetSocketAddress (Ipv4Address::GetAny (), servPort)); + sink->Start (Seconds (0.0)); // somehow we get by without a Stop. bad form? + + // setup Tx side using ns3::Node "c0[0]" to talk to "c0[1]":servPort + Ptr source = CreateObject(); + source->ConfSend (c0.Get (0), + InetSocketAddress (ifaces.GetAddress (1), + servPort)); + source->Start (Seconds (0.0)); + + // 10 sec is an eternity for this case, we should be done by then. + Simulator::Stop (Seconds (10)); + + + // For regression use only output ascii and pcap traces. +#ifdef REGRESSION_MODE + std::ofstream ascii; + ascii.open ("tcp-2way.tr"); + PointToPointHelper::EnableAsciiAll (ascii); + PointToPointHelper::EnablePcapAll ("tcp-2way"); +#endif + + /* + * Now lets schedule some packets and go. For scheduling packets + * we have to be careful not to do the backchannel too early or + * we try to use a socket that doesn't yet exist since on the Rx + * side the socket is created as part of the normal Tx->Rx connection + * setup. + * + * The delay of 40ms was by trial and error and seems good enough. It + * would be nice to know what the bounds are and why.... + */ + + char tagchar = 'A'; // the fill character in case we fill in SendPacket. + + Time d2t = MilliSeconds(40); /* rate to change time offset (dt) so packets + * are sent in order (Tx->Rx, Rx->Tx for a given + * size over a range of sizes).*/ + + Time dt = MilliSeconds(0); /* ns3 doesn't take absolute times, but times + * relative to Simulator::Now() */ + + uint32_t size = 0; + source->ScheduleSendPacket (dt, tagchar, size); + dt += d2t; + ++tagchar; + sink->ScheduleSendPacket (dt, tagchar, size); + for (size = 1; size <= 1000000; size *= 10) { + dt += d2t; + ++tagchar; + source->ScheduleSendPacket (dt, tagchar, size); + dt += d2t; + ++tagchar; + sink->ScheduleSendPacket (dt, tagchar, size); + } + + // Release the Hounds!! + Simulator::Run (); + Simulator::Destroy (); + fileOut.close(); +} diff --git a/examples/wscript b/examples/wscript index 1892e3f90..f3c6a3529 100644 --- a/examples/wscript +++ b/examples/wscript @@ -56,6 +56,10 @@ def build(bld): ['point-to-point', 'internet-stack']) obj.source = 'tcp-errors.cc' + obj = bld.create_ns3_program('tcp-2way', + ['point-to-point', 'internet-stack']) + obj.source = 'tcp-2way.cc' + obj = bld.create_ns3_program('tcp-star-server', ['point-to-point', 'internet-stack']) obj.source = 'tcp-star-server.cc' diff --git a/regression/tests/test-tcp-2way.py b/regression/tests/test-tcp-2way.py new file mode 100644 index 000000000..8e6c7d087 --- /dev/null +++ b/regression/tests/test-tcp-2way.py @@ -0,0 +1,13 @@ +#! /usr/bin/env python + +"""Generic trace-comparison-type regression test.""" + +import os +import shutil +import tracediff + +def run(verbose, generate, refDirName): + """Execute a test.""" + + return tracediff.run_test(verbose, generate, refDirName, + "tcp-2way") From fb17731cabf3b8d26a3511256283fb8114d2c01a Mon Sep 17 00:00:00 2001 From: Mathieu Lacage Date: Wed, 9 Jul 2008 19:52:15 -0700 Subject: [PATCH 154/495] more cleanups based on bug 249. --- src/node/tcp-socket-factory.h | 2 -- src/node/udp-socket-factory.h | 8 -------- 2 files changed, 10 deletions(-) diff --git a/src/node/tcp-socket-factory.h b/src/node/tcp-socket-factory.h index 92cede256..418bafde6 100644 --- a/src/node/tcp-socket-factory.h +++ b/src/node/tcp-socket-factory.h @@ -48,8 +48,6 @@ class TcpSocketFactory : public SocketFactory public: static TypeId GetTypeId (void); - virtual Ptr CreateSocket (void) = 0; - }; } // namespace ns3 diff --git a/src/node/udp-socket-factory.h b/src/node/udp-socket-factory.h index 4e2b74354..ff8309b4e 100644 --- a/src/node/udp-socket-factory.h +++ b/src/node/udp-socket-factory.h @@ -42,14 +42,6 @@ class UdpSocketFactory : public SocketFactory public: static TypeId GetTypeId (void); - /** - * \return smart pointer to Socket - * - * API for creating socket instances; must be implemented by UDP - * implementations.. - */ - virtual Ptr CreateSocket (void) = 0; - }; } // namespace ns3 From 7b34f76ef7128bb4d8965a5265a783c9e957ef69 Mon Sep 17 00:00:00 2001 From: Mathieu Lacage Date: Wed, 9 Jul 2008 20:11:16 -0700 Subject: [PATCH 155/495] define NS_DEPRECATED --- src/core/deprecated.h | 10 ++++++++++ src/core/wscript | 1 + 2 files changed, 11 insertions(+) create mode 100644 src/core/deprecated.h diff --git a/src/core/deprecated.h b/src/core/deprecated.h new file mode 100644 index 000000000..63ff10f95 --- /dev/null +++ b/src/core/deprecated.h @@ -0,0 +1,10 @@ +#ifndef NS3_DEPRECATED_H +#define NS3_DEPRECATED_H + +#ifdef __GNUC__ +#define NS_DEPRECATED __attribute__ ((deprecated)) +#else +#define NS_DEPRECATED +#endif + +#endif /* NS3_DEPRECATED_H */ diff --git a/src/core/wscript b/src/core/wscript index bf7ca3b5d..9646b06c7 100644 --- a/src/core/wscript +++ b/src/core/wscript @@ -110,5 +110,6 @@ def build(bld): 'trace-source-accessor.h', 'config.h', 'object-vector.h', + 'deprecated.h' ] From 7f07acc254a148e3835ec69fe685cee9bbbe07d4 Mon Sep 17 00:00:00 2001 From: Mathieu Lacage Date: Wed, 9 Jul 2008 20:12:05 -0700 Subject: [PATCH 156/495] use NS_DEPRECATED for bug 232. --- src/helper/csma-helper.cc | 11 +++++++++++ src/helper/csma-helper.h | 4 ++++ src/helper/point-to-point-helper.cc | 11 +++++++++++ src/helper/point-to-point-helper.h | 4 ++++ 4 files changed, 30 insertions(+) diff --git a/src/helper/csma-helper.cc b/src/helper/csma-helper.cc index 8524a7122..5cea6ec3d 100644 --- a/src/helper/csma-helper.cc +++ b/src/helper/csma-helper.cc @@ -63,6 +63,17 @@ CsmaHelper::SetChannelAttribute (std::string n1, const AttributeValue &v1) m_channelFactory.Set (n1, v1); } +void +CsmaHelper::SetDeviceParameter (std::string n1, const AttributeValue &v1) +{ + SetDeviceAttribute (n1, v1); +} +void +CsmaHelper::SetChannelParameter (std::string n1, const AttributeValue &v1) +{ + SetChannelAttribute (n1, v1); +} + void CsmaHelper::EnablePcap (std::string filename, uint32_t nodeid, uint32_t deviceid) { diff --git a/src/helper/csma-helper.h b/src/helper/csma-helper.h index 595c525ea..89cb7f138 100644 --- a/src/helper/csma-helper.h +++ b/src/helper/csma-helper.h @@ -27,6 +27,7 @@ #include "ns3/net-device-container.h" #include "ns3/node-container.h" #include "ns3/csma-channel.h" +#include "ns3/deprecated.h" namespace ns3 { @@ -79,6 +80,9 @@ public: */ void SetChannelAttribute (std::string n1, const AttributeValue &v1); + void SetDeviceParameter (std::string n1, const AttributeValue &v1) NS_DEPRECATED; + void SetChannelParameter (std::string n1, const AttributeValue &v1) NS_DEPRECATED; + /** * \param filename filename prefix to use for pcap files. * \param nodeid the id of the node to generate pcap output for. diff --git a/src/helper/point-to-point-helper.cc b/src/helper/point-to-point-helper.cc index eba654a17..ec2c1a7e6 100644 --- a/src/helper/point-to-point-helper.cc +++ b/src/helper/point-to-point-helper.cc @@ -63,6 +63,17 @@ PointToPointHelper::SetChannelAttribute (std::string n1, const AttributeValue &v m_channelFactory.Set (n1, v1); } +void +PointToPointHelper::SetDeviceParameter (std::string name, const AttributeValue &value) +{ + SetDeviceAttribute (name, value); +} +void +PointToPointHelper::SetChannelParameter (std::string name, const AttributeValue &value) +{ + SetChannelAttribute (name, value); +} + void PointToPointHelper::EnablePcap (std::string filename, uint32_t nodeid, uint32_t deviceid) { diff --git a/src/helper/point-to-point-helper.h b/src/helper/point-to-point-helper.h index 7603a50d0..a86daf52a 100644 --- a/src/helper/point-to-point-helper.h +++ b/src/helper/point-to-point-helper.h @@ -23,6 +23,7 @@ #include "ns3/object-factory.h" #include "ns3/net-device-container.h" #include "ns3/node-container.h" +#include "ns3/deprecated.h" #include namespace ns3 { @@ -78,6 +79,9 @@ public: */ void SetChannelAttribute (std::string name, const AttributeValue &value); + void SetDeviceParameter (std::string name, const AttributeValue &value) NS_DEPRECATED; + void SetChannelParameter (std::string name, const AttributeValue &value) NS_DEPRECATED; + /** * \param filename filename prefix to use for pcap files. * \param nodeid the id of the node to generate pcap output for. From 731a76246f86ccffb54384653239dd8b295d06bb Mon Sep 17 00:00:00 2001 From: Mathieu Lacage Date: Thu, 10 Jul 2008 15:58:24 -0700 Subject: [PATCH 157/495] bug 247: tcp checksum crashes when enabled. --- src/common/buffer.cc | 6 +++ src/common/buffer.h | 5 ++ src/internet-stack/tcp-header.cc | 68 +++++++++++---------------- src/internet-stack/tcp-header.h | 23 +++------ src/internet-stack/tcp-l4-protocol.cc | 3 +- src/internet-stack/udp-header.cc | 54 ++++++++++----------- src/internet-stack/udp-header.h | 10 ++-- src/internet-stack/udp-l4-protocol.cc | 8 ++-- 8 files changed, 78 insertions(+), 99 deletions(-) diff --git a/src/common/buffer.cc b/src/common/buffer.cc index 91b35b9f8..d00141f13 100644 --- a/src/common/buffer.cc +++ b/src/common/buffer.cc @@ -1128,6 +1128,12 @@ Buffer::Iterator::CalculateIpChecksum(uint16_t size, uint32_t initialChecksum) return ~sum; } +uint32_t +Buffer::Iterator::GetSize (void) const +{ + return m_dataEnd - m_dataStart; +} + } // namespace ns3 diff --git a/src/common/buffer.h b/src/common/buffer.h index 245f31ea8..4c65518de 100644 --- a/src/common/buffer.h +++ b/src/common/buffer.h @@ -358,6 +358,11 @@ public: */ uint16_t CalculateIpChecksum(uint16_t size, uint32_t initialChecksum); + /** + * \returns the size of the underlying buffer we are iterating + */ + uint32_t GetSize (void) const; + private: friend class Buffer; Iterator (Buffer const*buffer); diff --git a/src/internet-stack/tcp-header.cc b/src/internet-stack/tcp-header.cc index e23c9e281..93c2428ca 100644 --- a/src/internet-stack/tcp-header.cc +++ b/src/internet-stack/tcp-header.cc @@ -23,6 +23,7 @@ #include "tcp-socket-impl.h" #include "tcp-header.h" #include "ns3/buffer.h" +#include "ns3/address-utils.h" namespace ns3 { @@ -37,8 +38,6 @@ TcpHeader::TcpHeader () m_flags (0), m_windowSize (0xffff), m_urgentPointer (0), - m_initialChecksum(0), - m_checksum (0), m_calcChecksum(false), m_goodChecksum(true) {} @@ -52,11 +51,6 @@ TcpHeader::EnableChecksums (void) m_calcChecksum = true; } -void TcpHeader::SetPayloadSize(uint16_t payloadSize) -{ - m_payloadSize = payloadSize; -} - void TcpHeader::SetSourcePort (uint16_t port) { m_sourcePort = port; @@ -85,10 +79,6 @@ void TcpHeader::SetWindowSize (uint16_t windowSize) { m_windowSize = windowSize; } -void TcpHeader::SetChecksum (uint16_t checksum) -{ - m_checksum = checksum; -} void TcpHeader::SetUrgentPointer (uint16_t urgentPointer) { m_urgentPointer = urgentPointer; @@ -122,10 +112,6 @@ uint16_t TcpHeader::GetWindowSize () const { return m_windowSize; } -uint16_t TcpHeader::GetChecksum () const -{ - return m_checksum; -} uint16_t TcpHeader::GetUrgentPointer () const { return m_urgentPointer; @@ -133,29 +119,31 @@ uint16_t TcpHeader::GetUrgentPointer () const void TcpHeader::InitializeChecksum (Ipv4Address source, - Ipv4Address destination, - uint8_t protocol) + Ipv4Address destination, + uint8_t protocol) { - Buffer buf = Buffer(12); - uint8_t tmp[4]; - Buffer::Iterator it; - uint16_t tcpLength = m_payloadSize + GetSerializedSize(); + m_source = source; + m_destination = destination; + m_protocol = protocol; +} - buf.AddAtStart(12); - it = buf.Begin(); +uint16_t +TcpHeader::CalculateHeaderChecksum (uint16_t size) const +{ + Buffer buf = Buffer (12); + buf.AddAtStart (12); + Buffer::Iterator it = buf.Begin (); - source.Serialize(tmp); - it.Write(tmp, 4); /* source IP address */ - destination.Serialize(tmp); - it.Write(tmp, 4); /* destination IP address */ - it.WriteU8(0); /* protocol */ - it.WriteU8(protocol); /* protocol */ - it.WriteU8(tcpLength >> 8); /* length */ - it.WriteU8(tcpLength & 0xff); /* length */ + WriteTo (it, m_source); + WriteTo (it, m_destination); + it.WriteU8 (0); /* protocol */ + it.WriteU8 (m_protocol); /* protocol */ + it.WriteU8 (size >> 8); /* length */ + it.WriteU8 (size & 0xff); /* length */ - it = buf.Begin(); + it = buf.Begin (); /* we don't CompleteChecksum ( ~ ) now */ - m_initialChecksum = ~(it.CalculateIpChecksum(12)); + return ~(it.CalculateIpChecksum (12)); } bool @@ -219,7 +207,6 @@ uint32_t TcpHeader::GetSerializedSize (void) const void TcpHeader::Serialize (Buffer::Iterator start) const { Buffer::Iterator i = start; - uint16_t tcpLength = m_payloadSize + GetSerializedSize(); i.WriteHtonU16 (m_sourcePort); i.WriteHtonU16 (m_destinationPort); i.WriteHtonU32 (m_sequenceNumber); @@ -231,8 +218,9 @@ void TcpHeader::Serialize (Buffer::Iterator start) const if(m_calcChecksum) { + uint16_t headerChecksum = CalculateHeaderChecksum (start.GetSize ()); i = start; - uint16_t checksum = i.CalculateIpChecksum(tcpLength, m_initialChecksum); + uint16_t checksum = i.CalculateIpChecksum(start.GetSize (), headerChecksum); i = start; i.Next(16); @@ -250,16 +238,16 @@ uint32_t TcpHeader::Deserialize (Buffer::Iterator start) m_flags = field & 0x3F; m_length = field>>12; m_windowSize = i.ReadNtohU16 (); - m_checksum = i.ReadU16 (); + i.Next (2); m_urgentPointer = i.ReadNtohU16 (); if(m_calcChecksum) - { + { + uint16_t headerChecksum = CalculateHeaderChecksum (start.GetSize ()); i = start; - uint16_t checksum = i.CalculateIpChecksum(m_payloadSize + GetSerializedSize(), m_initialChecksum); - + uint16_t checksum = i.CalculateIpChecksum(start.GetSize (), headerChecksum); m_goodChecksum = (checksum == 0); - } + } return GetSerializedSize (); } diff --git a/src/internet-stack/tcp-header.h b/src/internet-stack/tcp-header.h index 99d91747a..bfcbc81d8 100644 --- a/src/internet-stack/tcp-header.h +++ b/src/internet-stack/tcp-header.h @@ -77,10 +77,6 @@ public: * \param windowSize the window size for this TcpHeader */ void SetWindowSize (uint16_t windowSize); - /** - * \param checksum the checksum for this TcpHeader - */ - void SetChecksum (uint16_t checksum); /** * \param urgentPointer the urgent pointer for this TcpHeader */ @@ -116,10 +112,6 @@ public: * \return the window size for this TcpHeader */ uint16_t GetWindowSize () const; - /** - * \return the checksum for this TcpHeader - */ - uint16_t GetChecksum () const; /** * \return the urgent pointer for this TcpHeader */ @@ -150,11 +142,6 @@ public: virtual void Serialize (Buffer::Iterator start) const; virtual uint32_t Deserialize (Buffer::Iterator start); - /** - * \param size The payload size in bytes - */ - void SetPayloadSize (uint16_t size); - /** * \brief Is the TCP checksum correct ? * \returns true if the checksum is correct, false otherwise. @@ -162,6 +149,7 @@ public: bool IsChecksumOk (void) const; private: + uint16_t CalculateHeaderChecksum (uint16_t size) const; uint16_t m_sourcePort; uint16_t m_destinationPort; uint32_t m_sequenceNumber; @@ -170,13 +158,14 @@ private: uint8_t m_flags; // really a uint6_t uint16_t m_windowSize; uint16_t m_urgentPointer; - uint16_t m_payloadSize; - uint16_t m_initialChecksum; - uint16_t m_checksum; + Ipv4Address m_source; + Ipv4Address m_destination; + uint8_t m_protocol; + + uint16_t m_initialChecksum; bool m_calcChecksum; bool m_goodChecksum; - }; }; // namespace ns3 diff --git a/src/internet-stack/tcp-l4-protocol.cc b/src/internet-stack/tcp-l4-protocol.cc index f0e9c0b9b..3f385cf5a 100644 --- a/src/internet-stack/tcp-l4-protocol.cc +++ b/src/internet-stack/tcp-l4-protocol.cc @@ -448,6 +448,7 @@ TcpL4Protocol::Receive (Ptr packet, if(m_calcChecksum) { tcpHeader.EnableChecksums(); + tcpHeader.InitializeChecksum (source, destination, PROT_NUMBER); } packet->PeekHeader (tcpHeader); @@ -495,7 +496,6 @@ TcpL4Protocol::Send (Ptr packet, TcpHeader tcpHeader; tcpHeader.SetDestinationPort (dport); tcpHeader.SetSourcePort (sport); - tcpHeader.SetPayloadSize(packet->GetSize()); if(m_calcChecksum) { tcpHeader.EnableChecksums(); @@ -529,7 +529,6 @@ TcpL4Protocol::SendPacket (Ptr packet, TcpHeader outgoingHeader, // XXX outgoingHeader cannot be logged outgoingHeader.SetLength (5); //header length in units of 32bit words - outgoingHeader.SetPayloadSize(packet->GetSize()); /* outgoingHeader.SetUrgentPointer (0); //XXX */ if(m_calcChecksum) { diff --git a/src/internet-stack/udp-header.cc b/src/internet-stack/udp-header.cc index 64a83710f..ce0af0766 100644 --- a/src/internet-stack/udp-header.cc +++ b/src/internet-stack/udp-header.cc @@ -19,6 +19,7 @@ */ #include "udp-header.h" +#include "ns3/address-utils.h" namespace ns3 { @@ -32,8 +33,6 @@ UdpHeader::UdpHeader () : m_sourcePort (0xfffd), m_destinationPort (0xfffd), m_payloadSize (0xfffd), - m_initialChecksum (0), - m_checksum(0), m_calcChecksum(false), m_goodChecksum(true) {} @@ -71,35 +70,31 @@ UdpHeader::GetDestinationPort (void) const return m_destinationPort; } void -UdpHeader::SetPayloadSize (uint16_t size) -{ - m_payloadSize = size; -} -void UdpHeader::InitializeChecksum (Ipv4Address source, Ipv4Address destination, uint8_t protocol) { - Buffer buf = Buffer(12); - uint8_t tmp[4]; - Buffer::Iterator it; - uint16_t udpLength = m_payloadSize + GetSerializedSize(); + m_source = source; + m_destination = destination; + m_protocol = protocol; +} +uint16_t +UdpHeader::CalculateHeaderChecksum (uint16_t size) const +{ + Buffer buf = Buffer (12); + buf.AddAtStart (12); + Buffer::Iterator it = buf.Begin (); - buf.AddAtStart(12); - it = buf.Begin(); + WriteTo (it, m_source); + WriteTo (it, m_destination); + it.WriteU8 (0); /* protocol */ + it.WriteU8 (m_protocol); /* protocol */ + it.WriteU8 (size >> 8); /* length */ + it.WriteU8 (size & 0xff); /* length */ - source.Serialize(tmp); - it.Write(tmp, 4); /* source IP address */ - destination.Serialize(tmp); - it.Write(tmp, 4); /* destination IP address */ - it.WriteU8(0); /* protocol */ - it.WriteU8(protocol); /* protocol */ - it.WriteU8(udpLength >> 8); /* length */ - it.WriteU8(udpLength & 0xff); /* length */ - - it = buf.Begin(); + it = buf.Begin (); /* we don't CompleteChecksum ( ~ ) now */ - m_initialChecksum = ~(it.CalculateIpChecksum(12)); + return ~(it.CalculateIpChecksum (12)); } bool @@ -142,17 +137,17 @@ void UdpHeader::Serialize (Buffer::Iterator start) const { Buffer::Iterator i = start; - uint16_t udpLength = m_payloadSize + GetSerializedSize(); i.WriteHtonU16 (m_sourcePort); i.WriteHtonU16 (m_destinationPort); - i.WriteHtonU16 (udpLength); + i.WriteHtonU16 (start.GetSize ()); i.WriteU16 (0); if (m_calcChecksum) { + uint16_t headerChecksum = CalculateHeaderChecksum (start.GetSize ()); i = start; - uint16_t checksum = i.CalculateIpChecksum(udpLength, m_initialChecksum); + uint16_t checksum = i.CalculateIpChecksum (start.GetSize (), headerChecksum); i = start; i.Next(6); @@ -166,12 +161,13 @@ UdpHeader::Deserialize (Buffer::Iterator start) m_sourcePort = i.ReadNtohU16 (); m_destinationPort = i.ReadNtohU16 (); m_payloadSize = i.ReadNtohU16 () - GetSerializedSize (); - m_checksum = i.ReadU16(); + i.Next (2); if(m_calcChecksum) { + uint16_t headerChecksum = CalculateHeaderChecksum (start.GetSize ()); i = start; - uint16_t checksum = i.CalculateIpChecksum(m_payloadSize + GetSerializedSize(), m_initialChecksum); + uint16_t checksum = i.CalculateIpChecksum (start.GetSize (), headerChecksum); m_goodChecksum = (checksum == 0); } diff --git a/src/internet-stack/udp-header.h b/src/internet-stack/udp-header.h index d3908e64f..23aaa1450 100644 --- a/src/internet-stack/udp-header.h +++ b/src/internet-stack/udp-header.h @@ -66,10 +66,6 @@ public: * \return the destination port for this UdpHeader */ uint16_t GetDestinationPort (void) const; - /** - * \param size The payload size in bytes - */ - void SetPayloadSize (uint16_t size); /** * \param source the ip source to use in the underlying @@ -100,12 +96,14 @@ public: bool IsChecksumOk (void) const; private: + uint16_t CalculateHeaderChecksum (uint16_t size) const; uint16_t m_sourcePort; uint16_t m_destinationPort; uint16_t m_payloadSize; - uint16_t m_initialChecksum; - uint16_t m_checksum; + Ipv4Address m_source; + Ipv4Address m_destination; + uint8_t m_protocol; bool m_calcChecksum; bool m_goodChecksum; }; diff --git a/src/internet-stack/udp-l4-protocol.cc b/src/internet-stack/udp-l4-protocol.cc index 8def85407..75b6e756d 100644 --- a/src/internet-stack/udp-l4-protocol.cc +++ b/src/internet-stack/udp-l4-protocol.cc @@ -163,7 +163,6 @@ UdpL4Protocol::Receive(Ptr packet, udpHeader.EnableChecksums(); } - udpHeader.SetPayloadSize (packet->GetSize () - udpHeader.GetSerializedSize ()); udpHeader.InitializeChecksum (source, destination, PROT_NUMBER); packet->RemoveHeader (udpHeader); @@ -195,13 +194,12 @@ UdpL4Protocol::Send (Ptr packet, if(m_calcChecksum) { udpHeader.EnableChecksums(); + udpHeader.InitializeChecksum (saddr, + daddr, + PROT_NUMBER); } udpHeader.SetDestinationPort (dport); udpHeader.SetSourcePort (sport); - udpHeader.SetPayloadSize (packet->GetSize ()); - udpHeader.InitializeChecksum (saddr, - daddr, - PROT_NUMBER); packet->AddHeader (udpHeader); From 14beae6e8db621ede8b980bc1070daa6125645a2 Mon Sep 17 00:00:00 2001 From: Raj Bhattacharjea Date: Thu, 10 Jul 2008 21:32:33 -0400 Subject: [PATCH 158/495] Remove tcp-2way as a regression test --- regression/tests/test-tcp-2way.py | 13 ------------- 1 file changed, 13 deletions(-) delete mode 100644 regression/tests/test-tcp-2way.py diff --git a/regression/tests/test-tcp-2way.py b/regression/tests/test-tcp-2way.py deleted file mode 100644 index 8e6c7d087..000000000 --- a/regression/tests/test-tcp-2way.py +++ /dev/null @@ -1,13 +0,0 @@ -#! /usr/bin/env python - -"""Generic trace-comparison-type regression test.""" - -import os -import shutil -import tracediff - -def run(verbose, generate, refDirName): - """Execute a test.""" - - return tracediff.run_test(verbose, generate, refDirName, - "tcp-2way") From 6911a69356903102b7db29071075d3ff074b5756 Mon Sep 17 00:00:00 2001 From: "Gustavo J. A. M. Carneiro" Date: Fri, 11 Jul 2008 11:36:59 +0100 Subject: [PATCH 159/495] Add compilation flag -Wno-error=deprecated-declarations, or else the NS_DEPRECATED macro becomes useless. --- wscript | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wscript b/wscript index 52856eeba..b2a6200c6 100644 --- a/wscript +++ b/wscript @@ -194,7 +194,7 @@ def configure(conf): if (os.path.basename(conf.env['CXX']).startswith("g++") and 'CXXFLAGS' not in os.environ): - variant_env.append_value('CXXFLAGS', ['-Werror']) + variant_env.append_value('CXXFLAGS', ['-Werror', '-Wno-error=deprecated-declarations']) if 'debug' in Params.g_options.debug_level.lower(): variant_env.append_value('CXXDEFINES', 'NS3_ASSERT_ENABLE') From 9d5d16844467fb3685c91beb003f9aecd5c2227a Mon Sep 17 00:00:00 2001 From: "Gustavo J. A. M. Carneiro" Date: Fri, 11 Jul 2008 18:39:19 +0100 Subject: [PATCH 160/495] Rescan APIs --- bindings/python/ns3_module_common.py | 2 ++ bindings/python/ns3_module_helper.py | 8 ++++++++ bindings/python/ns3_module_internet_stack.py | 8 -------- bindings/python/ns3_module_node.py | 8 ++------ 4 files changed, 12 insertions(+), 14 deletions(-) diff --git a/bindings/python/ns3_module_common.py b/bindings/python/ns3_module_common.py index 367fc2d98..658c1fca3 100644 --- a/bindings/python/ns3_module_common.py +++ b/bindings/python/ns3_module_common.py @@ -369,6 +369,8 @@ def register_Ns3BufferIterator_methods(root_module, cls): cls.add_method('CalculateIpChecksum', 'uint16_t', [param('uint16_t', 'size')]) ## buffer.h: uint16_t ns3::Buffer::Iterator::CalculateIpChecksum(uint16_t size, uint32_t initialChecksum) [member function] cls.add_method('CalculateIpChecksum', 'uint16_t', [param('uint16_t', 'size'), param('uint32_t', 'initialChecksum')]) + ## buffer.h: uint32_t ns3::Buffer::Iterator::GetSize() const [member function] + cls.add_method('GetSize', 'uint32_t', [], is_const=True) return def register_Ns3Chunk_methods(root_module, cls): diff --git a/bindings/python/ns3_module_helper.py b/bindings/python/ns3_module_helper.py index ca1ce24f0..99b4fa564 100644 --- a/bindings/python/ns3_module_helper.py +++ b/bindings/python/ns3_module_helper.py @@ -168,6 +168,10 @@ def register_Ns3PointToPointHelper_methods(root_module, cls): cls.add_method('SetDeviceAttribute', 'void', [param('std::string', 'name'), param('ns3::AttributeValue&', 'value', is_const=True)]) ## point-to-point-helper.h: void ns3::PointToPointHelper::SetChannelAttribute(std::string name, ns3::AttributeValue const & value) [member function] cls.add_method('SetChannelAttribute', 'void', [param('std::string', 'name'), param('ns3::AttributeValue&', 'value', is_const=True)]) + ## point-to-point-helper.h: void ns3::PointToPointHelper::SetDeviceParameter(std::string name, ns3::AttributeValue const & value) [member function] + cls.add_method('SetDeviceParameter', 'void', [param('std::string', 'name'), param('ns3::AttributeValue&', 'value', is_const=True)]) + ## point-to-point-helper.h: void ns3::PointToPointHelper::SetChannelParameter(std::string name, ns3::AttributeValue const & value) [member function] + cls.add_method('SetChannelParameter', 'void', [param('std::string', 'name'), param('ns3::AttributeValue&', 'value', is_const=True)]) ## point-to-point-helper.h: static void ns3::PointToPointHelper::EnablePcap(std::string filename, uint32_t nodeid, uint32_t deviceid) [member function] cls.add_method('EnablePcap', 'void', [param('std::string', 'filename'), param('uint32_t', 'nodeid'), param('uint32_t', 'deviceid')], is_static=True) ## point-to-point-helper.h: static void ns3::PointToPointHelper::EnablePcap(std::string filename, ns3::NetDeviceContainer d) [member function] @@ -215,6 +219,10 @@ def register_Ns3CsmaHelper_methods(root_module, cls): cls.add_method('SetDeviceAttribute', 'void', [param('std::string', 'n1'), param('ns3::AttributeValue&', 'v1', is_const=True)]) ## csma-helper.h: void ns3::CsmaHelper::SetChannelAttribute(std::string n1, ns3::AttributeValue const & v1) [member function] cls.add_method('SetChannelAttribute', 'void', [param('std::string', 'n1'), param('ns3::AttributeValue&', 'v1', is_const=True)]) + ## csma-helper.h: void ns3::CsmaHelper::SetDeviceParameter(std::string n1, ns3::AttributeValue const & v1) [member function] + cls.add_method('SetDeviceParameter', 'void', [param('std::string', 'n1'), param('ns3::AttributeValue&', 'v1', is_const=True)]) + ## csma-helper.h: void ns3::CsmaHelper::SetChannelParameter(std::string n1, ns3::AttributeValue const & v1) [member function] + cls.add_method('SetChannelParameter', 'void', [param('std::string', 'n1'), param('ns3::AttributeValue&', 'v1', is_const=True)]) ## csma-helper.h: static void ns3::CsmaHelper::EnablePcap(std::string filename, uint32_t nodeid, uint32_t deviceid) [member function] cls.add_method('EnablePcap', 'void', [param('std::string', 'filename'), param('uint32_t', 'nodeid'), param('uint32_t', 'deviceid')], is_static=True) ## csma-helper.h: static void ns3::CsmaHelper::EnablePcap(std::string filename, ns3::NetDeviceContainer d) [member function] diff --git a/bindings/python/ns3_module_internet_stack.py b/bindings/python/ns3_module_internet_stack.py index 2f51733a9..c430e0d34 100644 --- a/bindings/python/ns3_module_internet_stack.py +++ b/bindings/python/ns3_module_internet_stack.py @@ -116,8 +116,6 @@ def register_Ns3UdpHeader_methods(root_module, cls): cls.add_method('GetSourcePort', 'uint16_t', [], is_const=True) ## udp-header.h: uint16_t ns3::UdpHeader::GetDestinationPort() const [member function] cls.add_method('GetDestinationPort', 'uint16_t', [], is_const=True) - ## udp-header.h: void ns3::UdpHeader::SetPayloadSize(uint16_t size) [member function] - cls.add_method('SetPayloadSize', 'void', [param('uint16_t', 'size')]) ## udp-header.h: void ns3::UdpHeader::InitializeChecksum(ns3::Ipv4Address source, ns3::Ipv4Address destination, uint8_t protocol) [member function] cls.add_method('InitializeChecksum', 'void', [param('ns3::Ipv4Address', 'source'), param('ns3::Ipv4Address', 'destination'), param('uint8_t', 'protocol')]) ## udp-header.h: static ns3::TypeId ns3::UdpHeader::GetTypeId() [member function] @@ -155,8 +153,6 @@ def register_Ns3TcpHeader_methods(root_module, cls): cls.add_method('SetFlags', 'void', [param('uint8_t', 'flags')]) ## tcp-header.h: void ns3::TcpHeader::SetWindowSize(uint16_t windowSize) [member function] cls.add_method('SetWindowSize', 'void', [param('uint16_t', 'windowSize')]) - ## tcp-header.h: void ns3::TcpHeader::SetChecksum(uint16_t checksum) [member function] - cls.add_method('SetChecksum', 'void', [param('uint16_t', 'checksum')]) ## tcp-header.h: void ns3::TcpHeader::SetUrgentPointer(uint16_t urgentPointer) [member function] cls.add_method('SetUrgentPointer', 'void', [param('uint16_t', 'urgentPointer')]) ## tcp-header.h: uint16_t ns3::TcpHeader::GetSourcePort() const [member function] @@ -173,8 +169,6 @@ def register_Ns3TcpHeader_methods(root_module, cls): cls.add_method('GetFlags', 'uint8_t', [], is_const=True) ## tcp-header.h: uint16_t ns3::TcpHeader::GetWindowSize() const [member function] cls.add_method('GetWindowSize', 'uint16_t', [], is_const=True) - ## tcp-header.h: uint16_t ns3::TcpHeader::GetChecksum() const [member function] - cls.add_method('GetChecksum', 'uint16_t', [], is_const=True) ## tcp-header.h: uint16_t ns3::TcpHeader::GetUrgentPointer() const [member function] cls.add_method('GetUrgentPointer', 'uint16_t', [], is_const=True) ## tcp-header.h: void ns3::TcpHeader::InitializeChecksum(ns3::Ipv4Address source, ns3::Ipv4Address destination, uint8_t protocol) [member function] @@ -191,8 +185,6 @@ def register_Ns3TcpHeader_methods(root_module, cls): cls.add_method('Serialize', 'void', [param('ns3::Buffer::Iterator', 'start')], is_const=True, is_virtual=True) ## tcp-header.h: uint32_t ns3::TcpHeader::Deserialize(ns3::Buffer::Iterator start) [member function] cls.add_method('Deserialize', 'uint32_t', [param('ns3::Buffer::Iterator', 'start')], is_virtual=True) - ## tcp-header.h: void ns3::TcpHeader::SetPayloadSize(uint16_t size) [member function] - cls.add_method('SetPayloadSize', 'void', [param('uint16_t', 'size')]) ## tcp-header.h: bool ns3::TcpHeader::IsChecksumOk() const [member function] cls.add_method('IsChecksumOk', 'bool', [], is_const=True) return diff --git a/bindings/python/ns3_module_node.py b/bindings/python/ns3_module_node.py index 6368edc57..d01bad33a 100644 --- a/bindings/python/ns3_module_node.py +++ b/bindings/python/ns3_module_node.py @@ -96,11 +96,11 @@ def register_types(module): ## llc-snap-header.h: ns3::LlcSnapHeader [class] module.add_class('LlcSnapHeader', allow_subclassing=True, parent=root_module['ns3::Header']) ## udp-socket-factory.h: ns3::UdpSocketFactory [class] - module.add_class('UdpSocketFactory', allow_subclassing=True, parent=root_module['ns3::SocketFactory']) + module.add_class('UdpSocketFactory', parent=root_module['ns3::SocketFactory']) ## simple-net-device.h: ns3::SimpleNetDevice [class] module.add_class('SimpleNetDevice', allow_subclassing=True, parent=root_module['ns3::NetDevice']) ## tcp-socket-factory.h: ns3::TcpSocketFactory [class] - module.add_class('TcpSocketFactory', allow_subclassing=True, parent=root_module['ns3::SocketFactory']) + module.add_class('TcpSocketFactory', parent=root_module['ns3::SocketFactory']) ## packet-socket-factory.h: ns3::PacketSocketFactory [class] module.add_class('PacketSocketFactory', allow_subclassing=True, parent=root_module['ns3::SocketFactory']) @@ -1207,8 +1207,6 @@ def register_Ns3LlcSnapHeader_methods(root_module, cls): def register_Ns3UdpSocketFactory_methods(root_module, cls): ## udp-socket-factory.h: static ns3::TypeId ns3::UdpSocketFactory::GetTypeId() [member function] cls.add_method('GetTypeId', 'ns3::TypeId', [], is_static=True) - ## udp-socket-factory.h: ns3::Ptr ns3::UdpSocketFactory::CreateSocket() [member function] - cls.add_method('CreateSocket', 'ns3::Ptr< ns3::Socket >', [], is_pure_virtual=True, is_virtual=True) cls.add_constructor([]) return @@ -1272,8 +1270,6 @@ def register_Ns3SimpleNetDevice_methods(root_module, cls): def register_Ns3TcpSocketFactory_methods(root_module, cls): ## tcp-socket-factory.h: static ns3::TypeId ns3::TcpSocketFactory::GetTypeId() [member function] cls.add_method('GetTypeId', 'ns3::TypeId', [], is_static=True) - ## tcp-socket-factory.h: ns3::Ptr ns3::TcpSocketFactory::CreateSocket() [member function] - cls.add_method('CreateSocket', 'ns3::Ptr< ns3::Socket >', [], is_pure_virtual=True, is_virtual=True) cls.add_constructor([]) return From 9b8db57a001865aa4175681bed5c31b7bf51f2d8 Mon Sep 17 00:00:00 2001 From: "Gustavo J. A. M. Carneiro" Date: Fri, 11 Jul 2008 19:24:33 +0100 Subject: [PATCH 161/495] Check that the compiler accepts -Wno-error=deprecated-declarations before using it --- wscript | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/wscript b/wscript index b2a6200c6..38fceaee0 100644 --- a/wscript +++ b/wscript @@ -163,6 +163,27 @@ def set_options(opt): opt.sub_options('src') +def check_compilation_flag(conf, flag): + """ + Checks if the C++ compiler accepts a certain compilation flag or flags + flag: can be a string or a list of strings + """ + + # Check for -Wno-error=deprecated-declarations + save_CXXFLAGS = list(conf.env['CXXFLAGS']) + conf.env.append_value('CXXFLAGS', flag) + e = conf.create_test_configurator() + e.mandatory = 0 + e.code = '#include \nint main() { return 0; }\n' + e.want_message = 0 + ok = e.run() + conf.check_message_custom(flag, 'compilation flag support', + (ok and 'yes' or 'no')) + + if not ok: # if it doesn't accept, remove it again + conf.env['CXXFLAGS'] = save_CXXFLAGS + + def configure(conf): conf.check_tool('compiler_cxx') @@ -194,8 +215,12 @@ def configure(conf): if (os.path.basename(conf.env['CXX']).startswith("g++") and 'CXXFLAGS' not in os.environ): - variant_env.append_value('CXXFLAGS', ['-Werror', '-Wno-error=deprecated-declarations']) + variant_env.append_value('CXXFLAGS', '-Werror') + + check_compilation_flag(conf, '-Wno-error=deprecated-declarations') + + if 'debug' in Params.g_options.debug_level.lower(): variant_env.append_value('CXXDEFINES', 'NS3_ASSERT_ENABLE') variant_env.append_value('CXXDEFINES', 'NS3_LOG_ENABLE') From 8356645d0a508e4097d0192623d24fabb32c561c Mon Sep 17 00:00:00 2001 From: "Gustavo J. A. M. Carneiro" Date: Fri, 11 Jul 2008 19:32:22 +0100 Subject: [PATCH 162/495] Make sure we don't trigger deprecation warnings while compiling the python bindings. --- bindings/python/wscript | 1 + 1 file changed, 1 insertion(+) diff --git a/bindings/python/wscript b/bindings/python/wscript index d13ebeeba..9ad0fb18f 100644 --- a/bindings/python/wscript +++ b/bindings/python/wscript @@ -348,6 +348,7 @@ def build(bld): pymod.target = 'ns3/_ns3' pymod.name = 'ns3module' pymod.uselib_local = "ns3" + pymod.env.append_value('CXXDEFINES', ['NS_DEPRECATED=""', 'NS3_DEPRECATED_H']) # copy the __init__.py file to the build dir waf can't handle # this, it's against waf's principles to have build dir files From 90e5f8cf0eaf94eb75b39d962a91c61ed10de3bc Mon Sep 17 00:00:00 2001 From: "Gustavo J. A. M. Carneiro" Date: Sat, 12 Jul 2008 19:33:29 +0100 Subject: [PATCH 163/495] Add WAF option --pyrun, to make it easier to run Python programs. --- wscript | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/wscript b/wscript index 843a1a15e..bea93c482 100644 --- a/wscript +++ b/wscript @@ -141,6 +141,11 @@ def set_options(opt): ' It should be a shell command string containing %s inside,' ' which will be replaced by the actual program.'), type="string", default=None, dest='command_template') + opt.add_option('--pyrun', + help=('Run a python program using locally built ns3 python module;' + ' argument is the path to the python program, optionally followed' + ' by command-line options that are passed to the program.'), + type="string", default='', dest='pyrun') opt.add_option('--valgrind', help=('Change the default command template to run programs and unit tests with valgrind'), action="store_true", default=False, @@ -427,6 +432,10 @@ def shutdown(): run_program(Params.g_options.run, get_command_template()) raise SystemExit(0) + if Params.g_options.pyrun: + run_python_program(Params.g_options.pyrun) + raise SystemExit(0) + def _run_waf_check(): ## generate the trace sources list docs env = Params.g_build.env_of_name('default') @@ -561,6 +570,25 @@ def run_program(program_string, command_template=None): return retval + + +def run_python_program(program_string): + env = Params.g_build.env_of_name('default') + execvec = shlex.split(program_string) + + former_cwd = os.getcwd() + if (Params.g_options.cwd_launch): + os.chdir(Params.g_options.cwd_launch) + else: + os.chdir(Params.g_cwd_launch) + try: + retval = _run_argv([env['PYTHON']] + execvec) + finally: + os.chdir(former_cwd) + + return retval + + def check_shell(): if 'NS3_MODULE_PATH' not in os.environ: return From 1132bcbd99ab937565ba999a34cbf7ee7cd58018 Mon Sep 17 00:00:00 2001 From: "Gustavo J. A. M. Carneiro" Date: Sat, 12 Jul 2008 22:06:15 +0100 Subject: [PATCH 164/495] If GtkConfigStore support is disabled, disable the python bindings for it, or else compilation fails. --- bindings/python/ns3modulegen.py | 5 +++++ bindings/python/wscript | 4 ++++ 2 files changed, 9 insertions(+) diff --git a/bindings/python/ns3modulegen.py b/bindings/python/ns3modulegen.py index 4445d9eab..4ca929a1d 100644 --- a/bindings/python/ns3modulegen.py +++ b/bindings/python/ns3modulegen.py @@ -107,6 +107,11 @@ def main(): mod = __import__(local_module) mod.register_functions(root_module) + + # if GtkConfigStore support is disabled, disable the class wrapper + if 'DISABLE_GTK_CONFIG_STORE' in os.environ: + root_module.classes.remove(root_module['ns3::GtkConfigStore']) + root_module.generate(out, '_ns3') out.close() diff --git a/bindings/python/wscript b/bindings/python/wscript index 9ad0fb18f..d3d8f9616 100644 --- a/bindings/python/wscript +++ b/bindings/python/wscript @@ -334,6 +334,10 @@ def build(bld): bindgen.hidden_outputs.append("ns3_module_%s.cc" % module.replace('-', '_')) bindgen.prio = 50 + bindgen.os_env = dict(os.environ) + if not env['ENABLE_GTK_CONFIG_STORE']: + bindgen.os_env['DISABLE_GTK_CONFIG_STORE'] = "1" + ## we build python bindings if either we have the tools to ## generate them or if the pregenerated source file is already From 10ee9b9e01bd5f150bf6d5df5b56f05f06ed6760 Mon Sep 17 00:00:00 2001 From: "Gustavo J. A. M. Carneiro" Date: Sun, 13 Jul 2008 17:55:48 +0100 Subject: [PATCH 165/495] Python: make helper class methods using attribute optional parameters work. --- bindings/python/ns3modulegen.py | 1 + .../ns3modulegen_core_customizations.py | 25 +++++++++++++++++++ bindings/python/wscript | 2 +- 3 files changed, 27 insertions(+), 1 deletion(-) diff --git a/bindings/python/ns3modulegen.py b/bindings/python/ns3modulegen.py index 4ca929a1d..d986e9565 100644 --- a/bindings/python/ns3modulegen.py +++ b/bindings/python/ns3modulegen.py @@ -100,6 +100,7 @@ def main(): mod.register_methods(root_module) ns3modulegen_core_customizations.Object_customizations(root_module) + ns3modulegen_core_customizations.Attribute_customizations(root_module) register_functions(root_module) diff --git a/bindings/python/ns3modulegen_core_customizations.py b/bindings/python/ns3modulegen_core_customizations.py index 95721c5f4..50e6dc849 100644 --- a/bindings/python/ns3modulegen_core_customizations.py +++ b/bindings/python/ns3modulegen_core_customizations.py @@ -5,6 +5,7 @@ from pybindgen import (ReturnValue, Parameter) from pybindgen.cppmethod import CustomCppMethodWrapper, CustomCppConstructorWrapper from pybindgen.typehandlers.codesink import MemoryCodeSink from pybindgen.typehandlers import ctypeparser +from pybindgen import cppclass import warnings from pybindgen.typehandlers.base import CodeGenerationError @@ -493,3 +494,27 @@ int KwargsToAttributeList(PyObject *kwargs, ns3::TypeId tid, ns3::AttributeList return 0; } ''') + + +def Attribute_customizations(module): + # Fix up for the "const AttributeValue &v = EmptyAttribute()" + # case, as used extensively by helper classes. + + # Here's why we need to do this: pybindgen.gccxmlscanner, when + # scanning parameter default values, is only provided with the + # value as a simple C expression string. (py)gccxml does not + # report the type of the default value. + + # As a workaround, here we iterate over all parameters of all + # methods of all classes and tell pybindgen what is the type of + # the default value for attributes. + + for cls in module.classes: + for meth in cls.get_all_methods(): + for param in meth.parameters: + if isinstance(param, cppclass.CppClassRefParameter): + if param.cpp_class.name == 'AttributeValue' \ + and param.default_value is not None \ + and param.default_value_type is None: + param.default_value_type = 'ns3::EmptyAttributeValue' + diff --git a/bindings/python/wscript b/bindings/python/wscript index d3d8f9616..274620a5b 100644 --- a/bindings/python/wscript +++ b/bindings/python/wscript @@ -21,7 +21,7 @@ else: os.environ['PYTHONPATH'] = LOCAL_PYBINDGEN_PATH ## https://launchpad.net/pybindgen/ -REQUIRED_PYBINDGEN_VERSION = (0, 8, 0, 479) +REQUIRED_PYBINDGEN_VERSION = (0, 8, 0, 492) REQUIRED_PYGCCXML_VERSION = (0, 9, 5) From 2aff99d749d1432f5d97e933df080a3703ae7252 Mon Sep 17 00:00:00 2001 From: "Gustavo J. A. M. Carneiro" Date: Sun, 13 Jul 2008 18:08:48 +0100 Subject: [PATCH 166/495] Add mixed-wireless example ported to Python. --- examples/mixed-wireless.py | 341 +++++++++++++++++++++++++++++++++++++ 1 file changed, 341 insertions(+) create mode 100644 examples/mixed-wireless.py diff --git a/examples/mixed-wireless.py b/examples/mixed-wireless.py new file mode 100644 index 000000000..8e232ebdc --- /dev/null +++ b/examples/mixed-wireless.py @@ -0,0 +1,341 @@ +# /* +# * 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 +# * +# */ + +# +# This ns-3 example demonstrates the use of helper functions to ease +# the construction of simulation scenarios. +# +# The simulation topology consists of a mixed wired and wireless +# scenario in which a hierarchical mobility model is used. +# +# The simulation layout consists of N backbone routers interconnected +# by an ad hoc wifi network. +# Each backbone router also has a local 802.11 network and is connected +# to a local LAN. An additional set of(K-1) nodes are connected to +# this backbone. Finally, a local LAN is connected to each router +# on the backbone, with L-1 additional hosts. +# +# The nodes are populated with TCP/IP stacks, and OLSR unicast routing +# on the backbone. An example UDP transfer is shown. The simulator +# be configured to output tcpdumps or traces from different nodes. +# +# +# +--------------------------------------------------------+ +# | | +# | 802.11 ad hoc, ns-2 mobility | +# | | +# +--------------------------------------------------------+ +# | o o o(N backbone routers) | +# +--------+ +--------+ +# wired LAN | mobile | wired LAN | mobile | +# -----------| router | -----------| router | +# --------- --------- +# | | +# +----------------+ +----------------+ +# | 802.11 | | 802.11 | +# | net | | net | +# | K-1 hosts | | K-1 hosts | +# +----------------+ +----------------+ +# + +import ns3 + +# # +# # This function will be used below as a trace sink +# # +# static void +# CourseChangeCallback(std.string path, Ptr model) +# { +# Vector position = model.GetPosition(); +# std.cout << "CourseChange " << path << " x=" << position.x << ", y=" << position.y << ", z=" << position.z << std.endl; +# } + +def main(argv): + # + # First, we declare and initialize a few local variables that control some + # simulation parameters. + # + backboneNodes = 10 + infraNodes = 5 + lanNodes = 5 + stopTime = 10 + + # + # Simulation defaults are typically set next, before command line + # arguments are parsed. + # + ns3.Config.SetDefault("ns3::OnOffApplication::PacketSize", ns3.StringValue("210")) + ns3.Config.SetDefault("ns3::OnOffApplication::DataRate", ns3.StringValue("448kb/s")) + + # + # For convenience, we add the local variables to the command line argument + # system so that they can be overridden with flags such as + # "--backboneNodes=20" + # + cmd = ns3.CommandLine() + #cmd.AddValue("backboneNodes", "number of backbone nodes", backboneNodes) + #cmd.AddValue("infraNodes", "number of leaf nodes", infraNodes) + #cmd.AddValue("lanNodes", "number of LAN nodes", lanNodes) + #cmd.AddValue("stopTime", "simulation stop time(seconds)", stopTime) + + # + # The system global variables and the local values added to the argument + # system can be overridden by command line arguments by using this call. + # + cmd.Parse(argv) + + # The metadata system(off by default) is used by ascii tracing below + ns3.Packet.EnableMetadata() + + # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # / + # # + # Construct the backbone # + # # + # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # / + + # + # Create a container to manage the nodes of the adhoc(backbone) network. + # Later we'll create the rest of the nodes we'll need. + # + backbone = ns3.NodeContainer() + backbone.Create(backboneNodes) + # + # Create the backbone wifi net devices and install them into the nodes in + # our container + # + wifi = ns3.WifiHelper() + wifi.SetMac("ns3::AdhocWifiMac") + wifi.SetPhy("ns3::WifiPhy") + backboneDevices = wifi.Install(backbone) + # + # Add the IPv4 protocol stack to the nodes in our container + # + internet = ns3.InternetStackHelper() + internet.Install(backbone) + # + # Assign IPv4 addresses to the device drivers(actually to the associated + # IPv4 interfaces) we just created. + # + ipAddrs = ns3.Ipv4AddressHelper() + ipAddrs.SetBase(ns3.Ipv4Address("192.168.0.0"), ns3.Ipv4Mask("255.255.255.0")) + ipAddrs.Assign(backboneDevices) + + # + # The ad-hoc network nodes need a mobility model so we aggregate one to + # each of the nodes we just finished building. + # + mobility = ns3.MobilityHelper() + positionAlloc = ns3.ListPositionAllocator() + x = 0.0 + for i in range(backboneNodes): + positionAlloc.Add(ns3.Vector(x, 0.0, 0.0)) + x += 5.0 + mobility.SetPositionAllocator(positionAlloc) + mobility.SetMobilityModel("ns3::RandomDirection2dMobilityModel", + "Bounds", ns3.RectangleValue(ns3.Rectangle(0, 1000, 0, 1000)), + "Speed", ns3.RandomVariableValue(ns3.ConstantVariable(2000)), + "Pause", ns3.RandomVariableValue(ns3.ConstantVariable(0.2))) + mobility.Install(backbone) + + # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # / + # # + # Construct the LANs # + # # + # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # / + + # Reset the address base-- all of the CSMA networks will be in + # the "172.16 address space + ipAddrs.SetBase(ns3.Ipv4Address("172.16.0.0"), ns3.Ipv4Mask("255.255.255.0")) + + for i in range(backboneNodes): + print "Configuring local area network for backbone node ", i + # + # Create a container to manage the nodes of the LAN. We need + # two containers here; one with all of the new nodes, and one + # with all of the nodes including new and existing nodes + # + newLanNodes = ns3.NodeContainer() + newLanNodes.Create(lanNodes - 1) + # Now, create the container with all nodes on this link + lan = ns3.NodeContainer(ns3.NodeContainer(backbone.Get(i)), newLanNodes) + # + # Create the CSMA net devices and install them into the nodes in our + # collection. + # + csma = ns3.CsmaHelper() + csma.SetChannelAttribute("DataRate", ns3.DataRateValue(ns3.DataRate(5000000))) + csma.SetChannelAttribute("Delay", ns3.TimeValue(ns3.MilliSeconds(2))) + lanDevices = csma.Install(lan) + # + # Add the IPv4 protocol stack to the new LAN nodes + # + internet.Install(newLanNodes) + # + # Assign IPv4 addresses to the device drivers(actually to the + # associated IPv4 interfaces) we just created. + # + ipAddrs.Assign(lanDevices) + # + # Assign a new network prefix for the next LAN, according to the + # network mask initialized above + # + ipAddrs.NewNetwork() + + # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # / + # # + # Construct the mobile networks # + # # + # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # / + + # Reset the address base-- all of the 802.11 networks will be in + # the "10.0" address space + ipAddrs.SetBase(ns3.Ipv4Address("10.0.0.0"), ns3.Ipv4Mask("255.255.255.0")) + + for i in range(backboneNodes): + print "Configuring wireless network for backbone node ", i + # + # Create a container to manage the nodes of the LAN. We need + # two containers here; one with all of the new nodes, and one + # with all of the nodes including new and existing nodes + # + newInfraNodes = ns3.NodeContainer() + newInfraNodes.Create(infraNodes - 1) + # Now, create the container with all nodes on this link + infra = ns3.NodeContainer(ns3.NodeContainer(backbone.Get(i)), newInfraNodes) + # + # Create another ad hoc network and devices + # + wifiInfra = ns3.WifiHelper() + wifiInfra.SetMac("ns3::AdhocWifiMac") + wifiInfra.SetPhy("ns3::WifiPhy") + infraDevices = wifiInfra.Install(infra) + + # Add the IPv4 protocol stack to the nodes in our container + # + internet.Install(newInfraNodes) + # + # Assign IPv4 addresses to the device drivers(actually to the associated + # IPv4 interfaces) we just created. + # + ipAddrs.Assign(infraDevices) + # + # Assign a new network prefix for each mobile network, according to + # the network mask initialized above + # + ipAddrs.NewNetwork() + # + # The new wireless nodes need a mobility model so we aggregate one + # to each of the nodes we just finished building. + # + subnetAlloc = ns3.ListPositionAllocator() + for j in range(infra.GetN()): + subnetAlloc.Add(ns3.Vector(0.0, j, 0.0)) + + mobility.PushReferenceMobilityModel(backbone.Get(i)) + mobility.SetPositionAllocator(subnetAlloc) + mobility.SetMobilityModel("ns3::RandomDirection2dMobilityModel", + "Bounds", ns3.RectangleValue(ns3.Rectangle(-25, 25, -25, 25)), + "Speed", ns3.RandomVariableValue(ns3.ConstantVariable(30)), + "Pause", ns3.RandomVariableValue(ns3.ConstantVariable(0.4))) + mobility.Install(infra) + + # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # / + # # + # Routing configuration # + # # + # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # / + + print "Enabling OLSR routing on all backbone nodes" + olsr = ns3.OlsrHelper() + olsr.Install(backbone) + + # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # / + # # + # Application configuration # + # # + # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # / + + # Create the OnOff application to send UDP datagrams of size + # 210 bytes at a rate of 448 Kb/s, between two nodes + print "Create Applications." + port = 9 # Discard port(RFC 863) + + # Let's make sure that the user does not define too few LAN nodes + # to make this example work. We need lanNodes >= 5 + assert (lanNodes >= 5) + appSource = ns3.NodeList.GetNode(11) + appSink = ns3.NodeList.GetNode(13) + remoteAddr = ns3.Ipv4Address("172.16.0.5") + + onoff = ns3.OnOffHelper("ns3::UdpSocketFactory", + ns3.Address(ns3.InetSocketAddress(remoteAddr, port))) + onoff.SetAttribute("OnTime", ns3.RandomVariableValue(ns3.ConstantVariable(1))) + onoff.SetAttribute("OffTime", ns3.RandomVariableValue(ns3.ConstantVariable(0))) + apps = onoff.Install(ns3.NodeContainer(appSource)) + apps.Start(ns3.Seconds(3.0)) + apps.Stop(ns3.Seconds(20.0)) + + # Create a packet sink to receive these packets + sink = ns3.PacketSinkHelper("ns3::UdpSocketFactory", + ns3.InetSocketAddress(ns3.Ipv4Address.GetAny(), port)) + apps = sink.Install(ns3.NodeContainer(appSink)) + apps.Start(ns3.Seconds(3.0)) + + # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # / + # # + # Tracing configuration # + # # + # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # / + + print "Configure Tracing." + # + # Let's set up some ns-2-like ascii traces, using another helper class + # + #std.ofstream ascii + #ascii.open("mixed-wireless.tr") + #WifiHelper.EnableAsciiAll(ascii) + #CsmaHelper.EnableAsciiAll(ascii) + print "(tracing not done for Python)" + # Look at nodes 11, 13 only + # WifiHelper.EnableAscii(ascii, 11, 0); + # WifiHelper.EnableAscii(ascii, 13, 0); + + # Let's do a pcap trace on the backbone devices + ns3.WifiHelper.EnablePcap("mixed-wireless", backboneDevices) + # Let's additionally trace the application Sink, ifIndex 0 + ns3.CsmaHelper.EnablePcap("mixed-wireless", appSink.GetId(), 0) + +# #ifdef ENABLE_FOR_TRACING_EXAMPLE +# Config.Connect("/NodeList/*/$MobilityModel/CourseChange", +# MakeCallback(&CourseChangeCallback)) +# #endif + + + # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # + # # + # Run simulation # + # # + # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # + + print "Run Simulation." + ns3.Simulator.Stop(ns3.Seconds(stopTime)) + ns3.Simulator.Run() + ns3.Simulator.Destroy() + + +if __name__ == '__main__': + import sys + main(sys.argv) From 69dc042ec71eba930276a7bfda218fedbbb0193f Mon Sep 17 00:00:00 2001 From: "Gustavo J. A. M. Carneiro" Date: Mon, 14 Jul 2008 11:25:10 +0100 Subject: [PATCH 167/495] Make Python bindings depend only on NS-3 modules that have been API-scanned, not all modules. --- bindings/python/wscript | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/bindings/python/wscript b/bindings/python/wscript index 274620a5b..0248bb347 100644 --- a/bindings/python/wscript +++ b/bindings/python/wscript @@ -327,11 +327,24 @@ def build(bld): bindgen.hidden_inputs = ['everything.h', 'ns3modulegen_generated.py', 'ns3modulegen_core_customizations.py'] - for module in get_modules_and_headers().iterkeys(): - bindgen.hidden_inputs.append("ns3_module_%s.py" % module.replace('-', '_')) + + ## Get a list of scanned modules; the set of scanned modules + ## may be smaller than the set of all modules, in case a new + ## ns3 module is being developed which wasn't scanned yet. + scanned_modules = [] + for filename in os.listdir(bindgen.path.abspath()): + m = re.match(r"^ns3_module_(.+)\.py$", filename) + if m is None: + continue + scanned_modules.append(m.group(1)) + + for module in scanned_modules: + bindgen.hidden_inputs.append("ns3_module_%s.py" % module) + bindgen.hidden_outputs = ['ns3module.h'] - for module in get_modules_and_headers().iterkeys(): - bindgen.hidden_outputs.append("ns3_module_%s.cc" % module.replace('-', '_')) + for module in scanned_modules: + bindgen.hidden_outputs.append("ns3_module_%s.cc" % module) + bindgen.prio = 50 bindgen.os_env = dict(os.environ) From 6afc4f8d7fb9920f377b72af9074493116a34a53 Mon Sep 17 00:00:00 2001 From: "Gustavo J. A. M. Carneiro" Date: Mon, 14 Jul 2008 11:29:13 +0100 Subject: [PATCH 168/495] Again, make Python depend only on scanned modules (last fix was incomplete). --- bindings/python/wscript | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/bindings/python/wscript b/bindings/python/wscript index 0248bb347..bac616509 100644 --- a/bindings/python/wscript +++ b/bindings/python/wscript @@ -313,6 +313,16 @@ def build(bld): print "Rescanning the python bindings done." raise SystemExit + ## Get a list of scanned modules; the set of scanned modules + ## may be smaller than the set of all modules, in case a new + ## ns3 module is being developed which wasn't scanned yet. + scanned_modules = [] + for filename in os.listdir(bindgen.path.abspath()): + m = re.match(r"^ns3_module_(.+)\.py$", filename) + if m is None: + continue + scanned_modules.append(m.group(1)) + if env['ENABLE_PYTHON_BINDINGS']: bindgen = bld.create_obj('command-output') bindgen.name = 'pybindgen' @@ -328,16 +338,6 @@ def build(bld): 'ns3modulegen_generated.py', 'ns3modulegen_core_customizations.py'] - ## Get a list of scanned modules; the set of scanned modules - ## may be smaller than the set of all modules, in case a new - ## ns3 module is being developed which wasn't scanned yet. - scanned_modules = [] - for filename in os.listdir(bindgen.path.abspath()): - m = re.match(r"^ns3_module_(.+)\.py$", filename) - if m is None: - continue - scanned_modules.append(m.group(1)) - for module in scanned_modules: bindgen.hidden_inputs.append("ns3_module_%s.py" % module) @@ -360,8 +360,8 @@ def build(bld): pymod = bld.create_obj('cpp', 'shlib', 'pyext') pymod.source = ['ns3module.cc', 'ns3module_helpers.cc'] pymod.includes = '.' - for module in get_modules_and_headers().iterkeys(): - pymod.source.append("ns3_module_%s.cc" % module.replace('-', '_')) + for module in scanned_modules + pymod.source.append("ns3_module_%s.cc" % module) pymod.target = 'ns3/_ns3' pymod.name = 'ns3module' pymod.uselib_local = "ns3" From cfa12b46c4a8701194fcb62c722652e2dfecb78d Mon Sep 17 00:00:00 2001 From: "Gustavo J. A. M. Carneiro" Date: Mon, 14 Jul 2008 11:35:58 +0100 Subject: [PATCH 169/495] Again, make Python depend only on scanned modules (last fix was incomplete). --- bindings/python/wscript | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/bindings/python/wscript b/bindings/python/wscript index 0248bb347..a755cf28c 100644 --- a/bindings/python/wscript +++ b/bindings/python/wscript @@ -313,6 +313,16 @@ def build(bld): print "Rescanning the python bindings done." raise SystemExit + ## Get a list of scanned modules; the set of scanned modules + ## may be smaller than the set of all modules, in case a new + ## ns3 module is being developed which wasn't scanned yet. + scanned_modules = [] + for filename in os.listdir(bld.m_curdirnode.abspath()): + m = re.match(r"^ns3_module_(.+)\.py$", filename) + if m is None: + continue + scanned_modules.append(m.group(1)) + if env['ENABLE_PYTHON_BINDINGS']: bindgen = bld.create_obj('command-output') bindgen.name = 'pybindgen' @@ -328,16 +338,6 @@ def build(bld): 'ns3modulegen_generated.py', 'ns3modulegen_core_customizations.py'] - ## Get a list of scanned modules; the set of scanned modules - ## may be smaller than the set of all modules, in case a new - ## ns3 module is being developed which wasn't scanned yet. - scanned_modules = [] - for filename in os.listdir(bindgen.path.abspath()): - m = re.match(r"^ns3_module_(.+)\.py$", filename) - if m is None: - continue - scanned_modules.append(m.group(1)) - for module in scanned_modules: bindgen.hidden_inputs.append("ns3_module_%s.py" % module) @@ -360,8 +360,8 @@ def build(bld): pymod = bld.create_obj('cpp', 'shlib', 'pyext') pymod.source = ['ns3module.cc', 'ns3module_helpers.cc'] pymod.includes = '.' - for module in get_modules_and_headers().iterkeys(): - pymod.source.append("ns3_module_%s.cc" % module.replace('-', '_')) + for module in scanned_modules: + pymod.source.append("ns3_module_%s.cc" % module) pymod.target = 'ns3/_ns3' pymod.name = 'ns3module' pymod.uselib_local = "ns3" From 65d4f0972c41d4004c8054d08e48952f0ed9635a Mon Sep 17 00:00:00 2001 From: "Gustavo J. A. M. Carneiro" Date: Mon, 14 Jul 2008 11:42:49 +0100 Subject: [PATCH 170/495] Rescan API --- bindings/python/callbacks_list.py | 4 +- bindings/python/ns3_module_bridge.py | 153 +++++++++++++++++++ bindings/python/ns3_module_common.py | 16 +- bindings/python/ns3_module_contrib.py | 2 +- bindings/python/ns3_module_core.py | 104 ++++++------- bindings/python/ns3_module_csma.py | 18 ++- bindings/python/ns3_module_global_routing.py | 2 +- bindings/python/ns3_module_internet_stack.py | 14 +- bindings/python/ns3_module_mobility.py | 28 ++-- bindings/python/ns3_module_node.py | 148 +++++++++--------- bindings/python/ns3_module_olsr.py | 6 +- bindings/python/ns3_module_onoff.py | 2 +- bindings/python/ns3_module_packet_sink.py | 2 +- bindings/python/ns3_module_point_to_point.py | 10 +- bindings/python/ns3_module_simulator.py | 10 +- bindings/python/ns3_module_udp_echo.py | 4 +- bindings/python/ns3_module_wifi.py | 72 ++++----- bindings/python/ns3modulegen_generated.py | 34 +++++ 18 files changed, 416 insertions(+), 213 deletions(-) create mode 100644 bindings/python/ns3_module_bridge.py diff --git a/bindings/python/callbacks_list.py b/bindings/python/callbacks_list.py index 718c72288..2ea5db414 100644 --- a/bindings/python/callbacks_list.py +++ b/bindings/python/callbacks_list.py @@ -1,12 +1,12 @@ callback_classes = [ ['void', 'ns3::empty', 'ns3::empty', 'ns3::empty', 'ns3::empty', 'ns3::empty', 'ns3::empty'], - ['bool', 'ns3::Ptr', 'ns3::Ptr', 'unsigned short', 'ns3::Address const&', 'ns3::empty', 'ns3::empty'], ['void', 'ns3::Ptr', 'ns3::empty', 'ns3::empty', 'ns3::empty', 'ns3::empty', 'ns3::empty'], ['void', 'ns3::Ptr', 'unsigned int', 'ns3::empty', 'ns3::empty', 'ns3::empty', 'ns3::empty'], ['void', 'ns3::Ptr', 'ns3::Address const&', 'ns3::empty', 'ns3::empty', 'ns3::empty', 'ns3::empty'], ['bool', 'ns3::Ptr', 'ns3::Address const&', 'ns3::empty', 'ns3::empty', 'ns3::empty', 'ns3::empty'], ['void', 'ns3::Ptr', 'ns3::Mac48Address const&', 'ns3::empty', 'ns3::empty', 'ns3::empty', 'ns3::empty'], - ['void', 'ns3::Ptr', 'ns3::Ptr', 'unsigned short', 'ns3::Address const&', 'ns3::empty', 'ns3::empty'], + ['bool', 'ns3::Ptr', 'ns3::Ptr', 'unsigned short', 'ns3::Address const&', 'ns3::Address const&', 'ns3::NetDevice::PacketType'], + ['void', 'ns3::Ptr', 'ns3::Ptr', 'unsigned short', 'ns3::Address const&', 'ns3::Address const&', 'ns3::NetDevice::PacketType'], ['void', 'ns3::Ptr', 'double', 'ns3::empty', 'ns3::empty', 'ns3::empty', 'ns3::empty'], ['void', 'ns3::Ptr', 'double', 'ns3::WifiMode', 'ns3::WifiPreamble', 'ns3::empty', 'ns3::empty'], ] diff --git a/bindings/python/ns3_module_bridge.py b/bindings/python/ns3_module_bridge.py new file mode 100644 index 000000000..b15f97df0 --- /dev/null +++ b/bindings/python/ns3_module_bridge.py @@ -0,0 +1,153 @@ +from pybindgen import Module, FileCodeSink, write_preamble, param, retval + +def register_types(module): + root_module = module.get_root() + + ## bridge-net-device.h: ns3::BridgeNetDevice [class] + module.add_class('BridgeNetDevice', parent=root_module['ns3::NetDevice']) + ## bridge-channel.h: ns3::BridgeChannel [class] + module.add_class('BridgeChannel', parent=root_module['ns3::Channel']) + + ## Register a nested module for the namespace internal + + nested_module = module.add_cpp_namespace('internal') + register_types_ns3_internal(nested_module) + + + ## Register a nested module for the namespace TimeStepPrecision + + nested_module = module.add_cpp_namespace('TimeStepPrecision') + register_types_ns3_TimeStepPrecision(nested_module) + + + ## Register a nested module for the namespace Config + + nested_module = module.add_cpp_namespace('Config') + register_types_ns3_Config(nested_module) + + + ## Register a nested module for the namespace olsr + + nested_module = module.add_cpp_namespace('olsr') + register_types_ns3_olsr(nested_module) + + +def register_types_ns3_internal(module): + root_module = module.get_root() + + +def register_types_ns3_TimeStepPrecision(module): + root_module = module.get_root() + + +def register_types_ns3_Config(module): + root_module = module.get_root() + + +def register_types_ns3_olsr(module): + root_module = module.get_root() + + +def register_methods(root_module): + register_Ns3BridgeNetDevice_methods(root_module, root_module['ns3::BridgeNetDevice']) + register_Ns3BridgeChannel_methods(root_module, root_module['ns3::BridgeChannel']) + return + +def register_Ns3BridgeNetDevice_methods(root_module, cls): + ## bridge-net-device.h: static ns3::TypeId ns3::BridgeNetDevice::GetTypeId() [member function] + cls.add_method('GetTypeId', 'ns3::TypeId', [], is_static=True) + ## bridge-net-device.h: ns3::BridgeNetDevice::BridgeNetDevice() [constructor] + cls.add_constructor([], visibility='public') + ## bridge-net-device.h: void ns3::BridgeNetDevice::AddBridgePort(ns3::Ptr bridgePort) [member function] + cls.add_method('AddBridgePort', 'void', [param('ns3::Ptr< ns3::NetDevice >', 'bridgePort')]) + ## bridge-net-device.h: void ns3::BridgeNetDevice::SetName(std::string const name) [member function] + cls.add_method('SetName', 'void', [param('std::string', 'name', is_const=True)], is_virtual=True) + ## bridge-net-device.h: std::string ns3::BridgeNetDevice::GetName() const [member function] + cls.add_method('GetName', 'std::string', [], is_const=True, is_virtual=True) + ## bridge-net-device.h: void ns3::BridgeNetDevice::SetIfIndex(uint32_t const index) [member function] + cls.add_method('SetIfIndex', 'void', [param('uint32_t', 'index', is_const=True)], is_virtual=True) + ## bridge-net-device.h: uint32_t ns3::BridgeNetDevice::GetIfIndex() const [member function] + cls.add_method('GetIfIndex', 'uint32_t', [], is_const=True, is_virtual=True) + ## bridge-net-device.h: ns3::Ptr ns3::BridgeNetDevice::GetChannel() const [member function] + cls.add_method('GetChannel', 'ns3::Ptr< ns3::Channel >', [], is_const=True, is_virtual=True) + ## bridge-net-device.h: ns3::Address ns3::BridgeNetDevice::GetAddress() const [member function] + cls.add_method('GetAddress', 'ns3::Address', [], is_const=True, is_virtual=True) + ## bridge-net-device.h: bool ns3::BridgeNetDevice::SetMtu(uint16_t const mtu) [member function] + cls.add_method('SetMtu', 'bool', [param('uint16_t', 'mtu', is_const=True)], is_virtual=True) + ## bridge-net-device.h: uint16_t ns3::BridgeNetDevice::GetMtu() const [member function] + cls.add_method('GetMtu', 'uint16_t', [], is_const=True, is_virtual=True) + ## bridge-net-device.h: bool ns3::BridgeNetDevice::IsLinkUp() const [member function] + cls.add_method('IsLinkUp', 'bool', [], is_const=True, is_virtual=True) + ## bridge-net-device.h: void ns3::BridgeNetDevice::SetLinkChangeCallback(ns3::Callback callback) [member function] + cls.add_method('SetLinkChangeCallback', 'void', [param('ns3::Callback< void, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty >', 'callback')], is_virtual=True) + ## bridge-net-device.h: bool ns3::BridgeNetDevice::IsBroadcast() const [member function] + cls.add_method('IsBroadcast', 'bool', [], is_const=True, is_virtual=True) + ## bridge-net-device.h: ns3::Address ns3::BridgeNetDevice::GetBroadcast() const [member function] + cls.add_method('GetBroadcast', 'ns3::Address', [], is_const=True, is_virtual=True) + ## bridge-net-device.h: bool ns3::BridgeNetDevice::IsMulticast() const [member function] + cls.add_method('IsMulticast', 'bool', [], is_const=True, is_virtual=True) + ## bridge-net-device.h: ns3::Address ns3::BridgeNetDevice::GetMulticast() const [member function] + cls.add_method('GetMulticast', 'ns3::Address', [], is_const=True, is_virtual=True) + ## bridge-net-device.h: ns3::Address ns3::BridgeNetDevice::MakeMulticastAddress(ns3::Ipv4Address multicastGroup) const [member function] + cls.add_method('MakeMulticastAddress', 'ns3::Address', [param('ns3::Ipv4Address', 'multicastGroup')], is_const=True, is_virtual=True) + ## bridge-net-device.h: bool ns3::BridgeNetDevice::IsPointToPoint() const [member function] + cls.add_method('IsPointToPoint', 'bool', [], is_const=True, is_virtual=True) + ## bridge-net-device.h: bool ns3::BridgeNetDevice::Send(ns3::Ptr packet, ns3::Address const & dest, uint16_t protocolNumber) [member function] + cls.add_method('Send', 'bool', [param('ns3::Ptr< ns3::Packet >', 'packet'), param('ns3::Address&', 'dest', is_const=True), param('uint16_t', 'protocolNumber')], is_virtual=True) + ## bridge-net-device.h: bool ns3::BridgeNetDevice::SendFrom(ns3::Ptr packet, ns3::Address const & source, ns3::Address const & dest, uint16_t protocolNumber) [member function] + cls.add_method('SendFrom', 'bool', [param('ns3::Ptr< ns3::Packet >', 'packet'), param('ns3::Address&', 'source', is_const=True), param('ns3::Address&', 'dest', is_const=True), param('uint16_t', 'protocolNumber')], is_virtual=True) + ## bridge-net-device.h: ns3::Ptr ns3::BridgeNetDevice::GetNode() const [member function] + cls.add_method('GetNode', 'ns3::Ptr< ns3::Node >', [], is_const=True, is_virtual=True) + ## bridge-net-device.h: void ns3::BridgeNetDevice::SetNode(ns3::Ptr node) [member function] + cls.add_method('SetNode', 'void', [param('ns3::Ptr< ns3::Node >', 'node')], is_virtual=True) + ## bridge-net-device.h: bool ns3::BridgeNetDevice::NeedsArp() const [member function] + cls.add_method('NeedsArp', 'bool', [], is_const=True, is_virtual=True) + ## bridge-net-device.h: void ns3::BridgeNetDevice::SetReceiveCallback(ns3::Callback, ns3::Ptr, unsigned short, ns3::Address const&, ns3::Address const&, ns3::NetDevice::PacketType> cb) [member function] + cls.add_method('SetReceiveCallback', 'void', [param('ns3::Callback< bool, ns3::Ptr< ns3::NetDevice >, ns3::Ptr< ns3::Packet >, unsigned short, ns3::Address const&, ns3::Address const&, ns3::NetDevice::PacketType >', 'cb')], is_virtual=True) + ## bridge-net-device.h: void ns3::BridgeNetDevice::DoDispose() [member function] + cls.add_method('DoDispose', 'void', [], visibility='protected', is_virtual=True) + ## bridge-net-device.h: void ns3::BridgeNetDevice::ReceiveFromDevice(ns3::Ptr device, ns3::Ptr packet, uint16_t protocol, ns3::Address const & source, ns3::Address const & destination, ns3::NetDevice::PacketType packetType) [member function] + cls.add_method('ReceiveFromDevice', 'void', [param('ns3::Ptr< ns3::NetDevice >', 'device'), param('ns3::Ptr< ns3::Packet >', 'packet'), param('uint16_t', 'protocol'), param('ns3::Address&', 'source', is_const=True), param('ns3::Address&', 'destination', is_const=True), param('ns3::NetDevice::PacketType', 'packetType')], visibility='protected') + ## bridge-net-device.h: void ns3::BridgeNetDevice::ForwardUnicast(ns3::Ptr incomingPort, ns3::Ptr packet, uint16_t protocol, ns3::Mac48Address src, ns3::Mac48Address dst) [member function] + cls.add_method('ForwardUnicast', 'void', [param('ns3::Ptr< ns3::NetDevice >', 'incomingPort'), param('ns3::Ptr< ns3::Packet >', 'packet'), param('uint16_t', 'protocol'), param('ns3::Mac48Address', 'src'), param('ns3::Mac48Address', 'dst')], visibility='protected') + ## bridge-net-device.h: void ns3::BridgeNetDevice::ForwardBroadcast(ns3::Ptr incomingPort, ns3::Ptr packet, uint16_t protocol, ns3::Mac48Address src, ns3::Mac48Address dst) [member function] + cls.add_method('ForwardBroadcast', 'void', [param('ns3::Ptr< ns3::NetDevice >', 'incomingPort'), param('ns3::Ptr< ns3::Packet >', 'packet'), param('uint16_t', 'protocol'), param('ns3::Mac48Address', 'src'), param('ns3::Mac48Address', 'dst')], visibility='protected') + ## bridge-net-device.h: void ns3::BridgeNetDevice::Learn(ns3::Mac48Address source, ns3::Ptr port) [member function] + cls.add_method('Learn', 'void', [param('ns3::Mac48Address', 'source'), param('ns3::Ptr< ns3::NetDevice >', 'port')], visibility='protected') + ## bridge-net-device.h: ns3::Ptr ns3::BridgeNetDevice::GetLearnedState(ns3::Mac48Address source) [member function] + cls.add_method('GetLearnedState', 'ns3::Ptr< ns3::NetDevice >', [param('ns3::Mac48Address', 'source')], visibility='protected') + return + +def register_Ns3BridgeChannel_methods(root_module, cls): + ## bridge-channel.h: static ns3::TypeId ns3::BridgeChannel::GetTypeId() [member function] + cls.add_method('GetTypeId', 'ns3::TypeId', [], is_static=True) + ## bridge-channel.h: ns3::BridgeChannel::BridgeChannel() [constructor] + cls.add_constructor([], visibility='public') + ## bridge-channel.h: void ns3::BridgeChannel::AddChannel(ns3::Ptr bridgedChannel) [member function] + cls.add_method('AddChannel', 'void', [param('ns3::Ptr< ns3::Channel >', 'bridgedChannel')]) + ## bridge-channel.h: uint32_t ns3::BridgeChannel::GetNDevices() const [member function] + cls.add_method('GetNDevices', 'uint32_t', [], is_const=True, is_virtual=True) + ## bridge-channel.h: ns3::Ptr ns3::BridgeChannel::GetDevice(uint32_t i) const [member function] + cls.add_method('GetDevice', 'ns3::Ptr< ns3::NetDevice >', [param('uint32_t', 'i')], is_const=True, is_virtual=True) + return + +def register_functions(root_module): + module = root_module + register_functions_ns3_internal(module.get_submodule('internal'), root_module) + register_functions_ns3_TimeStepPrecision(module.get_submodule('TimeStepPrecision'), root_module) + register_functions_ns3_Config(module.get_submodule('Config'), root_module) + register_functions_ns3_olsr(module.get_submodule('olsr'), root_module) + return + +def register_functions_ns3_internal(module, root_module): + return + +def register_functions_ns3_TimeStepPrecision(module, root_module): + return + +def register_functions_ns3_Config(module, root_module): + return + +def register_functions_ns3_olsr(module, root_module): + return + diff --git a/bindings/python/ns3_module_common.py b/bindings/python/ns3_module_common.py index 658c1fca3..ee80eda02 100644 --- a/bindings/python/ns3_module_common.py +++ b/bindings/python/ns3_module_common.py @@ -24,27 +24,27 @@ def register_types(module): ## buffer.h: ns3::Buffer::Iterator [class] module.add_class('Iterator', outer_class=root_module['ns3::Buffer']) ## chunk.h: ns3::Chunk [class] - module.add_class('Chunk', allow_subclassing=True, parent=root_module['ns3::ObjectBase']) + module.add_class('Chunk', parent=root_module['ns3::ObjectBase']) ## data-rate.h: ns3::DataRate [class] module.add_class('DataRate') ## tag.h: ns3::Tag [class] - module.add_class('Tag', allow_subclassing=True, parent=root_module['ns3::ObjectBase']) + module.add_class('Tag', parent=root_module['ns3::ObjectBase']) ## pcap-writer.h: ns3::PcapWriter [class] module.add_class('PcapWriter', parent=root_module['ns3::RefCountBase']) ## data-rate.h: ns3::DataRateChecker [class] module.add_class('DataRateChecker', parent=root_module['ns3::AttributeChecker']) ## error-model.h: ns3::ErrorModel [class] - module.add_class('ErrorModel', allow_subclassing=True, parent=root_module['ns3::Object']) + module.add_class('ErrorModel', parent=root_module['ns3::Object']) ## header.h: ns3::Header [class] - module.add_class('Header', allow_subclassing=True, parent=root_module['ns3::Chunk']) + module.add_class('Header', parent=root_module['ns3::Chunk']) ## trailer.h: ns3::Trailer [class] - module.add_class('Trailer', allow_subclassing=True, parent=root_module['ns3::Chunk']) + module.add_class('Trailer', parent=root_module['ns3::Chunk']) ## error-model.h: ns3::ListErrorModel [class] - module.add_class('ListErrorModel', allow_subclassing=True, parent=root_module['ns3::ErrorModel']) + module.add_class('ListErrorModel', parent=root_module['ns3::ErrorModel']) ## data-rate.h: ns3::DataRateValue [class] - module.add_class('DataRateValue', allow_subclassing=True, parent=root_module['ns3::AttributeValue']) + module.add_class('DataRateValue', parent=root_module['ns3::AttributeValue']) ## error-model.h: ns3::RateErrorModel [class] - module.add_class('RateErrorModel', allow_subclassing=True, parent=root_module['ns3::ErrorModel']) + module.add_class('RateErrorModel', parent=root_module['ns3::ErrorModel']) ## Register a nested module for the namespace internal diff --git a/bindings/python/ns3_module_contrib.py b/bindings/python/ns3_module_contrib.py index 852b23750..550413ff7 100644 --- a/bindings/python/ns3_module_contrib.py +++ b/bindings/python/ns3_module_contrib.py @@ -16,7 +16,7 @@ def register_types(module): ## gtk-config-store.h: ns3::GtkConfigStore [class] module.add_class('GtkConfigStore') ## config-store.h: ns3::ConfigStore [class] - module.add_class('ConfigStore', allow_subclassing=True, parent=root_module['ns3::ObjectBase']) + module.add_class('ConfigStore', parent=root_module['ns3::ObjectBase']) ## delay-jitter-estimation.h: ns3::DelayJitterEstimation [class] module.add_class('DelayJitterEstimation') diff --git a/bindings/python/ns3_module_core.py b/bindings/python/ns3_module_core.py index 6020f63c7..0ad9704e9 100644 --- a/bindings/python/ns3_module_core.py +++ b/bindings/python/ns3_module_core.py @@ -32,7 +32,7 @@ def register_types(module): ## object-factory.h: ns3::ObjectFactory [class] module.add_class('ObjectFactory') ## attribute.h: ns3::AttributeAccessor [class] - module.add_class('AttributeAccessor', allow_subclassing=True, parent=root_module['ns3::RefCountBase']) + module.add_class('AttributeAccessor', parent=root_module['ns3::RefCountBase']) ## random-variable.h: ns3::ParetoVariable [class] module.add_class('ParetoVariable', parent=root_module['ns3::RandomVariable']) ## random-variable.h: ns3::ConstantVariable [class] @@ -40,7 +40,7 @@ def register_types(module): ## random-variable.h: ns3::EmpiricalVariable [class] module.add_class('EmpiricalVariable', parent=root_module['ns3::RandomVariable']) ## enum.h: ns3::EnumChecker [class] - module.add_class('EnumChecker', allow_subclassing=True, parent=root_module['ns3::AttributeChecker']) + module.add_class('EnumChecker', parent=root_module['ns3::AttributeChecker']) ## empty.h: ns3::empty [class] module.add_class('empty') ## object-base.h: ns3::ObjectBase [class] @@ -82,7 +82,7 @@ def register_types(module): ## random-variable.h: ns3::IntEmpiricalVariable [class] module.add_class('IntEmpiricalVariable', parent=root_module['ns3::EmpiricalVariable']) ## pointer.h: ns3::PointerChecker [class] - module.add_class('PointerChecker', allow_subclassing=True, parent=root_module['ns3::AttributeChecker']) + module.add_class('PointerChecker', parent=root_module['ns3::AttributeChecker']) ## random-variable.h: ns3::WeibullVariable [class] module.add_class('WeibullVariable', parent=root_module['ns3::RandomVariable']) ## callback.h: ns3::CallbackBase [class] @@ -118,47 +118,47 @@ def register_types(module): ## random-variable.h: ns3::UniformVariable [class] module.add_class('UniformVariable', parent=root_module['ns3::RandomVariable']) ## object.h: ns3::Object [class] - module.add_class('Object', peekref_method='GetReferenceCount', parent=root_module['ns3::ObjectBase'], incref_method='Ref', decref_method='Unref', allow_subclassing=True, automatic_type_narrowing=True) + module.add_class('Object', incref_method='Ref', automatic_type_narrowing=True, decref_method='Unref', parent=root_module['ns3::ObjectBase'], peekref_method='GetReferenceCount') ## object.h: ns3::Object::AggregateIterator [class] module.add_class('AggregateIterator', outer_class=root_module['ns3::Object']) ## random-variable.h: ns3::SequentialVariable [class] module.add_class('SequentialVariable', parent=root_module['ns3::RandomVariable']) ## object-vector.h: ns3::ObjectVectorChecker [class] - module.add_class('ObjectVectorChecker', allow_subclassing=True, parent=root_module['ns3::AttributeChecker']) + module.add_class('ObjectVectorChecker', parent=root_module['ns3::AttributeChecker']) ## string.h: ns3::StringChecker [class] module.add_class('StringChecker', parent=root_module['ns3::AttributeChecker']) ## object-vector.h: ns3::ObjectVectorValue [class] - module.add_class('ObjectVectorValue', allow_subclassing=True, parent=root_module['ns3::AttributeValue']) + module.add_class('ObjectVectorValue', parent=root_module['ns3::AttributeValue']) ## boolean.h: ns3::BooleanChecker [class] module.add_class('BooleanChecker', parent=root_module['ns3::AttributeChecker']) ## uinteger.h: ns3::UintegerValue [class] - module.add_class('UintegerValue', allow_subclassing=True, parent=root_module['ns3::AttributeValue']) + module.add_class('UintegerValue', parent=root_module['ns3::AttributeValue']) ## object-vector.h: ns3::ObjectVectorAccessor [class] - module.add_class('ObjectVectorAccessor', allow_subclassing=True, parent=root_module['ns3::AttributeAccessor']) + module.add_class('ObjectVectorAccessor', parent=root_module['ns3::AttributeAccessor']) ## pointer.h: ns3::PointerValue [class] - module.add_class('PointerValue', allow_subclassing=True, parent=root_module['ns3::AttributeValue']) + module.add_class('PointerValue', parent=root_module['ns3::AttributeValue']) ## object-factory.h: ns3::ObjectFactoryChecker [class] module.add_class('ObjectFactoryChecker', parent=root_module['ns3::AttributeChecker']) ## type-id.h: ns3::TypeIdChecker [class] module.add_class('TypeIdChecker', parent=root_module['ns3::AttributeChecker']) ## double.h: ns3::DoubleValue [class] - module.add_class('DoubleValue', allow_subclassing=True, parent=root_module['ns3::AttributeValue']) - ## string.h: ns3::StringValue [class] - module.add_class('StringValue', allow_subclassing=True, parent=root_module['ns3::AttributeValue']) + module.add_class('DoubleValue', parent=root_module['ns3::AttributeValue']) ## type-id.h: ns3::TypeIdValue [class] - module.add_class('TypeIdValue', allow_subclassing=True, parent=root_module['ns3::AttributeValue']) + module.add_class('TypeIdValue', parent=root_module['ns3::AttributeValue']) ## enum.h: ns3::EnumValue [class] - module.add_class('EnumValue', allow_subclassing=True, parent=root_module['ns3::AttributeValue']) + module.add_class('EnumValue', parent=root_module['ns3::AttributeValue']) ## random-variable.h: ns3::RandomVariableValue [class] - module.add_class('RandomVariableValue', allow_subclassing=True, parent=root_module['ns3::AttributeValue']) + module.add_class('RandomVariableValue', parent=root_module['ns3::AttributeValue']) ## object-factory.h: ns3::ObjectFactoryValue [class] - module.add_class('ObjectFactoryValue', allow_subclassing=True, parent=root_module['ns3::AttributeValue']) + module.add_class('ObjectFactoryValue', parent=root_module['ns3::AttributeValue']) ## integer.h: ns3::IntegerValue [class] - module.add_class('IntegerValue', allow_subclassing=True, parent=root_module['ns3::AttributeValue']) - ## attribute.h: ns3::EmptyAttributeValue [class] - module.add_class('EmptyAttributeValue', allow_subclassing=True, parent=root_module['ns3::AttributeValue']) + module.add_class('IntegerValue', parent=root_module['ns3::AttributeValue']) ## boolean.h: ns3::BooleanValue [class] - module.add_class('BooleanValue', allow_subclassing=True, parent=root_module['ns3::AttributeValue']) + module.add_class('BooleanValue', parent=root_module['ns3::AttributeValue']) + ## string.h: ns3::StringValue [class] + module.add_class('StringValue', parent=root_module['ns3::AttributeValue']) + ## attribute.h: ns3::EmptyAttributeValue [class] + module.add_class('EmptyAttributeValue', parent=root_module['ns3::AttributeValue']) ## traced-value.h: ns3::TracedValue [class] module.add_class('TracedValue', template_parameters=['unsigned int']) ## traced-value.h: ns3::TracedValue [class] @@ -273,14 +273,14 @@ def register_methods(root_module): register_Ns3ObjectFactoryChecker_methods(root_module, root_module['ns3::ObjectFactoryChecker']) register_Ns3TypeIdChecker_methods(root_module, root_module['ns3::TypeIdChecker']) register_Ns3DoubleValue_methods(root_module, root_module['ns3::DoubleValue']) - register_Ns3StringValue_methods(root_module, root_module['ns3::StringValue']) register_Ns3TypeIdValue_methods(root_module, root_module['ns3::TypeIdValue']) register_Ns3EnumValue_methods(root_module, root_module['ns3::EnumValue']) register_Ns3RandomVariableValue_methods(root_module, root_module['ns3::RandomVariableValue']) register_Ns3ObjectFactoryValue_methods(root_module, root_module['ns3::ObjectFactoryValue']) register_Ns3IntegerValue_methods(root_module, root_module['ns3::IntegerValue']) - register_Ns3EmptyAttributeValue_methods(root_module, root_module['ns3::EmptyAttributeValue']) register_Ns3BooleanValue_methods(root_module, root_module['ns3::BooleanValue']) + register_Ns3StringValue_methods(root_module, root_module['ns3::StringValue']) + register_Ns3EmptyAttributeValue_methods(root_module, root_module['ns3::EmptyAttributeValue']) register_Ns3TracedValue__Unsigned_int_methods(root_module, root_module['ns3::TracedValue< unsigned int >']) return @@ -1061,23 +1061,6 @@ def register_Ns3DoubleValue_methods(root_module, cls): cls.add_method('DeserializeFromString', 'bool', [param('std::string', 'value'), param('ns3::Ptr< ns3::AttributeChecker const >', 'checker')], is_virtual=True) return -def register_Ns3StringValue_methods(root_module, cls): - ## string.h: ns3::StringValue::StringValue() [constructor] - cls.add_constructor([], visibility='public') - ## string.h: ns3::StringValue::StringValue(std::string const & value) [constructor] - cls.add_constructor([param('std::string&', 'value', is_const=True)], visibility='public') - ## string.h: void ns3::StringValue::Set(std::string const & value) [member function] - cls.add_method('Set', 'void', [param('std::string&', 'value', is_const=True)]) - ## string.h: std::string ns3::StringValue::Get() const [member function] - cls.add_method('Get', 'std::string', [], is_const=True) - ## string.h: ns3::Ptr ns3::StringValue::Copy() const [member function] - cls.add_method('Copy', 'ns3::Ptr< ns3::AttributeValue >', [], is_const=True, is_virtual=True) - ## string.h: std::string ns3::StringValue::SerializeToString(ns3::Ptr checker) const [member function] - cls.add_method('SerializeToString', 'std::string', [param('ns3::Ptr< ns3::AttributeChecker const >', 'checker')], is_const=True, is_virtual=True) - ## string.h: bool ns3::StringValue::DeserializeFromString(std::string value, ns3::Ptr checker) [member function] - cls.add_method('DeserializeFromString', 'bool', [param('std::string', 'value'), param('ns3::Ptr< ns3::AttributeChecker const >', 'checker')], is_virtual=True) - return - def register_Ns3TypeIdValue_methods(root_module, cls): ## type-id.h: ns3::TypeIdValue::TypeIdValue() [constructor] cls.add_constructor([], visibility='public') @@ -1163,19 +1146,6 @@ def register_Ns3IntegerValue_methods(root_module, cls): cls.add_method('DeserializeFromString', 'bool', [param('std::string', 'value'), param('ns3::Ptr< ns3::AttributeChecker const >', 'checker')], is_virtual=True) return -def register_Ns3EmptyAttributeValue_methods(root_module, cls): - ## attribute.h: ns3::EmptyAttributeValue::EmptyAttributeValue(ns3::EmptyAttributeValue const & arg0) [copy constructor] - cls.add_constructor([param('ns3::EmptyAttributeValue&', 'arg0', is_const=True)], visibility='public') - ## attribute.h: ns3::EmptyAttributeValue::EmptyAttributeValue() [constructor] - cls.add_constructor([], visibility='public') - ## attribute.h: ns3::Ptr ns3::EmptyAttributeValue::Copy() const [member function] - cls.add_method('Copy', 'ns3::Ptr< ns3::AttributeValue >', [], is_const=True, visibility='private', is_virtual=True) - ## attribute.h: std::string ns3::EmptyAttributeValue::SerializeToString(ns3::Ptr checker) const [member function] - cls.add_method('SerializeToString', 'std::string', [param('ns3::Ptr< ns3::AttributeChecker const >', 'checker')], is_const=True, visibility='private', is_virtual=True) - ## attribute.h: bool ns3::EmptyAttributeValue::DeserializeFromString(std::string value, ns3::Ptr checker) [member function] - cls.add_method('DeserializeFromString', 'bool', [param('std::string', 'value'), param('ns3::Ptr< ns3::AttributeChecker const >', 'checker')], visibility='private', is_virtual=True) - return - def register_Ns3BooleanValue_methods(root_module, cls): ## boolean.h: ns3::BooleanValue::BooleanValue(ns3::BooleanValue const & arg0) [copy constructor] cls.add_constructor([param('ns3::BooleanValue&', 'arg0', is_const=True)], visibility='public') @@ -1196,6 +1166,36 @@ def register_Ns3BooleanValue_methods(root_module, cls): cls.add_output_stream_operator() return +def register_Ns3StringValue_methods(root_module, cls): + ## string.h: ns3::StringValue::StringValue() [constructor] + cls.add_constructor([], visibility='public') + ## string.h: ns3::StringValue::StringValue(std::string const & value) [constructor] + cls.add_constructor([param('std::string&', 'value', is_const=True)], visibility='public') + ## string.h: void ns3::StringValue::Set(std::string const & value) [member function] + cls.add_method('Set', 'void', [param('std::string&', 'value', is_const=True)]) + ## string.h: std::string ns3::StringValue::Get() const [member function] + cls.add_method('Get', 'std::string', [], is_const=True) + ## string.h: ns3::Ptr ns3::StringValue::Copy() const [member function] + cls.add_method('Copy', 'ns3::Ptr< ns3::AttributeValue >', [], is_const=True, is_virtual=True) + ## string.h: std::string ns3::StringValue::SerializeToString(ns3::Ptr checker) const [member function] + cls.add_method('SerializeToString', 'std::string', [param('ns3::Ptr< ns3::AttributeChecker const >', 'checker')], is_const=True, is_virtual=True) + ## string.h: bool ns3::StringValue::DeserializeFromString(std::string value, ns3::Ptr checker) [member function] + cls.add_method('DeserializeFromString', 'bool', [param('std::string', 'value'), param('ns3::Ptr< ns3::AttributeChecker const >', 'checker')], is_virtual=True) + return + +def register_Ns3EmptyAttributeValue_methods(root_module, cls): + ## attribute.h: ns3::EmptyAttributeValue::EmptyAttributeValue(ns3::EmptyAttributeValue const & arg0) [copy constructor] + cls.add_constructor([param('ns3::EmptyAttributeValue&', 'arg0', is_const=True)], visibility='public') + ## attribute.h: ns3::EmptyAttributeValue::EmptyAttributeValue() [constructor] + cls.add_constructor([], visibility='public') + ## attribute.h: ns3::Ptr ns3::EmptyAttributeValue::Copy() const [member function] + cls.add_method('Copy', 'ns3::Ptr< ns3::AttributeValue >', [], is_const=True, visibility='private', is_virtual=True) + ## attribute.h: std::string ns3::EmptyAttributeValue::SerializeToString(ns3::Ptr checker) const [member function] + cls.add_method('SerializeToString', 'std::string', [param('ns3::Ptr< ns3::AttributeChecker const >', 'checker')], is_const=True, visibility='private', is_virtual=True) + ## attribute.h: bool ns3::EmptyAttributeValue::DeserializeFromString(std::string value, ns3::Ptr checker) [member function] + cls.add_method('DeserializeFromString', 'bool', [param('std::string', 'value'), param('ns3::Ptr< ns3::AttributeChecker const >', 'checker')], visibility='private', is_virtual=True) + return + def register_Ns3TracedValue__Unsigned_int_methods(root_module, cls): ## traced-value.h: ns3::TracedValue::TracedValue() [constructor] cls.add_constructor([], visibility='public') diff --git a/bindings/python/ns3_module_csma.py b/bindings/python/ns3_module_csma.py index ee4152eac..aa310a6b4 100644 --- a/bindings/python/ns3_module_csma.py +++ b/bindings/python/ns3_module_csma.py @@ -10,9 +10,9 @@ def register_types(module): ## backoff.h: ns3::Backoff [class] module.add_class('Backoff') ## csma-channel.h: ns3::CsmaChannel [class] - module.add_class('CsmaChannel', allow_subclassing=True, parent=root_module['ns3::Channel']) + module.add_class('CsmaChannel', parent=root_module['ns3::Channel']) ## csma-net-device.h: ns3::CsmaNetDevice [class] - module.add_class('CsmaNetDevice', allow_subclassing=True, parent=root_module['ns3::NetDevice']) + module.add_class('CsmaNetDevice', parent=root_module['ns3::NetDevice']) ## csma-net-device.h: ns3::CsmaNetDevice::CsmaEncapsulationMode [enumeration] module.add_enum('CsmaEncapsulationMode', ['ETHERNET_V1', 'IP_ARP', 'RAW', 'LLC'], outer_class=root_module['ns3::CsmaNetDevice']) @@ -159,8 +159,8 @@ def register_Ns3CsmaNetDevice_methods(root_module, cls): cls.add_method('SetQueue', 'void', [param('ns3::Ptr< ns3::Queue >', 'queue')]) ## csma-net-device.h: void ns3::CsmaNetDevice::SetReceiveErrorModel(ns3::Ptr em) [member function] cls.add_method('SetReceiveErrorModel', 'void', [param('ns3::Ptr< ns3::ErrorModel >', 'em')]) - ## csma-net-device.h: void ns3::CsmaNetDevice::Receive(ns3::Ptr p) [member function] - cls.add_method('Receive', 'void', [param('ns3::Ptr< ns3::Packet >', 'p')]) + ## csma-net-device.h: void ns3::CsmaNetDevice::Receive(ns3::Ptr p, ns3::Ptr sender) [member function] + cls.add_method('Receive', 'void', [param('ns3::Ptr< ns3::Packet >', 'p'), param('ns3::Ptr< ns3::CsmaNetDevice >', 'sender')]) ## csma-net-device.h: bool ns3::CsmaNetDevice::IsSendEnabled() [member function] cls.add_method('IsSendEnabled', 'bool', []) ## csma-net-device.h: void ns3::CsmaNetDevice::SetSendEnable(bool enable) [member function] @@ -205,20 +205,22 @@ def register_Ns3CsmaNetDevice_methods(root_module, cls): cls.add_method('IsPointToPoint', 'bool', [], is_const=True, is_virtual=True) ## csma-net-device.h: bool ns3::CsmaNetDevice::Send(ns3::Ptr packet, ns3::Address const & dest, uint16_t protocolNumber) [member function] cls.add_method('Send', 'bool', [param('ns3::Ptr< ns3::Packet >', 'packet'), param('ns3::Address&', 'dest', is_const=True), param('uint16_t', 'protocolNumber')], is_virtual=True) + ## csma-net-device.h: bool ns3::CsmaNetDevice::SendFrom(ns3::Ptr packet, ns3::Address const & source, ns3::Address const & dest, uint16_t protocolNumber) [member function] + cls.add_method('SendFrom', 'bool', [param('ns3::Ptr< ns3::Packet >', 'packet'), param('ns3::Address&', 'source', is_const=True), param('ns3::Address&', 'dest', is_const=True), param('uint16_t', 'protocolNumber')], is_virtual=True) ## csma-net-device.h: ns3::Ptr ns3::CsmaNetDevice::GetNode() const [member function] cls.add_method('GetNode', 'ns3::Ptr< ns3::Node >', [], is_const=True, is_virtual=True) ## csma-net-device.h: void ns3::CsmaNetDevice::SetNode(ns3::Ptr node) [member function] cls.add_method('SetNode', 'void', [param('ns3::Ptr< ns3::Node >', 'node')], is_virtual=True) ## csma-net-device.h: bool ns3::CsmaNetDevice::NeedsArp() const [member function] cls.add_method('NeedsArp', 'bool', [], is_const=True, is_virtual=True) - ## csma-net-device.h: void ns3::CsmaNetDevice::SetReceiveCallback(ns3::Callback, ns3::Ptr, unsigned short, ns3::Address const&, ns3::empty, ns3::empty> cb) [member function] - cls.add_method('SetReceiveCallback', 'void', [param('ns3::Callback< bool, ns3::Ptr< ns3::NetDevice >, ns3::Ptr< ns3::Packet >, unsigned short, ns3::Address const&, ns3::empty, ns3::empty >', 'cb')], is_virtual=True) + ## csma-net-device.h: void ns3::CsmaNetDevice::SetReceiveCallback(ns3::Callback, ns3::Ptr, unsigned short, ns3::Address const&, ns3::Address const&, ns3::NetDevice::PacketType> cb) [member function] + cls.add_method('SetReceiveCallback', 'void', [param('ns3::Callback< bool, ns3::Ptr< ns3::NetDevice >, ns3::Ptr< ns3::Packet >, unsigned short, ns3::Address const&, ns3::Address const&, ns3::NetDevice::PacketType >', 'cb')], is_virtual=True) ## csma-net-device.h: void ns3::CsmaNetDevice::DoDispose() [member function] cls.add_method('DoDispose', 'void', [], visibility='protected', is_virtual=True) ## csma-net-device.h: ns3::Ptr ns3::CsmaNetDevice::GetQueue() const [member function] cls.add_method('GetQueue', 'ns3::Ptr< ns3::Queue >', [], is_const=True, visibility='protected') - ## csma-net-device.h: void ns3::CsmaNetDevice::AddHeader(ns3::Ptr p, ns3::Mac48Address dest, uint16_t protocolNumber) [member function] - cls.add_method('AddHeader', 'void', [param('ns3::Ptr< ns3::Packet >', 'p'), param('ns3::Mac48Address', 'dest'), param('uint16_t', 'protocolNumber')], visibility='protected') + ## csma-net-device.h: void ns3::CsmaNetDevice::AddHeader(ns3::Ptr p, ns3::Mac48Address source, ns3::Mac48Address dest, uint16_t protocolNumber) [member function] + cls.add_method('AddHeader', 'void', [param('ns3::Ptr< ns3::Packet >', 'p'), param('ns3::Mac48Address', 'source'), param('ns3::Mac48Address', 'dest'), param('uint16_t', 'protocolNumber')], visibility='protected') ## csma-net-device.h: bool ns3::CsmaNetDevice::ProcessHeader(ns3::Ptr p, uint16_t & param) [member function] cls.add_method('ProcessHeader', 'bool', [param('ns3::Ptr< ns3::Packet >', 'p'), param('uint16_t&', 'param')], visibility='protected') return diff --git a/bindings/python/ns3_module_global_routing.py b/bindings/python/ns3_module_global_routing.py index 026ea0ac0..6a80d9623 100644 --- a/bindings/python/ns3_module_global_routing.py +++ b/bindings/python/ns3_module_global_routing.py @@ -16,7 +16,7 @@ def register_types(module): ## global-router-interface.h: ns3::GlobalRoutingLinkRecord::LinkType [enumeration] module.add_enum('LinkType', ['Unknown', 'PointToPoint', 'TransitNetwork', 'StubNetwork', 'VirtualLink'], outer_class=root_module['ns3::GlobalRoutingLinkRecord']) ## global-router-interface.h: ns3::GlobalRouter [class] - module.add_class('GlobalRouter', allow_subclassing=True, is_singleton=True, parent=root_module['ns3::Object']) + module.add_class('GlobalRouter', is_singleton=True, parent=root_module['ns3::Object']) ## Register a nested module for the namespace internal diff --git a/bindings/python/ns3_module_internet_stack.py b/bindings/python/ns3_module_internet_stack.py index c430e0d34..6adcbf070 100644 --- a/bindings/python/ns3_module_internet_stack.py +++ b/bindings/python/ns3_module_internet_stack.py @@ -4,17 +4,17 @@ def register_types(module): root_module = module.get_root() ## ipv4-interface.h: ns3::Ipv4Interface [class] - module.add_class('Ipv4Interface', allow_subclassing=True, parent=root_module['ns3::Object']) + module.add_class('Ipv4Interface', parent=root_module['ns3::Object']) ## udp-header.h: ns3::UdpHeader [class] - module.add_class('UdpHeader', allow_subclassing=True, parent=root_module['ns3::Header']) + module.add_class('UdpHeader', parent=root_module['ns3::Header']) ## tcp-header.h: ns3::TcpHeader [class] - module.add_class('TcpHeader', allow_subclassing=True, parent=root_module['ns3::Header']) + module.add_class('TcpHeader', parent=root_module['ns3::Header']) ## tcp-header.h: ns3::TcpHeader::Flags_t [enumeration] module.add_enum('Flags_t', ['NONE', 'FIN', 'SYN', 'RST', 'PSH', 'ACK', 'URG'], outer_class=root_module['ns3::TcpHeader']) ## ipv4-static-routing.h: ns3::Ipv4StaticRouting [class] - module.add_class('Ipv4StaticRouting', allow_subclassing=True, parent=root_module['ns3::Ipv4RoutingProtocol']) + module.add_class('Ipv4StaticRouting', parent=root_module['ns3::Ipv4RoutingProtocol']) ## ipv4-l3-protocol.h: ns3::Ipv4L3Protocol [class] - module.add_class('Ipv4L3Protocol', allow_subclassing=True, parent=root_module['ns3::Object']) + module.add_class('Ipv4L3Protocol', parent=root_module['ns3::Object']) ## Register a nested module for the namespace internal @@ -245,8 +245,8 @@ def register_Ns3Ipv4L3Protocol_methods(root_module, cls): cls.add_method('SetDefaultTtl', 'void', [param('uint8_t', 'ttl')]) ## ipv4-l3-protocol.h: ns3::Ptr ns3::Ipv4L3Protocol::FindInterfaceForDevice(ns3::Ptr device) [member function] cls.add_method('FindInterfaceForDevice', 'ns3::Ptr< ns3::Ipv4Interface >', [param('ns3::Ptr< const ns3::NetDevice >', 'device')]) - ## ipv4-l3-protocol.h: void ns3::Ipv4L3Protocol::Receive(ns3::Ptr device, ns3::Ptr p, uint16_t protocol, ns3::Address const & from) [member function] - cls.add_method('Receive', 'void', [param('ns3::Ptr< ns3::NetDevice >', 'device'), param('ns3::Ptr< ns3::Packet >', 'p'), param('uint16_t', 'protocol'), param('ns3::Address&', 'from', is_const=True)]) + ## ipv4-l3-protocol.h: void ns3::Ipv4L3Protocol::Receive(ns3::Ptr device, ns3::Ptr p, uint16_t protocol, ns3::Address const & from, ns3::Address const & to, ns3::NetDevice::PacketType packetType) [member function] + cls.add_method('Receive', 'void', [param('ns3::Ptr< ns3::NetDevice >', 'device'), param('ns3::Ptr< ns3::Packet >', 'p'), param('uint16_t', 'protocol'), param('ns3::Address&', 'from', is_const=True), param('ns3::Address&', 'to', is_const=True), param('ns3::NetDevice::PacketType', 'packetType')]) ## ipv4-l3-protocol.h: void ns3::Ipv4L3Protocol::Send(ns3::Ptr packet, ns3::Ipv4Address source, ns3::Ipv4Address destination, uint8_t protocol) [member function] cls.add_method('Send', 'void', [param('ns3::Ptr< ns3::Packet >', 'packet'), param('ns3::Ipv4Address', 'source'), param('ns3::Ipv4Address', 'destination'), param('uint8_t', 'protocol')]) ## ipv4-l3-protocol.h: void ns3::Ipv4L3Protocol::AddHostRouteTo(ns3::Ipv4Address dest, ns3::Ipv4Address nextHop, uint32_t interface) [member function] diff --git a/bindings/python/ns3_module_mobility.py b/bindings/python/ns3_module_mobility.py index 2f5cedefe..470560ba9 100644 --- a/bindings/python/ns3_module_mobility.py +++ b/bindings/python/ns3_module_mobility.py @@ -16,37 +16,37 @@ def register_types(module): ## rectangle.h: ns3::Rectangle::Side [enumeration] module.add_enum('Side', ['RIGHT', 'LEFT', 'TOP', 'BOTTOM'], outer_class=root_module['ns3::Rectangle']) ## position-allocator.h: ns3::PositionAllocator [class] - module.add_class('PositionAllocator', allow_subclassing=True, parent=root_module['ns3::Object']) + module.add_class('PositionAllocator', parent=root_module['ns3::Object']) ## position-allocator.h: ns3::ListPositionAllocator [class] - module.add_class('ListPositionAllocator', allow_subclassing=True, parent=root_module['ns3::PositionAllocator']) + module.add_class('ListPositionAllocator', parent=root_module['ns3::PositionAllocator']) ## rectangle.h: ns3::RectangleValue [class] - module.add_class('RectangleValue', allow_subclassing=True, parent=root_module['ns3::AttributeValue']) + module.add_class('RectangleValue', parent=root_module['ns3::AttributeValue']) ## position-allocator.h: ns3::RandomRectanglePositionAllocator [class] - module.add_class('RandomRectanglePositionAllocator', allow_subclassing=True, parent=root_module['ns3::PositionAllocator']) + module.add_class('RandomRectanglePositionAllocator', parent=root_module['ns3::PositionAllocator']) ## vector.h: ns3::VectorValue [class] - module.add_class('VectorValue', allow_subclassing=True, parent=root_module['ns3::AttributeValue']) + module.add_class('VectorValue', parent=root_module['ns3::AttributeValue']) ## position-allocator.h: ns3::RandomDiscPositionAllocator [class] - module.add_class('RandomDiscPositionAllocator', allow_subclassing=True, parent=root_module['ns3::PositionAllocator']) + module.add_class('RandomDiscPositionAllocator', parent=root_module['ns3::PositionAllocator']) ## mobility-model.h: ns3::MobilityModel [class] - module.add_class('MobilityModel', allow_subclassing=True, parent=root_module['ns3::Object']) + module.add_class('MobilityModel', parent=root_module['ns3::Object']) ## random-direction-2d-mobility-model.h: ns3::RandomDirection2dMobilityModel [class] - module.add_class('RandomDirection2dMobilityModel', allow_subclassing=True, parent=root_module['ns3::MobilityModel']) + module.add_class('RandomDirection2dMobilityModel', parent=root_module['ns3::MobilityModel']) ## position-allocator.h: ns3::GridPositionAllocator [class] - module.add_class('GridPositionAllocator', allow_subclassing=True, parent=root_module['ns3::PositionAllocator']) + module.add_class('GridPositionAllocator', parent=root_module['ns3::PositionAllocator']) ## position-allocator.h: ns3::GridPositionAllocator::LayoutType [enumeration] module.add_enum('LayoutType', ['ROW_FIRST', 'COLUMN_FIRST'], outer_class=root_module['ns3::GridPositionAllocator']) ## random-waypoint-mobility-model.h: ns3::RandomWaypointMobilityModel [class] - module.add_class('RandomWaypointMobilityModel', allow_subclassing=True, parent=root_module['ns3::MobilityModel']) + module.add_class('RandomWaypointMobilityModel', parent=root_module['ns3::MobilityModel']) ## random-walk-2d-mobility-model.h: ns3::RandomWalk2dMobilityModel [class] - module.add_class('RandomWalk2dMobilityModel', allow_subclassing=True, parent=root_module['ns3::MobilityModel']) + module.add_class('RandomWalk2dMobilityModel', parent=root_module['ns3::MobilityModel']) ## random-walk-2d-mobility-model.h: ns3::RandomWalk2dMobilityModel::Mode [enumeration] module.add_enum('Mode', ['MODE_DISTANCE', 'MODE_TIME'], outer_class=root_module['ns3::RandomWalk2dMobilityModel']) ## static-speed-mobility-model.h: ns3::StaticSpeedMobilityModel [class] - module.add_class('StaticSpeedMobilityModel', allow_subclassing=True, parent=root_module['ns3::MobilityModel']) + module.add_class('StaticSpeedMobilityModel', parent=root_module['ns3::MobilityModel']) ## hierarchical-mobility-model.h: ns3::HierarchicalMobilityModel [class] - module.add_class('HierarchicalMobilityModel', allow_subclassing=True, parent=root_module['ns3::MobilityModel']) + module.add_class('HierarchicalMobilityModel', parent=root_module['ns3::MobilityModel']) ## static-mobility-model.h: ns3::StaticMobilityModel [class] - module.add_class('StaticMobilityModel', allow_subclassing=True, parent=root_module['ns3::MobilityModel']) + module.add_class('StaticMobilityModel', parent=root_module['ns3::MobilityModel']) ## Register a nested module for the namespace internal diff --git a/bindings/python/ns3_module_node.py b/bindings/python/ns3_module_node.py index d01bad33a..c3d161e8f 100644 --- a/bindings/python/ns3_module_node.py +++ b/bindings/python/ns3_module_node.py @@ -40,15 +40,15 @@ def register_types(module): ## ipv4-address.h: ns3::Ipv4Mask [class] module.add_class('Ipv4Mask') ## ipv4-address.h: ns3::Ipv4AddressValue [class] - module.add_class('Ipv4AddressValue', allow_subclassing=True, parent=root_module['ns3::AttributeValue']) + module.add_class('Ipv4AddressValue', parent=root_module['ns3::AttributeValue']) ## ipv4.h: ns3::Ipv4RoutingProtocol [class] - module.add_class('Ipv4RoutingProtocol', allow_subclassing=True, parent=root_module['ns3::Object']) + module.add_class('Ipv4RoutingProtocol', parent=root_module['ns3::Object']) ## mac48-address.h: ns3::Mac48AddressValue [class] - module.add_class('Mac48AddressValue', allow_subclassing=True, parent=root_module['ns3::AttributeValue']) + module.add_class('Mac48AddressValue', parent=root_module['ns3::AttributeValue']) ## ipv4-address.h: ns3::Ipv4MaskValue [class] - module.add_class('Ipv4MaskValue', allow_subclassing=True, parent=root_module['ns3::AttributeValue']) + module.add_class('Ipv4MaskValue', parent=root_module['ns3::AttributeValue']) ## socket.h: ns3::SocketAddressTag [class] - module.add_class('SocketAddressTag', allow_subclassing=True, parent=root_module['ns3::Tag']) + module.add_class('SocketAddressTag', parent=root_module['ns3::Tag']) ## inet-socket-address.h: ns3::InetSocketAddress [class] module.add_class('InetSocketAddress') ## inet-socket-address.h: ns3::InetSocketAddress [class] @@ -58,51 +58,53 @@ def register_types(module): ## ipv4-address.h: ns3::Ipv4Address [class] root_module['ns3::Ipv4Address'].implicitly_converts_to(root_module['ns3::Address']) ## application.h: ns3::Application [class] - module.add_class('Application', allow_subclassing=True, parent=root_module['ns3::Object']) + module.add_class('Application', parent=root_module['ns3::Object']) ## queue.h: ns3::Queue [class] - module.add_class('Queue', allow_subclassing=True, parent=root_module['ns3::Object']) + module.add_class('Queue', parent=root_module['ns3::Object']) ## socket.h: ns3::Socket [class] - module.add_class('Socket', allow_subclassing=True, parent=root_module['ns3::Object']) + module.add_class('Socket', parent=root_module['ns3::Object']) ## socket.h: ns3::Socket::SocketErrno [enumeration] module.add_enum('SocketErrno', ['ERROR_NOTERROR', 'ERROR_ISCONN', 'ERROR_NOTCONN', 'ERROR_MSGSIZE', 'ERROR_AGAIN', 'ERROR_SHUTDOWN', 'ERROR_OPNOTSUPP', 'ERROR_AFNOSUPPORT', 'ERROR_INVAL', 'ERROR_BADF', 'ERROR_NOROUTETOHOST', 'SOCKET_ERRNO_LAST'], outer_class=root_module['ns3::Socket']) ## ipv4-header.h: ns3::Ipv4Header [class] - module.add_class('Ipv4Header', allow_subclassing=True, parent=root_module['ns3::Header']) + module.add_class('Ipv4Header', parent=root_module['ns3::Header']) ## udp-socket.h: ns3::UdpSocket [class] - module.add_class('UdpSocket', allow_subclassing=True, parent=root_module['ns3::Socket']) + module.add_class('UdpSocket', parent=root_module['ns3::Socket']) ## net-device.h: ns3::NetDevice [class] - module.add_class('NetDevice', allow_subclassing=True, parent=root_module['ns3::Object']) - ## channel.h: ns3::Channel [class] - module.add_class('Channel', allow_subclassing=True, parent=root_module['ns3::Object']) - ## simple-channel.h: ns3::SimpleChannel [class] - module.add_class('SimpleChannel', allow_subclassing=True, parent=root_module['ns3::Channel']) + module.add_class('NetDevice', parent=root_module['ns3::Object']) + ## net-device.h: ns3::NetDevice::PacketType [enumeration] + module.add_enum('PacketType', ['PACKET_HOST', 'PACKET_BROADCAST', 'PACKET_MULTICAST', 'PACKET_OTHERHOST'], outer_class=root_module['ns3::NetDevice']) ## address.h: ns3::AddressValue [class] - module.add_class('AddressValue', allow_subclassing=True, parent=root_module['ns3::AttributeValue']) + module.add_class('AddressValue', parent=root_module['ns3::AttributeValue']) ## node.h: ns3::Node [class] - module.add_class('Node', allow_subclassing=True, parent=root_module['ns3::Object']) + module.add_class('Node', parent=root_module['ns3::Object']) ## tcp-socket.h: ns3::TcpSocket [class] - module.add_class('TcpSocket', allow_subclassing=True, parent=root_module['ns3::Socket']) + module.add_class('TcpSocket', parent=root_module['ns3::Socket']) + ## channel.h: ns3::Channel [class] + module.add_class('Channel', parent=root_module['ns3::Object']) ## ethernet-header.h: ns3::EthernetHeader [class] - module.add_class('EthernetHeader', allow_subclassing=True, parent=root_module['ns3::Header']) + module.add_class('EthernetHeader', parent=root_module['ns3::Header']) ## socket.h: ns3::SocketIpTtlTag [class] - module.add_class('SocketIpTtlTag', allow_subclassing=True, parent=root_module['ns3::Tag']) + module.add_class('SocketIpTtlTag', parent=root_module['ns3::Tag']) ## ipv4.h: ns3::Ipv4 [class] - module.add_class('Ipv4', allow_subclassing=True, parent=root_module['ns3::Object']) + module.add_class('Ipv4', parent=root_module['ns3::Object']) ## socket-factory.h: ns3::SocketFactory [class] - module.add_class('SocketFactory', allow_subclassing=True, parent=root_module['ns3::Object']) + module.add_class('SocketFactory', parent=root_module['ns3::Object']) ## drop-tail-queue.h: ns3::DropTailQueue [class] - module.add_class('DropTailQueue', allow_subclassing=True, parent=root_module['ns3::Queue']) + module.add_class('DropTailQueue', parent=root_module['ns3::Queue']) ## ethernet-trailer.h: ns3::EthernetTrailer [class] - module.add_class('EthernetTrailer', allow_subclassing=True, parent=root_module['ns3::Trailer']) + module.add_class('EthernetTrailer', parent=root_module['ns3::Trailer']) ## llc-snap-header.h: ns3::LlcSnapHeader [class] - module.add_class('LlcSnapHeader', allow_subclassing=True, parent=root_module['ns3::Header']) + module.add_class('LlcSnapHeader', parent=root_module['ns3::Header']) ## udp-socket-factory.h: ns3::UdpSocketFactory [class] module.add_class('UdpSocketFactory', parent=root_module['ns3::SocketFactory']) ## simple-net-device.h: ns3::SimpleNetDevice [class] - module.add_class('SimpleNetDevice', allow_subclassing=True, parent=root_module['ns3::NetDevice']) + module.add_class('SimpleNetDevice', parent=root_module['ns3::NetDevice']) + ## simple-channel.h: ns3::SimpleChannel [class] + module.add_class('SimpleChannel', parent=root_module['ns3::Channel']) ## tcp-socket-factory.h: ns3::TcpSocketFactory [class] module.add_class('TcpSocketFactory', parent=root_module['ns3::SocketFactory']) ## packet-socket-factory.h: ns3::PacketSocketFactory [class] - module.add_class('PacketSocketFactory', allow_subclassing=True, parent=root_module['ns3::SocketFactory']) + module.add_class('PacketSocketFactory', parent=root_module['ns3::SocketFactory']) ## Register a nested module for the namespace internal @@ -171,11 +173,10 @@ def register_methods(root_module): register_Ns3Ipv4Header_methods(root_module, root_module['ns3::Ipv4Header']) register_Ns3UdpSocket_methods(root_module, root_module['ns3::UdpSocket']) register_Ns3NetDevice_methods(root_module, root_module['ns3::NetDevice']) - register_Ns3Channel_methods(root_module, root_module['ns3::Channel']) - register_Ns3SimpleChannel_methods(root_module, root_module['ns3::SimpleChannel']) register_Ns3AddressValue_methods(root_module, root_module['ns3::AddressValue']) register_Ns3Node_methods(root_module, root_module['ns3::Node']) register_Ns3TcpSocket_methods(root_module, root_module['ns3::TcpSocket']) + register_Ns3Channel_methods(root_module, root_module['ns3::Channel']) register_Ns3EthernetHeader_methods(root_module, root_module['ns3::EthernetHeader']) register_Ns3SocketIpTtlTag_methods(root_module, root_module['ns3::SocketIpTtlTag']) register_Ns3Ipv4_methods(root_module, root_module['ns3::Ipv4']) @@ -185,6 +186,7 @@ def register_methods(root_module): register_Ns3LlcSnapHeader_methods(root_module, root_module['ns3::LlcSnapHeader']) register_Ns3UdpSocketFactory_methods(root_module, root_module['ns3::UdpSocketFactory']) register_Ns3SimpleNetDevice_methods(root_module, root_module['ns3::SimpleNetDevice']) + register_Ns3SimpleChannel_methods(root_module, root_module['ns3::SimpleChannel']) register_Ns3TcpSocketFactory_methods(root_module, root_module['ns3::TcpSocketFactory']) register_Ns3PacketSocketFactory_methods(root_module, root_module['ns3::PacketSocketFactory']) return @@ -851,49 +853,19 @@ def register_Ns3NetDevice_methods(root_module, cls): cls.add_method('IsPointToPoint', 'bool', [], is_pure_virtual=True, is_const=True, is_virtual=True) ## net-device.h: bool ns3::NetDevice::Send(ns3::Ptr packet, ns3::Address const & dest, uint16_t protocolNumber) [member function] cls.add_method('Send', 'bool', [param('ns3::Ptr< ns3::Packet >', 'packet'), param('ns3::Address&', 'dest', is_const=True), param('uint16_t', 'protocolNumber')], is_pure_virtual=True, is_virtual=True) + ## net-device.h: bool ns3::NetDevice::SendFrom(ns3::Ptr packet, ns3::Address const & source, ns3::Address const & dest, uint16_t protocolNumber) [member function] + cls.add_method('SendFrom', 'bool', [param('ns3::Ptr< ns3::Packet >', 'packet'), param('ns3::Address&', 'source', is_const=True), param('ns3::Address&', 'dest', is_const=True), param('uint16_t', 'protocolNumber')], is_pure_virtual=True, is_virtual=True) ## net-device.h: ns3::Ptr ns3::NetDevice::GetNode() const [member function] cls.add_method('GetNode', 'ns3::Ptr< ns3::Node >', [], is_pure_virtual=True, is_const=True, is_virtual=True) ## net-device.h: void ns3::NetDevice::SetNode(ns3::Ptr node) [member function] cls.add_method('SetNode', 'void', [param('ns3::Ptr< ns3::Node >', 'node')], is_pure_virtual=True, is_virtual=True) ## net-device.h: bool ns3::NetDevice::NeedsArp() const [member function] cls.add_method('NeedsArp', 'bool', [], is_pure_virtual=True, is_const=True, is_virtual=True) - ## net-device.h: void ns3::NetDevice::SetReceiveCallback(ns3::Callback, ns3::Ptr, unsigned short, ns3::Address const&, ns3::empty, ns3::empty> cb) [member function] - cls.add_method('SetReceiveCallback', 'void', [param('ns3::Callback< bool, ns3::Ptr< ns3::NetDevice >, ns3::Ptr< ns3::Packet >, unsigned short, ns3::Address const&, ns3::empty, ns3::empty >', 'cb')], is_pure_virtual=True, is_virtual=True) + ## net-device.h: void ns3::NetDevice::SetReceiveCallback(ns3::Callback, ns3::Ptr, unsigned short, ns3::Address const&, ns3::Address const&, ns3::NetDevice::PacketType> cb) [member function] + cls.add_method('SetReceiveCallback', 'void', [param('ns3::Callback< bool, ns3::Ptr< ns3::NetDevice >, ns3::Ptr< ns3::Packet >, unsigned short, ns3::Address const&, ns3::Address const&, ns3::NetDevice::PacketType >', 'cb')], is_pure_virtual=True, is_virtual=True) cls.add_constructor([]) return -def register_Ns3Channel_methods(root_module, cls): - ## channel.h: static ns3::TypeId ns3::Channel::GetTypeId() [member function] - cls.add_method('GetTypeId', 'ns3::TypeId', [], is_static=True) - ## channel.h: ns3::Channel::Channel() [constructor] - cls.add_constructor([], visibility='public') - ## channel.h: ns3::Channel::Channel(std::string name) [constructor] - cls.add_constructor([param('std::string', 'name')], visibility='public') - ## channel.h: void ns3::Channel::SetName(std::string arg0) [member function] - cls.add_method('SetName', 'void', [param('std::string', 'arg0')]) - ## channel.h: std::string ns3::Channel::GetName() [member function] - cls.add_method('GetName', 'std::string', []) - ## channel.h: uint32_t ns3::Channel::GetNDevices() const [member function] - cls.add_method('GetNDevices', 'uint32_t', [], is_pure_virtual=True, is_const=True, is_virtual=True) - ## channel.h: ns3::Ptr ns3::Channel::GetDevice(uint32_t i) const [member function] - cls.add_method('GetDevice', 'ns3::Ptr< ns3::NetDevice >', [param('uint32_t', 'i')], is_pure_virtual=True, is_const=True, is_virtual=True) - return - -def register_Ns3SimpleChannel_methods(root_module, cls): - ## simple-channel.h: static ns3::TypeId ns3::SimpleChannel::GetTypeId() [member function] - cls.add_method('GetTypeId', 'ns3::TypeId', [], is_static=True) - ## simple-channel.h: ns3::SimpleChannel::SimpleChannel() [constructor] - cls.add_constructor([], visibility='public') - ## simple-channel.h: void ns3::SimpleChannel::Send(ns3::Ptr p, uint16_t protocol, ns3::Mac48Address to, ns3::Mac48Address from, ns3::Ptr sender) [member function] - cls.add_method('Send', 'void', [param('ns3::Ptr< ns3::Packet >', 'p'), param('uint16_t', 'protocol'), param('ns3::Mac48Address', 'to'), param('ns3::Mac48Address', 'from'), param('ns3::Ptr< ns3::SimpleNetDevice >', 'sender')]) - ## simple-channel.h: void ns3::SimpleChannel::Add(ns3::Ptr device) [member function] - cls.add_method('Add', 'void', [param('ns3::Ptr< ns3::SimpleNetDevice >', 'device')]) - ## simple-channel.h: uint32_t ns3::SimpleChannel::GetNDevices() const [member function] - cls.add_method('GetNDevices', 'uint32_t', [], is_const=True, is_virtual=True) - ## simple-channel.h: ns3::Ptr ns3::SimpleChannel::GetDevice(uint32_t i) const [member function] - cls.add_method('GetDevice', 'ns3::Ptr< ns3::NetDevice >', [param('uint32_t', 'i')], is_const=True, is_virtual=True) - return - def register_Ns3AddressValue_methods(root_module, cls): ## address.h: ns3::AddressValue::AddressValue() [constructor] cls.add_constructor([], visibility='public') @@ -936,10 +908,14 @@ def register_Ns3Node_methods(root_module, cls): cls.add_method('GetFirstApplication', 'ns3::Ptr< ns3::Application >', [param('ns3::TypeId', 'tid')]) ## node.h: uint32_t ns3::Node::GetNApplications() const [member function] cls.add_method('GetNApplications', 'uint32_t', [], is_const=True) - ## node.h: void ns3::Node::RegisterProtocolHandler(ns3::Callback, ns3::Ptr, unsigned short, ns3::Address const&, ns3::empty, ns3::empty> handler, uint16_t protocolType, ns3::Ptr device) [member function] - cls.add_method('RegisterProtocolHandler', 'void', [param('ns3::Callback< void, ns3::Ptr< ns3::NetDevice >, ns3::Ptr< ns3::Packet >, unsigned short, ns3::Address const&, ns3::empty, ns3::empty >', 'handler'), param('uint16_t', 'protocolType'), param('ns3::Ptr< ns3::NetDevice >', 'device')]) - ## node.h: void ns3::Node::UnregisterProtocolHandler(ns3::Callback, ns3::Ptr, unsigned short, ns3::Address const&, ns3::empty, ns3::empty> handler) [member function] - cls.add_method('UnregisterProtocolHandler', 'void', [param('ns3::Callback< void, ns3::Ptr< ns3::NetDevice >, ns3::Ptr< ns3::Packet >, unsigned short, ns3::Address const&, ns3::empty, ns3::empty >', 'handler')]) + ## node.h: void ns3::Node::RegisterProtocolHandler(ns3::Callback, ns3::Ptr, unsigned short, ns3::Address const&, ns3::Address const&, ns3::NetDevice::PacketType> handler, uint16_t protocolType, ns3::Ptr device) [member function] + cls.add_method('RegisterProtocolHandler', 'void', [param('ns3::Callback< void, ns3::Ptr< ns3::NetDevice >, ns3::Ptr< ns3::Packet >, unsigned short, ns3::Address const&, ns3::Address const&, ns3::NetDevice::PacketType >', 'handler'), param('uint16_t', 'protocolType'), param('ns3::Ptr< ns3::NetDevice >', 'device')]) + ## node.h: void ns3::Node::UnregisterProtocolHandler(ns3::Callback, ns3::Ptr, unsigned short, ns3::Address const&, ns3::Address const&, ns3::NetDevice::PacketType> handler) [member function] + cls.add_method('UnregisterProtocolHandler', 'void', [param('ns3::Callback< void, ns3::Ptr< ns3::NetDevice >, ns3::Ptr< ns3::Packet >, unsigned short, ns3::Address const&, ns3::Address const&, ns3::NetDevice::PacketType >', 'handler')]) + ## node.h: void ns3::Node::RegisterPromiscuousProtocolHandler(ns3::Callback,ns3::Ptr,short unsigned int,const ns3::Address&,const ns3::Address&,bool> handler, uint16_t protocolType, ns3::Ptr device) [member function] + cls.add_method('RegisterPromiscuousProtocolHandler', 'void', [param('ns3::Callback< void, ns3::Ptr< ns3::NetDevice >, ns3::Ptr< ns3::Packet >, short unsigned int, const ns3::Address&, const ns3::Address&, bool >', 'handler'), param('uint16_t', 'protocolType'), param('ns3::Ptr< ns3::NetDevice >', 'device')]) + ## node.h: void ns3::Node::UnregisterPromiscuousProtocolHandler(ns3::Callback,ns3::Ptr,short unsigned int,const ns3::Address&,const ns3::Address&,bool> handler) [member function] + cls.add_method('UnregisterPromiscuousProtocolHandler', 'void', [param('ns3::Callback< void, ns3::Ptr< ns3::NetDevice >, ns3::Ptr< ns3::Packet >, short unsigned int, const ns3::Address&, const ns3::Address&, bool >', 'handler')]) ## node.h: void ns3::Node::DoDispose() [member function] cls.add_method('DoDispose', 'void', [], visibility='protected', is_virtual=True) ## node.h: void ns3::Node::NotifyDeviceAdded(ns3::Ptr device) [member function] @@ -993,6 +969,23 @@ def register_Ns3TcpSocket_methods(root_module, cls): cls.add_method('GetDelAckMaxCount', 'uint32_t', [], is_pure_virtual=True, is_const=True, visibility='private', is_virtual=True) return +def register_Ns3Channel_methods(root_module, cls): + ## channel.h: static ns3::TypeId ns3::Channel::GetTypeId() [member function] + cls.add_method('GetTypeId', 'ns3::TypeId', [], is_static=True) + ## channel.h: ns3::Channel::Channel() [constructor] + cls.add_constructor([], visibility='public') + ## channel.h: ns3::Channel::Channel(std::string name) [constructor] + cls.add_constructor([param('std::string', 'name')], visibility='public') + ## channel.h: void ns3::Channel::SetName(std::string arg0) [member function] + cls.add_method('SetName', 'void', [param('std::string', 'arg0')]) + ## channel.h: std::string ns3::Channel::GetName() [member function] + cls.add_method('GetName', 'std::string', []) + ## channel.h: uint32_t ns3::Channel::GetNDevices() const [member function] + cls.add_method('GetNDevices', 'uint32_t', [], is_pure_virtual=True, is_const=True, is_virtual=True) + ## channel.h: ns3::Ptr ns3::Channel::GetDevice(uint32_t i) const [member function] + cls.add_method('GetDevice', 'ns3::Ptr< ns3::NetDevice >', [param('uint32_t', 'i')], is_pure_virtual=True, is_const=True, is_virtual=True) + return + def register_Ns3EthernetHeader_methods(root_module, cls): ## ethernet-header.h: ns3::EthernetHeader::EthernetHeader(bool hasPreamble) [constructor] cls.add_constructor([param('bool', 'hasPreamble')], visibility='public') @@ -1255,18 +1248,35 @@ def register_Ns3SimpleNetDevice_methods(root_module, cls): cls.add_method('IsPointToPoint', 'bool', [], is_const=True, is_virtual=True) ## simple-net-device.h: bool ns3::SimpleNetDevice::Send(ns3::Ptr packet, ns3::Address const & dest, uint16_t protocolNumber) [member function] cls.add_method('Send', 'bool', [param('ns3::Ptr< ns3::Packet >', 'packet'), param('ns3::Address&', 'dest', is_const=True), param('uint16_t', 'protocolNumber')], is_virtual=True) + ## simple-net-device.h: bool ns3::SimpleNetDevice::SendFrom(ns3::Ptr packet, ns3::Address const & source, ns3::Address const & dest, uint16_t protocolNumber) [member function] + cls.add_method('SendFrom', 'bool', [param('ns3::Ptr< ns3::Packet >', 'packet'), param('ns3::Address&', 'source', is_const=True), param('ns3::Address&', 'dest', is_const=True), param('uint16_t', 'protocolNumber')], is_virtual=True) ## simple-net-device.h: ns3::Ptr ns3::SimpleNetDevice::GetNode() const [member function] cls.add_method('GetNode', 'ns3::Ptr< ns3::Node >', [], is_const=True, is_virtual=True) ## simple-net-device.h: void ns3::SimpleNetDevice::SetNode(ns3::Ptr node) [member function] cls.add_method('SetNode', 'void', [param('ns3::Ptr< ns3::Node >', 'node')], is_virtual=True) ## simple-net-device.h: bool ns3::SimpleNetDevice::NeedsArp() const [member function] cls.add_method('NeedsArp', 'bool', [], is_const=True, is_virtual=True) - ## simple-net-device.h: void ns3::SimpleNetDevice::SetReceiveCallback(ns3::Callback, ns3::Ptr, unsigned short, ns3::Address const&, ns3::empty, ns3::empty> cb) [member function] - cls.add_method('SetReceiveCallback', 'void', [param('ns3::Callback< bool, ns3::Ptr< ns3::NetDevice >, ns3::Ptr< ns3::Packet >, unsigned short, ns3::Address const&, ns3::empty, ns3::empty >', 'cb')], is_virtual=True) + ## simple-net-device.h: void ns3::SimpleNetDevice::SetReceiveCallback(ns3::Callback, ns3::Ptr, unsigned short, ns3::Address const&, ns3::Address const&, ns3::NetDevice::PacketType> cb) [member function] + cls.add_method('SetReceiveCallback', 'void', [param('ns3::Callback< bool, ns3::Ptr< ns3::NetDevice >, ns3::Ptr< ns3::Packet >, unsigned short, ns3::Address const&, ns3::Address const&, ns3::NetDevice::PacketType >', 'cb')], is_virtual=True) ## simple-net-device.h: void ns3::SimpleNetDevice::DoDispose() [member function] cls.add_method('DoDispose', 'void', [], visibility='protected', is_virtual=True) return +def register_Ns3SimpleChannel_methods(root_module, cls): + ## simple-channel.h: static ns3::TypeId ns3::SimpleChannel::GetTypeId() [member function] + cls.add_method('GetTypeId', 'ns3::TypeId', [], is_static=True) + ## simple-channel.h: ns3::SimpleChannel::SimpleChannel() [constructor] + cls.add_constructor([], visibility='public') + ## simple-channel.h: void ns3::SimpleChannel::Send(ns3::Ptr p, uint16_t protocol, ns3::Mac48Address to, ns3::Mac48Address from, ns3::Ptr sender) [member function] + cls.add_method('Send', 'void', [param('ns3::Ptr< ns3::Packet >', 'p'), param('uint16_t', 'protocol'), param('ns3::Mac48Address', 'to'), param('ns3::Mac48Address', 'from'), param('ns3::Ptr< ns3::SimpleNetDevice >', 'sender')]) + ## simple-channel.h: void ns3::SimpleChannel::Add(ns3::Ptr device) [member function] + cls.add_method('Add', 'void', [param('ns3::Ptr< ns3::SimpleNetDevice >', 'device')]) + ## simple-channel.h: uint32_t ns3::SimpleChannel::GetNDevices() const [member function] + cls.add_method('GetNDevices', 'uint32_t', [], is_const=True, is_virtual=True) + ## simple-channel.h: ns3::Ptr ns3::SimpleChannel::GetDevice(uint32_t i) const [member function] + cls.add_method('GetDevice', 'ns3::Ptr< ns3::NetDevice >', [param('uint32_t', 'i')], is_const=True, is_virtual=True) + return + def register_Ns3TcpSocketFactory_methods(root_module, cls): ## tcp-socket-factory.h: static ns3::TypeId ns3::TcpSocketFactory::GetTypeId() [member function] cls.add_method('GetTypeId', 'ns3::TypeId', [], is_static=True) diff --git a/bindings/python/ns3_module_olsr.py b/bindings/python/ns3_module_olsr.py index 68089d125..0ff367f61 100644 --- a/bindings/python/ns3_module_olsr.py +++ b/bindings/python/ns3_module_olsr.py @@ -44,7 +44,7 @@ def register_types_ns3_olsr(module): root_module = module.get_root() ## olsr-header.h: ns3::olsr::MessageHeader [class] - module.add_class('MessageHeader', allow_subclassing=True, parent=root_module['ns3::Header']) + module.add_class('MessageHeader', parent=root_module['ns3::Header']) ## olsr-header.h: ns3::olsr::MessageHeader::MessageType [enumeration] module.add_enum('MessageType', ['HELLO_MESSAGE', 'TC_MESSAGE', 'MID_MESSAGE', 'HNA_MESSAGE'], outer_class=root_module['ns3::olsr::MessageHeader']) ## olsr-header.h: ns3::olsr::MessageHeader::Mid [struct] @@ -60,9 +60,9 @@ def register_types_ns3_olsr(module): ## olsr-header.h: ns3::olsr::MessageHeader::Hna::Association [struct] module.add_class('Association', outer_class=root_module['ns3::olsr::MessageHeader::Hna']) ## olsr-agent.h: ns3::olsr::Agent [class] - module.add_class('Agent', allow_subclassing=True, parent=root_module['ns3::Object']) + module.add_class('Agent', parent=root_module['ns3::Object']) ## olsr-header.h: ns3::olsr::PacketHeader [class] - module.add_class('PacketHeader', allow_subclassing=True, parent=root_module['ns3::Header']) + module.add_class('PacketHeader', parent=root_module['ns3::Header']) def register_methods(root_module): register_Ns3OlsrMessageHeader_methods(root_module, root_module['ns3::olsr::MessageHeader']) diff --git a/bindings/python/ns3_module_onoff.py b/bindings/python/ns3_module_onoff.py index 3bef4f8f3..08aa7d9ba 100644 --- a/bindings/python/ns3_module_onoff.py +++ b/bindings/python/ns3_module_onoff.py @@ -4,7 +4,7 @@ def register_types(module): root_module = module.get_root() ## onoff-application.h: ns3::OnOffApplication [class] - module.add_class('OnOffApplication', allow_subclassing=True, parent=root_module['ns3::Application']) + module.add_class('OnOffApplication', parent=root_module['ns3::Application']) ## Register a nested module for the namespace internal diff --git a/bindings/python/ns3_module_packet_sink.py b/bindings/python/ns3_module_packet_sink.py index 1f24781aa..81ff49dfb 100644 --- a/bindings/python/ns3_module_packet_sink.py +++ b/bindings/python/ns3_module_packet_sink.py @@ -4,7 +4,7 @@ def register_types(module): root_module = module.get_root() ## packet-sink.h: ns3::PacketSink [class] - module.add_class('PacketSink', allow_subclassing=True, parent=root_module['ns3::Application']) + module.add_class('PacketSink', parent=root_module['ns3::Application']) ## Register a nested module for the namespace internal diff --git a/bindings/python/ns3_module_point_to_point.py b/bindings/python/ns3_module_point_to_point.py index 1cb6892e9..ac6e8520c 100644 --- a/bindings/python/ns3_module_point_to_point.py +++ b/bindings/python/ns3_module_point_to_point.py @@ -4,9 +4,9 @@ def register_types(module): root_module = module.get_root() ## point-to-point-channel.h: ns3::PointToPointChannel [class] - module.add_class('PointToPointChannel', allow_subclassing=True, parent=root_module['ns3::Channel']) + module.add_class('PointToPointChannel', parent=root_module['ns3::Channel']) ## point-to-point-net-device.h: ns3::PointToPointNetDevice [class] - module.add_class('PointToPointNetDevice', allow_subclassing=True, parent=root_module['ns3::NetDevice']) + module.add_class('PointToPointNetDevice', parent=root_module['ns3::NetDevice']) ## Register a nested module for the namespace internal @@ -123,14 +123,16 @@ def register_Ns3PointToPointNetDevice_methods(root_module, cls): cls.add_method('IsPointToPoint', 'bool', [], is_const=True, is_virtual=True) ## point-to-point-net-device.h: bool ns3::PointToPointNetDevice::Send(ns3::Ptr packet, ns3::Address const & dest, uint16_t protocolNumber) [member function] cls.add_method('Send', 'bool', [param('ns3::Ptr< ns3::Packet >', 'packet'), param('ns3::Address&', 'dest', is_const=True), param('uint16_t', 'protocolNumber')], is_virtual=True) + ## point-to-point-net-device.h: bool ns3::PointToPointNetDevice::SendFrom(ns3::Ptr packet, ns3::Address const & source, ns3::Address const & dest, uint16_t protocolNumber) [member function] + cls.add_method('SendFrom', 'bool', [param('ns3::Ptr< ns3::Packet >', 'packet'), param('ns3::Address&', 'source', is_const=True), param('ns3::Address&', 'dest', is_const=True), param('uint16_t', 'protocolNumber')], is_virtual=True) ## point-to-point-net-device.h: ns3::Ptr ns3::PointToPointNetDevice::GetNode() const [member function] cls.add_method('GetNode', 'ns3::Ptr< ns3::Node >', [], is_const=True, is_virtual=True) ## point-to-point-net-device.h: void ns3::PointToPointNetDevice::SetNode(ns3::Ptr node) [member function] cls.add_method('SetNode', 'void', [param('ns3::Ptr< ns3::Node >', 'node')], is_virtual=True) ## point-to-point-net-device.h: bool ns3::PointToPointNetDevice::NeedsArp() const [member function] cls.add_method('NeedsArp', 'bool', [], is_const=True, is_virtual=True) - ## point-to-point-net-device.h: void ns3::PointToPointNetDevice::SetReceiveCallback(ns3::Callback, ns3::Ptr, unsigned short, ns3::Address const&, ns3::empty, ns3::empty> cb) [member function] - cls.add_method('SetReceiveCallback', 'void', [param('ns3::Callback< bool, ns3::Ptr< ns3::NetDevice >, ns3::Ptr< ns3::Packet >, unsigned short, ns3::Address const&, ns3::empty, ns3::empty >', 'cb')], is_virtual=True) + ## point-to-point-net-device.h: void ns3::PointToPointNetDevice::SetReceiveCallback(ns3::Callback, ns3::Ptr, unsigned short, ns3::Address const&, ns3::Address const&, ns3::NetDevice::PacketType> cb) [member function] + cls.add_method('SetReceiveCallback', 'void', [param('ns3::Callback< bool, ns3::Ptr< ns3::NetDevice >, ns3::Ptr< ns3::Packet >, unsigned short, ns3::Address const&, ns3::Address const&, ns3::NetDevice::PacketType >', 'cb')], is_virtual=True) ## point-to-point-net-device.h: void ns3::PointToPointNetDevice::DoDispose() [member function] cls.add_method('DoDispose', 'void', [], visibility='private', is_virtual=True) return diff --git a/bindings/python/ns3_module_simulator.py b/bindings/python/ns3_module_simulator.py index c06e3b783..9c837f9d0 100644 --- a/bindings/python/ns3_module_simulator.py +++ b/bindings/python/ns3_module_simulator.py @@ -28,17 +28,17 @@ def register_types(module): ## nstime.h: ns3::TimeChecker [class] module.add_class('TimeChecker', parent=root_module['ns3::AttributeChecker']) ## scheduler.h: ns3::Scheduler [class] - module.add_class('Scheduler', allow_subclassing=True, parent=root_module['ns3::Object']) + module.add_class('Scheduler', parent=root_module['ns3::Object']) ## scheduler.h: ns3::Scheduler::EventKey [struct] module.add_class('EventKey', outer_class=root_module['ns3::Scheduler']) ## nstime.h: ns3::TimeValue [class] - module.add_class('TimeValue', allow_subclassing=True, parent=root_module['ns3::AttributeValue']) + module.add_class('TimeValue', parent=root_module['ns3::AttributeValue']) ## heap-scheduler.h: ns3::HeapScheduler [class] - module.add_class('HeapScheduler', allow_subclassing=True, parent=root_module['ns3::Scheduler']) + module.add_class('HeapScheduler', parent=root_module['ns3::Scheduler']) ## list-scheduler.h: ns3::ListScheduler [class] - module.add_class('ListScheduler', allow_subclassing=True, parent=root_module['ns3::Scheduler']) + module.add_class('ListScheduler', parent=root_module['ns3::Scheduler']) ## map-scheduler.h: ns3::MapScheduler [class] - module.add_class('MapScheduler', allow_subclassing=True, parent=root_module['ns3::Scheduler']) + module.add_class('MapScheduler', parent=root_module['ns3::Scheduler']) ## Register a nested module for the namespace internal diff --git a/bindings/python/ns3_module_udp_echo.py b/bindings/python/ns3_module_udp_echo.py index d7b9b7aae..91c273684 100644 --- a/bindings/python/ns3_module_udp_echo.py +++ b/bindings/python/ns3_module_udp_echo.py @@ -4,9 +4,9 @@ def register_types(module): root_module = module.get_root() ## udp-echo-client.h: ns3::UdpEchoClient [class] - module.add_class('UdpEchoClient', allow_subclassing=True, parent=root_module['ns3::Application']) + module.add_class('UdpEchoClient', parent=root_module['ns3::Application']) ## udp-echo-server.h: ns3::UdpEchoServer [class] - module.add_class('UdpEchoServer', allow_subclassing=True, parent=root_module['ns3::Application']) + module.add_class('UdpEchoServer', parent=root_module['ns3::Application']) ## Register a nested module for the namespace internal diff --git a/bindings/python/ns3_module_wifi.py b/bindings/python/ns3_module_wifi.py index 4348d8129..ff93b16c9 100644 --- a/bindings/python/ns3_module_wifi.py +++ b/bindings/python/ns3_module_wifi.py @@ -16,15 +16,15 @@ def register_types(module): ## supported-rates.h: ns3::SupportedRates [class] module.add_class('SupportedRates') ## ideal-wifi-manager.h: ns3::IdealWifiRemoteStation [class] - module.add_class('IdealWifiRemoteStation', allow_subclassing=True, parent=root_module['ns3::WifiRemoteStation']) + module.add_class('IdealWifiRemoteStation', parent=root_module['ns3::WifiRemoteStation']) ## wifi-mode.h: ns3::WifiModeChecker [class] module.add_class('WifiModeChecker', parent=root_module['ns3::AttributeChecker']) ## wifi-mode.h: ns3::WifiModeFactory [class] module.add_class('WifiModeFactory') ## onoe-wifi-manager.h: ns3::OnoeWifiRemoteStation [class] - module.add_class('OnoeWifiRemoteStation', allow_subclassing=True, parent=root_module['ns3::WifiRemoteStation']) + module.add_class('OnoeWifiRemoteStation', parent=root_module['ns3::WifiRemoteStation']) ## rraa-wifi-manager.h: ns3::RraaWifiRemoteStation [class] - module.add_class('RraaWifiRemoteStation', allow_subclassing=True, parent=root_module['ns3::WifiRemoteStation']) + module.add_class('RraaWifiRemoteStation', parent=root_module['ns3::WifiRemoteStation']) ## ssid.h: ns3::Ssid [class] module.add_class('Ssid') ## wifi-mode.h: ns3::WifiMode [class] @@ -32,69 +32,69 @@ def register_types(module): ## wifi-mode.h: ns3::WifiMode::ModulationType [enumeration] module.add_enum('ModulationType', ['BPSK', 'QAM'], outer_class=root_module['ns3::WifiMode']) ## ssid.h: ns3::SsidValue [class] - module.add_class('SsidValue', allow_subclassing=True, parent=root_module['ns3::AttributeValue']) + module.add_class('SsidValue', parent=root_module['ns3::AttributeValue']) ## ssid.h: ns3::SsidChecker [class] module.add_class('SsidChecker', parent=root_module['ns3::AttributeChecker']) ## constant-rate-wifi-manager.h: ns3::ConstantRateWifiRemoteStation [class] - module.add_class('ConstantRateWifiRemoteStation', allow_subclassing=True, parent=root_module['ns3::WifiRemoteStation']) + module.add_class('ConstantRateWifiRemoteStation', parent=root_module['ns3::WifiRemoteStation']) ## propagation-loss-model.h: ns3::PropagationLossModel [class] - module.add_class('PropagationLossModel', allow_subclassing=True, parent=root_module['ns3::Object']) + module.add_class('PropagationLossModel', parent=root_module['ns3::Object']) ## arf-wifi-manager.h: ns3::ArfWifiRemoteStation [class] - module.add_class('ArfWifiRemoteStation', allow_subclassing=True, parent=root_module['ns3::WifiRemoteStation']) + module.add_class('ArfWifiRemoteStation', parent=root_module['ns3::WifiRemoteStation']) ## wifi-mac.h: ns3::WifiMac [class] - module.add_class('WifiMac', allow_subclassing=True, parent=root_module['ns3::Object']) + module.add_class('WifiMac', parent=root_module['ns3::Object']) ## nqap-wifi-mac.h: ns3::NqapWifiMac [class] - module.add_class('NqapWifiMac', allow_subclassing=True, parent=root_module['ns3::WifiMac']) + module.add_class('NqapWifiMac', parent=root_module['ns3::WifiMac']) ## amrr-wifi-manager.h: ns3::AmrrWifiRemoteStation [class] - module.add_class('AmrrWifiRemoteStation', allow_subclassing=True, parent=root_module['ns3::WifiRemoteStation']) + module.add_class('AmrrWifiRemoteStation', parent=root_module['ns3::WifiRemoteStation']) ## composite-propagation-loss-model.h: ns3::CompositePropagationLossModel [class] - module.add_class('CompositePropagationLossModel', allow_subclassing=True, parent=root_module['ns3::PropagationLossModel']) + module.add_class('CompositePropagationLossModel', parent=root_module['ns3::PropagationLossModel']) ## propagation-loss-model.h: ns3::FriisPropagationLossModel [class] - module.add_class('FriisPropagationLossModel', allow_subclassing=True, parent=root_module['ns3::PropagationLossModel']) + module.add_class('FriisPropagationLossModel', parent=root_module['ns3::PropagationLossModel']) ## wifi-remote-station-manager.h: ns3::WifiRemoteStationManager [class] - module.add_class('WifiRemoteStationManager', allow_subclassing=True, parent=root_module['ns3::Object']) + module.add_class('WifiRemoteStationManager', parent=root_module['ns3::Object']) ## wifi-mode.h: ns3::WifiModeValue [class] - module.add_class('WifiModeValue', allow_subclassing=True, parent=root_module['ns3::AttributeValue']) + module.add_class('WifiModeValue', parent=root_module['ns3::AttributeValue']) ## onoe-wifi-manager.h: ns3::OnoeWifiManager [class] - module.add_class('OnoeWifiManager', allow_subclassing=True, parent=root_module['ns3::WifiRemoteStationManager']) + module.add_class('OnoeWifiManager', parent=root_module['ns3::WifiRemoteStationManager']) ## wifi-phy.h: ns3::WifiPhy [class] - module.add_class('WifiPhy', allow_subclassing=True, parent=root_module['ns3::Object']) + module.add_class('WifiPhy', parent=root_module['ns3::Object']) ## wifi-phy.h: ns3::WifiPhy::State [enumeration] module.add_enum('State', ['SYNC', 'TX', 'CCA_BUSY', 'IDLE'], outer_class=root_module['ns3::WifiPhy']) ## wifi-channel.h: ns3::WifiChannel [class] - module.add_class('WifiChannel', allow_subclassing=True, parent=root_module['ns3::Channel']) + module.add_class('WifiChannel', parent=root_module['ns3::Channel']) ## propagation-loss-model.h: ns3::LogDistancePropagationLossModel [class] - module.add_class('LogDistancePropagationLossModel', allow_subclassing=True, parent=root_module['ns3::PropagationLossModel']) + module.add_class('LogDistancePropagationLossModel', parent=root_module['ns3::PropagationLossModel']) ## constant-rate-wifi-manager.h: ns3::ConstantRateWifiManager [class] - module.add_class('ConstantRateWifiManager', allow_subclassing=True, parent=root_module['ns3::WifiRemoteStationManager']) + module.add_class('ConstantRateWifiManager', parent=root_module['ns3::WifiRemoteStationManager']) ## aarf-wifi-manager.h: ns3::AarfWifiRemoteStation [class] - module.add_class('AarfWifiRemoteStation', allow_subclassing=True, parent=root_module['ns3::ArfWifiRemoteStation']) + module.add_class('AarfWifiRemoteStation', parent=root_module['ns3::ArfWifiRemoteStation']) ## propagation-delay-model.h: ns3::PropagationDelayModel [class] - module.add_class('PropagationDelayModel', allow_subclassing=True, parent=root_module['ns3::Object']) + module.add_class('PropagationDelayModel', parent=root_module['ns3::Object']) ## adhoc-wifi-mac.h: ns3::AdhocWifiMac [class] - module.add_class('AdhocWifiMac', allow_subclassing=True, parent=root_module['ns3::WifiMac']) + module.add_class('AdhocWifiMac', parent=root_module['ns3::WifiMac']) ## jakes-propagation-loss-model.h: ns3::JakesPropagationLossModel [class] - module.add_class('JakesPropagationLossModel', allow_subclassing=True, parent=root_module['ns3::PropagationLossModel']) + module.add_class('JakesPropagationLossModel', parent=root_module['ns3::PropagationLossModel']) ## propagation-delay-model.h: ns3::ConstantSpeedPropagationDelayModel [class] - module.add_class('ConstantSpeedPropagationDelayModel', allow_subclassing=True, parent=root_module['ns3::PropagationDelayModel']) + module.add_class('ConstantSpeedPropagationDelayModel', parent=root_module['ns3::PropagationDelayModel']) ## wifi-net-device.h: ns3::WifiNetDevice [class] - module.add_class('WifiNetDevice', allow_subclassing=True, parent=root_module['ns3::NetDevice']) + module.add_class('WifiNetDevice', parent=root_module['ns3::NetDevice']) ## nqsta-wifi-mac.h: ns3::NqstaWifiMac [class] - module.add_class('NqstaWifiMac', allow_subclassing=True, parent=root_module['ns3::WifiMac']) + module.add_class('NqstaWifiMac', parent=root_module['ns3::WifiMac']) ## propagation-loss-model.h: ns3::RandomPropagationLossModel [class] - module.add_class('RandomPropagationLossModel', allow_subclassing=True, parent=root_module['ns3::PropagationLossModel']) + module.add_class('RandomPropagationLossModel', parent=root_module['ns3::PropagationLossModel']) ## propagation-delay-model.h: ns3::RandomPropagationDelayModel [class] - module.add_class('RandomPropagationDelayModel', allow_subclassing=True, parent=root_module['ns3::PropagationDelayModel']) + module.add_class('RandomPropagationDelayModel', parent=root_module['ns3::PropagationDelayModel']) ## amrr-wifi-manager.h: ns3::AmrrWifiManager [class] - module.add_class('AmrrWifiManager', allow_subclassing=True, parent=root_module['ns3::WifiRemoteStationManager']) + module.add_class('AmrrWifiManager', parent=root_module['ns3::WifiRemoteStationManager']) ## rraa-wifi-manager.h: ns3::RraaWifiManager [class] - module.add_class('RraaWifiManager', allow_subclassing=True, parent=root_module['ns3::WifiRemoteStationManager']) + module.add_class('RraaWifiManager', parent=root_module['ns3::WifiRemoteStationManager']) ## ideal-wifi-manager.h: ns3::IdealWifiManager [class] - module.add_class('IdealWifiManager', allow_subclassing=True, parent=root_module['ns3::WifiRemoteStationManager']) + module.add_class('IdealWifiManager', parent=root_module['ns3::WifiRemoteStationManager']) ## arf-wifi-manager.h: ns3::ArfWifiManager [class] - module.add_class('ArfWifiManager', allow_subclassing=True, parent=root_module['ns3::WifiRemoteStationManager']) + module.add_class('ArfWifiManager', parent=root_module['ns3::WifiRemoteStationManager']) ## aarf-wifi-manager.h: ns3::AarfWifiManager [class] - module.add_class('AarfWifiManager', allow_subclassing=True, parent=root_module['ns3::ArfWifiManager']) + module.add_class('AarfWifiManager', parent=root_module['ns3::ArfWifiManager']) ## Register a nested module for the namespace internal @@ -1067,14 +1067,16 @@ def register_Ns3WifiNetDevice_methods(root_module, cls): cls.add_method('IsPointToPoint', 'bool', [], is_const=True, is_virtual=True) ## wifi-net-device.h: bool ns3::WifiNetDevice::Send(ns3::Ptr packet, ns3::Address const & dest, uint16_t protocolNumber) [member function] cls.add_method('Send', 'bool', [param('ns3::Ptr< ns3::Packet >', 'packet'), param('ns3::Address&', 'dest', is_const=True), param('uint16_t', 'protocolNumber')], is_virtual=True) + ## wifi-net-device.h: bool ns3::WifiNetDevice::SendFrom(ns3::Ptr packet, ns3::Address const & src, ns3::Address const & dest, uint16_t protocolNumber) [member function] + cls.add_method('SendFrom', 'bool', [param('ns3::Ptr< ns3::Packet >', 'packet'), param('ns3::Address&', 'src', is_const=True), param('ns3::Address&', 'dest', is_const=True), param('uint16_t', 'protocolNumber')], is_virtual=True) ## wifi-net-device.h: ns3::Ptr ns3::WifiNetDevice::GetNode() const [member function] cls.add_method('GetNode', 'ns3::Ptr< ns3::Node >', [], is_const=True, is_virtual=True) ## wifi-net-device.h: void ns3::WifiNetDevice::SetNode(ns3::Ptr node) [member function] cls.add_method('SetNode', 'void', [param('ns3::Ptr< ns3::Node >', 'node')], is_virtual=True) ## wifi-net-device.h: bool ns3::WifiNetDevice::NeedsArp() const [member function] cls.add_method('NeedsArp', 'bool', [], is_const=True, is_virtual=True) - ## wifi-net-device.h: void ns3::WifiNetDevice::SetReceiveCallback(ns3::Callback, ns3::Ptr, unsigned short, ns3::Address const&, ns3::empty, ns3::empty> cb) [member function] - cls.add_method('SetReceiveCallback', 'void', [param('ns3::Callback< bool, ns3::Ptr< ns3::NetDevice >, ns3::Ptr< ns3::Packet >, unsigned short, ns3::Address const&, ns3::empty, ns3::empty >', 'cb')], is_virtual=True) + ## wifi-net-device.h: void ns3::WifiNetDevice::SetReceiveCallback(ns3::Callback, ns3::Ptr, unsigned short, ns3::Address const&, ns3::Address const&, ns3::NetDevice::PacketType> cb) [member function] + cls.add_method('SetReceiveCallback', 'void', [param('ns3::Callback< bool, ns3::Ptr< ns3::NetDevice >, ns3::Ptr< ns3::Packet >, unsigned short, ns3::Address const&, ns3::Address const&, ns3::NetDevice::PacketType >', 'cb')], is_virtual=True) ## wifi-net-device.h: void ns3::WifiNetDevice::DoDispose() [member function] cls.add_method('DoDispose', 'void', [], visibility='private', is_virtual=True) return diff --git a/bindings/python/ns3modulegen_generated.py b/bindings/python/ns3modulegen_generated.py index ad3e8d947..2e700fe0d 100644 --- a/bindings/python/ns3modulegen_generated.py +++ b/bindings/python/ns3modulegen_generated.py @@ -22,6 +22,7 @@ import ns3_module_point_to_point import ns3_module_internet_stack import ns3_module_wifi import ns3_module_csma +import ns3_module_bridge import ns3_module_packet_sink import ns3_module_global_routing import ns3_module_onoff @@ -146,6 +147,17 @@ def register_types(module): ns3_module_csma__local.register_types(module) root_module.end_section('ns3_module_csma') + root_module.begin_section('ns3_module_bridge') + ns3_module_bridge.register_types(module) + + try: + import ns3_module_bridge__local + except ImportError: + pass + else: + ns3_module_bridge__local.register_types(module) + + root_module.end_section('ns3_module_bridge') root_module.begin_section('ns3_module_packet_sink') ns3_module_packet_sink.register_types(module) @@ -364,6 +376,17 @@ def register_methods(root_module): ns3_module_csma__local.register_methods(root_module) root_module.end_section('ns3_module_csma') + root_module.begin_section('ns3_module_bridge') + ns3_module_bridge.register_methods(root_module) + + try: + import ns3_module_bridge__local + except ImportError: + pass + else: + ns3_module_bridge__local.register_methods(root_module) + + root_module.end_section('ns3_module_bridge') root_module.begin_section('ns3_module_packet_sink') ns3_module_packet_sink.register_methods(root_module) @@ -544,6 +567,17 @@ def register_functions(root_module): ns3_module_csma__local.register_functions(root_module) root_module.end_section('ns3_module_csma') + root_module.begin_section('ns3_module_bridge') + ns3_module_bridge.register_functions(root_module) + + try: + import ns3_module_bridge__local + except ImportError: + pass + else: + ns3_module_bridge__local.register_functions(root_module) + + root_module.end_section('ns3_module_bridge') root_module.begin_section('ns3_module_packet_sink') ns3_module_packet_sink.register_functions(root_module) From 2ca65219dea8d24fc063d8e91232f12f971e2074 Mon Sep 17 00:00:00 2001 From: "Gustavo J. A. M. Carneiro" Date: Mon, 14 Jul 2008 15:41:51 +0100 Subject: [PATCH 171/495] Add csma-bridge example ported to Python. --- examples/csma-bridge.py | 155 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 155 insertions(+) create mode 100644 examples/csma-bridge.py diff --git a/examples/csma-bridge.py b/examples/csma-bridge.py new file mode 100644 index 000000000..b5778fea0 --- /dev/null +++ b/examples/csma-bridge.py @@ -0,0 +1,155 @@ +# /* +# * 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 +# */ + +# Network topology +# +# n0 n1 +# | | +# ---------- +# | Switch | +# ---------- +# | | +# n2 n3 +# +# +# - CBR/UDP flows from n0 to n1 and from n3 to n0 +# - DropTail queues +# - Tracing of queues and packet receptions to file "csma-bridge.tr" + +import ns3 + + +def main(argv): + # + # Make the random number generators generate reproducible results. + # + ns3.RandomVariable.UseGlobalSeed(1, 1, 2, 3, 5, 8) + + # + # Allow the user to override any of the defaults and the above Bind() at + # run-time, via command-line arguments + # + cmd = ns3.CommandLine() + cmd.Parse(argv) + + # + # Explicitly create the nodes required by the topology(shown above). + # + print "Create nodes." + terminals = ns3.NodeContainer() + terminals.Create(4) + + csmaSwitch = ns3.NodeContainer() + csmaSwitch.Create(1) + + print "Build Topology" + csma = ns3.CsmaHelper() + csma.SetChannelAttribute("DataRate", ns3.DataRateValue(ns3.DataRate(5000000))) + csma.SetChannelAttribute("Delay", ns3.TimeValue(ns3.MilliSeconds(2))) + + # Create the csma links, from each terminal to the switch + + terminalDevices = ns3.NetDeviceContainer() + switchDevices = ns3.NetDeviceContainer() + + for i in range(4): + link = csma.Install(ns3.NodeContainer(ns3.NodeContainer(terminals.Get(i)), csmaSwitch)) + terminalDevices.Add(link.Get(0)) + switchDevices.Add(link.Get(1)) + + # Create the bridge netdevice, which will do the packet switching + switchNode = csmaSwitch.Get(0) + bridgeDevice = ns3.BridgeNetDevice() + switchNode.AddDevice(bridgeDevice) + + for portIter in range(switchDevices.GetN()): + bridgeDevice.AddBridgePort(switchDevices.Get(portIter)) + + # Add internet stack to the terminals + internet = ns3.InternetStackHelper() + internet.Install(terminals) + + # We've got the "hardware" in place. Now we need to add IP addresses. + # + print "Assign IP Addresses." + ipv4 = ns3.Ipv4AddressHelper() + ipv4.SetBase(ns3.Ipv4Address("10.1.1.0"), ns3.Ipv4Mask("255.255.255.0")) + ipv4.Assign(terminalDevices) + + # + # Create an OnOff application to send UDP datagrams from node zero to node 1. + # + print "Create Applications." + port = 9 # Discard port(RFC 863) + + onoff = ns3.OnOffHelper("ns3::UdpSocketFactory", + ns3.Address(ns3.InetSocketAddress(ns3.Ipv4Address("10.1.1.2"), port))) + onoff.SetAttribute("OnTime", ns3.RandomVariableValue(ns3.ConstantVariable(1))) + onoff.SetAttribute("OffTime", ns3.RandomVariableValue(ns3.ConstantVariable(0))) + + app = onoff.Install(ns3.NodeContainer(terminals.Get(0))) + # Start the application + app.Start(ns3.Seconds(1.0)) + app.Stop(ns3.Seconds(10.0)) + + # Create an optional packet sink to receive these packets + sink = ns3.PacketSinkHelper("ns3::UdpSocketFactory", + ns3.Address(ns3.InetSocketAddress(ns3.Ipv4Address.GetAny(), port))) + sink.Install(ns3.NodeContainer(terminals.Get(1))) + + # + # Create a similar flow from n3 to n0, starting at time 1.1 seconds + # + onoff.SetAttribute("Remote", + ns3.AddressValue(ns3.InetSocketAddress(ns3.Ipv4Address("10.1.1.1"), port))) + app2 = onoff.Install(ns3.NodeContainer(terminals.Get(3))) + + sink.Install(ns3.NodeContainer(terminals.Get(0))) + + app2.Start(ns3.Seconds(1.1)) + app2.Stop(ns3.Seconds(10.0)) + + # + # Configure tracing of all enqueue, dequeue, and NetDevice receive events. + # Trace output will be sent to the file "csma-bridge.tr" + # + #print "Configure Tracing." + #std.ofstream ascii + #ascii.open("csma-bridge.tr") + #CsmaHelper.EnableAsciiAll(ascii) + + # + # Also configure some tcpdump traces; each interface will be traced. + # The output files will be named: + # csma-bridge.pcap-- + # and can be read by the "tcpdump -r" command(use "-tt" option to + # display timestamps correctly) + # + ns3.CsmaHelper.EnablePcapAll("csma-bridge") + + # + # Now, do the actual simulation. + # + print "Run Simulation." + ns3.Simulator.Run() + ns3.Simulator.Destroy() + print "Done." + + + +if __name__ == '__main__': + import sys + main(sys.argv) + From db748a0000c57e60c6ff4762f8d4eb2c79d18e65 Mon Sep 17 00:00:00 2001 From: Craig Dowell Date: Tue, 15 Jul 2008 15:59:57 -0700 Subject: [PATCH 172/495] add system threads and synchronization primitives --- src/core/system-condition.h | 106 +++++++++++++++ src/core/system-mutex.h | 120 +++++++++++++++++ src/core/system-thread.h | 156 ++++++++++++++++++++++ src/core/unix-system-condition.cc | 212 ++++++++++++++++++++++++++++++ src/core/unix-system-mutex.cc | 131 ++++++++++++++++++ src/core/unix-system-thread.cc | 138 +++++++++++++++++++ src/core/wscript | 16 ++- 7 files changed, 877 insertions(+), 2 deletions(-) create mode 100644 src/core/system-condition.h create mode 100644 src/core/system-mutex.h create mode 100644 src/core/system-thread.h create mode 100644 src/core/unix-system-condition.cc create mode 100644 src/core/unix-system-mutex.cc create mode 100644 src/core/unix-system-thread.cc diff --git a/src/core/system-condition.h b/src/core/system-condition.h new file mode 100644 index 000000000..eb3d78b0e --- /dev/null +++ b/src/core/system-condition.h @@ -0,0 +1,106 @@ +/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ +/* + * Copyright (c) 2008 University of Washington + * + * 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 + */ + +#ifndef SYSTEM_CONDITION_H +#define SYSTEM_CONDITION_H + +#include "ptr.h" + +namespace ns3 { + +class SystemConditionPrivate; + +/** + * @brief A class which provides a relatively platform-independent + * conditional-wait thread synchronization primitive. + * + * It is often desirable to have a mechanism by which a thread can suspend its + * execution and relinquish the process until some condition to becomes true. + * We provide platform-independent access to this OS-dependent capability with + * the SystemCondition class. + * + * There are two ways to tell the underlying primitive that the condition has + * become true: Signal and Broadcast. Signal will only wake up one thread + * waiting on the condition (according to the OS scheduling policy); + * Broadcast will wake up all of the threads waiting on the condition + * (cf. "The Thundering Herd"). + * + * In order to wait for the underlying condition, you also have two + * alternatives: Wait and TimedWait. The Wait call will wait forever for the + * condition to become true; but the TimedWait has a timeout. + * + * The condition underlying this class is a simple boolean variable. It is + * set to false in each call to Wait and TimedWait. It is set to true in each + * call to Signal and Broadcast. This is a fairly simple-minded condition + * designed for + * + * A typical use case will be to call Wait() or TimedWait() in one thread + * context and put the processor to sleep until an event happens somewhere + * else that + */ +class SystemCondition +{ +public: + SystemCondition (); + ~SystemCondition (); + + /** + * Set the value of the underlying condition. + */ + void SetCondition (bool condition); + + /** + * Get the value of the underlying condition. + */ + bool GetCondition (void); + + /** + * Release one thread if waiting for the condition to be true. If you want + * a waiting thread to return, you should have done a SetCondition (true) + * prior to calling. + */ + void Signal (void); + + /** + * Release all threads waiting for the condition to be true. If you want + * all waiting threads to return, you should have done a SetCondition (true) + * prior to calling. + */ + void Broadcast (void); + + /** + * Wait, possibly forever, for the condition to be true. + */ + void Wait (void); + + /** + * Wait a maximum of ns nanoseconds for the condition to be true. If the + * wait times out, return true else return false. + */ + bool TimedWait (uint64_t ns); + + +private: + SystemConditionPrivate * m_priv; +}; + +} //namespace ns3 + +#endif /* SYSTEM_CONDITION_H */ + + diff --git a/src/core/system-mutex.h b/src/core/system-mutex.h new file mode 100644 index 000000000..2bb411ab0 --- /dev/null +++ b/src/core/system-mutex.h @@ -0,0 +1,120 @@ +/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ +/* + * Copyright (c) 2008 INRIA + * + * 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 + * + * Author: Mathieu Lacage + */ + +#ifndef SYSTEM_MUTEX_H +#define SYSTEM_MUTEX_H + +#include "ptr.h" + +namespace ns3 { + +class SystemMutexPrivate; + +/** + * @brief A class which provides a relatively platform-independent Mutual + * Exclusion thread synchronization primitive. + * + * When more than one thread needs to access a shared resource (data structure + * or device), the system needs to provide a way to serialize access to the + * resource. An operating system will typically provide a Mutual Exclusion + * primitive to provide that capability. We provide plattorm-independent + * access to the OS-dependent capability with the SystemMutex class. + * + * There are two operations: Lock and Unlock. Lock allows an executing + * SystemThread to attempt to acquire ownership of the Mutual Exclusion + * object. If the SystemMutex object is not owned by another thread, then + * ownership is granted to the calling SystemThread and Lock returns + * immediately, However, if the SystemMutex is already owned by another + * SystemThread, the calling SystemThread is blocked until the current owner + * releases the SystemMutex by calling Unlock. + * + * @see CriticalSection + */ +class SystemMutex +{ +public: + SystemMutex (); + ~SystemMutex (); + + /** + * Acquire ownership of the Mutual Exclusion object. + */ + void Lock (); + + /** + * Release ownership of the Mutual Exclusion object. + */ + void Unlock (); + +private: + SystemMutexPrivate * m_priv; +}; + +/** + * @brief A class which provides a simple way to implement a Critical Section. + * + * When more than one SystemThread needs to access a shared resource, we + * conrol access by acquiring a SystemMutex. The CriticalSection class uses + * the C++ scoping rules to automatically perform the required Lock and Unlock + * operations to implement a Critical Section. + * + * If one wants to treat an entire method call as a critical section, one would + * do something like, + * + * Class::Method () + * { + * CriticalSection cs (mutex); + * ... + * } + * + * In this case, the critical section is entered when the CriticalSection + * object is created, and the critical section is exited when the + * CriticalSection object goes out of scope at the end of the method. + * + * Finer granularity is achieved by using local scope blocks. + * + * Class::Method () + * { + * ... + * { + * CriticalSection cs (mutex); + * } + * ... + * } + * + * Here, the critical section is entered partway through the method when the + * CriticalSection object is created in the local scope block (the braces). + * The critical section is exited when the CriticalSection object goes out of + * scope at the end of block. + * + * @see SystemMutex + */ +class CriticalSection +{ +public: + CriticalSection (SystemMutex &mutex); + ~CriticalSection (); +private: + SystemMutex &m_mutex; +}; + +} //namespace ns3 + +#endif /* SYSTEM_MUTEX_H */ diff --git a/src/core/system-thread.h b/src/core/system-thread.h new file mode 100644 index 000000000..2ec613b40 --- /dev/null +++ b/src/core/system-thread.h @@ -0,0 +1,156 @@ +/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ +/* + * Copyright (c) 2008 INRIA + * + * 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 + * + * Author: Mathieu Lacage + */ + +#ifndef SYSTEM_THREAD_H +#define SYSTEM_THREAD_H + +#include "callback.h" + +namespace ns3 { + +class SystemThreadImpl; + +/** + * @brief A class which provides a relatively platform-independent thread + * primitive. + * + * This class allows for creation of multiple threads of execution in a + * process. The exact implementation of the thread functionality is + * operating system dependent, but typically in ns-3 one is using an + * environment in which Posix Threads are supported (either navively or + * in the case of Windows via Cygwin's implementation of pthreads on the + * Win32 API. In either case we expect that these will be kernel-level + * threads and therefore a system with multiple CPUs will see truly concurrent + * execution. + * + * Synchronization between threads is provided via the SystemMutex class. + */ +class SystemThread +{ +public: + /** + * @brief Create a SystemThread object. + * + * A system thread object is not created running. A thread of execution + * must be explicitly started by calling the Start method. When the + * Start method is called, it will spawn a thread of execution and cause + * that thread to call out into the callback function provided here as + * a parameter. + * + * Like all ns-3 callbacks, the provided callback may refer to a function + * or a method of an object depending on how the MakeCallback function is + * used. + * + * The most common use is expected to be creating a thread of execution in + * a method. In this case you would use code similar to, + * + * MyClass myObject; + * Ptr st = Create ( + * MakeCallback (&MyClass::MyMethod, &myObject)); + * st->Start (); + * + * The SystemThread is passed a callback that calls out to the function + * MyClass::MyMethod. When this function is called, it is called as an + * object method on the myObject object. Essentially what you are doing + * is asking the SystemThread to call object->MyMethod () in a new thread + * of execution. + * + * Remember that if you are invoking a callback on an object that is + * managed by a smart pointer, you need to call PeekPointer. + * + * Ptr myPtr = Create (); + * Ptr st = Create ( + * MakeCallback (&MyClass::MyMethod, PeekPointer (myPtr))); + * st->Start (); + * + * Just like any thread, you can synchronize with its termination. The + * method provided to do this is Join (). If you call Join() you will block + * until the SystemThread run method returns. + * + * @warning I've made the system thread class look like a normal ns3 object + * with smart pointers, and living in the heap. This makes it very easy to + * manage threads from a single master thread context. You should be very + * aware though that I have not made Ptr multithread safe! This means that + * if you pass Ptr around in a multithreaded environment, it is + * possible that the reference count will get messed up since it is not an + * atomic operation. CREATE AND MANAGE YOUR THREADS IN ONE PLACE -- LEAVE + * THE PTR THERE. + */ + SystemThread(Callback callback); + + /** + * @brief Destroy a SystemThread object. + * + */ + ~SystemThread(); + + /** + * Increment the reference count. This method should not be called + * by user code. Object instances are expected to be used in conjunction + * of the Ptr template which would make calling Ref unecessary and + * dangerous. + */ + inline void Ref (void) const; + + /** + * Decrement the reference count. This method should not be called + * by user code. Object instances are expected to be used in conjunction + * of the Ptr template which would make calling Ref unecessary and + * dangerous. + */ + inline void Unref (void) const; + + /** + * @brief Start a thread of execution, running the provided callback. + */ + void Start (void); + + /** + * @brief Suspend the caller until the thread of execution, running the + * provided callback, finishes. + */ + void Join (void); + +private: + SystemThreadImpl * m_impl; + mutable uint32_t m_count; +}; + + void +SystemThread::Ref (void) const +{ + m_count++; +} + + void +SystemThread::Unref (void) const +{ + m_count--; + if (m_count == 0) + { + delete this; + } +} + +} //namespace ns3 + +#endif /* SYSTEM_THREAD_H */ + + diff --git a/src/core/unix-system-condition.cc b/src/core/unix-system-condition.cc new file mode 100644 index 000000000..b2bfa11d7 --- /dev/null +++ b/src/core/unix-system-condition.cc @@ -0,0 +1,212 @@ +/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ +/* + * Copyright (c) 2008 University of Washington + * + * 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 + */ + +#include +#include +#include +#include "fatal-error.h" +#include "system-condition.h" +#include "log.h" + +NS_LOG_COMPONENT_DEFINE ("SystemCondition"); + +namespace ns3 { + +class SystemConditionPrivate { +public: + static const uint64_t NS_PER_SEC = (uint64_t)1000000000; + + SystemConditionPrivate (); + ~SystemConditionPrivate (); + + void SetCondition (bool condition); + bool GetCondition (void); + void Signal (void); + void Broadcast (void); + void Wait (void); + bool TimedWait (uint64_t ns); + +private: + pthread_mutex_t m_mutex; + pthread_cond_t m_cond; + bool m_condition; +}; + +SystemConditionPrivate::SystemConditionPrivate () +{ + NS_LOG_FUNCTION_NOARGS (); + + m_condition = false; + + pthread_mutexattr_t mAttr; + pthread_mutexattr_init (&mAttr); + pthread_mutexattr_settype (&mAttr, PTHREAD_MUTEX_ERRORCHECK_NP); + pthread_mutex_init (&m_mutex, &mAttr); + + pthread_condattr_t cAttr; + pthread_condattr_init (&cAttr); + pthread_condattr_setpshared (&cAttr, PTHREAD_PROCESS_PRIVATE); + pthread_cond_init (&m_cond, &cAttr); +} + +SystemConditionPrivate::~SystemConditionPrivate() +{ + NS_LOG_FUNCTION_NOARGS (); + pthread_mutex_destroy (&m_mutex); + pthread_cond_destroy (&m_cond); +} + + void +SystemConditionPrivate::SetCondition (bool condition) +{ + NS_LOG_FUNCTION_NOARGS (); + m_condition = condition; +} + + bool +SystemConditionPrivate::GetCondition (void) +{ + NS_LOG_FUNCTION_NOARGS (); + return m_condition; +} + + void +SystemConditionPrivate::Signal (void) +{ + NS_LOG_FUNCTION_NOARGS (); + + pthread_mutex_lock (&m_mutex); + pthread_cond_signal (&m_cond); + pthread_mutex_unlock (&m_mutex); +} + + void +SystemConditionPrivate::Broadcast (void) +{ + NS_LOG_FUNCTION_NOARGS (); + + pthread_mutex_lock (&m_mutex); + pthread_cond_broadcast (&m_cond); + pthread_mutex_unlock (&m_mutex); +} + + void +SystemConditionPrivate::Wait (void) +{ + NS_LOG_FUNCTION_NOARGS (); + + pthread_mutex_lock (&m_mutex); + m_condition = false; + while (m_condition == false) + { + pthread_cond_wait (&m_cond, &m_mutex); + } + pthread_mutex_unlock (&m_mutex); +} + + bool +SystemConditionPrivate::TimedWait (uint64_t ns) +{ + NS_LOG_FUNCTION_NOARGS (); + + struct timespec ts; + ts.tv_sec = ns / NS_PER_SEC; + ts.tv_nsec = ns % NS_PER_SEC; + + struct timeval tv; + gettimeofday(&tv, NULL); + + ts.tv_sec += tv.tv_sec; + ts.tv_nsec += tv.tv_usec * 1000; + if (ts.tv_nsec > (int64_t)NS_PER_SEC) + { + ++ts.tv_sec; + ts.tv_nsec %= NS_PER_SEC; + } + + int rc; + + pthread_mutex_lock (&m_mutex); + while (m_condition == false) + { + rc = pthread_cond_timedwait (&m_cond, &m_mutex, &ts); + if (rc == ETIMEDOUT) + { + pthread_mutex_unlock (&m_mutex); + return true; + } + } + pthread_mutex_unlock (&m_mutex); + return false; +} + +SystemCondition::SystemCondition() + : m_priv (new SystemConditionPrivate ()) +{ + NS_LOG_FUNCTION_NOARGS (); +} + +SystemCondition::~SystemCondition () +{ + NS_LOG_FUNCTION_NOARGS (); + delete m_priv; +} + + void +SystemCondition::SetCondition (bool condition) +{ + NS_LOG_FUNCTION_NOARGS (); + m_priv->SetCondition (condition); +} + + bool +SystemCondition::GetCondition (void) +{ + NS_LOG_FUNCTION_NOARGS (); + return m_priv->GetCondition (); +} + + void +SystemCondition::Signal (void) +{ + NS_LOG_FUNCTION_NOARGS (); + m_priv->Signal (); +} + + void +SystemCondition::Broadcast (void) +{ + NS_LOG_FUNCTION_NOARGS (); + m_priv->Broadcast (); +} + + void +SystemCondition::Wait (void) +{ + NS_LOG_FUNCTION_NOARGS (); + m_priv->Wait (); +} + + bool +SystemCondition::TimedWait (uint64_t ns) +{ + NS_LOG_FUNCTION_NOARGS (); + return m_priv->TimedWait (ns); +} + +} // namespace ns3 diff --git a/src/core/unix-system-mutex.cc b/src/core/unix-system-mutex.cc new file mode 100644 index 000000000..359ffa74d --- /dev/null +++ b/src/core/unix-system-mutex.cc @@ -0,0 +1,131 @@ +/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ +/* + * Copyright (c) 2008 INRIA + * + * 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 + * + * Author: Mathieu Lacage + */ + +#include +#include +#include "fatal-error.h" +#include "system-mutex.h" +#include "log.h" + +NS_LOG_COMPONENT_DEFINE ("SystemMutex"); + +namespace ns3 { + +class SystemMutexPrivate { +public: + SystemMutexPrivate (); + ~SystemMutexPrivate (); + + void Lock (void); + void Unlock (void); +private: + pthread_mutex_t m_mutex; +}; + +SystemMutexPrivate::SystemMutexPrivate () +{ + NS_LOG_FUNCTION_NOARGS (); + + pthread_mutexattr_t attr; + pthread_mutexattr_init (&attr); +// +// Make this an error checking mutex. This will check to see if the current +// thread already owns the mutex before trying to lock it. Instead of +// deadlocking it returns an error. It will also check to make sure a thread +// has previously called pthread_mutex_lock when it calls pthread_mutex_unlock. +// + pthread_mutexattr_settype (&attr, PTHREAD_MUTEX_ERRORCHECK_NP); + pthread_mutex_init (&m_mutex, &attr); +} + +SystemMutexPrivate::~SystemMutexPrivate() +{ + NS_LOG_FUNCTION_NOARGS (); + pthread_mutex_destroy (&m_mutex); +} + + void +SystemMutexPrivate::Lock (void) +{ + NS_LOG_FUNCTION_NOARGS (); + + int rc = pthread_mutex_lock (&m_mutex); + if (rc != 0) + { + NS_FATAL_ERROR ("SystemMutexPrivate::Lock()" + "pthread_mutex_lock failed: " << rc << " = \"" << + strerror(rc) << "\""); + } +} + + void +SystemMutexPrivate::Unlock (void) +{ + NS_LOG_FUNCTION_NOARGS (); + + int rc = pthread_mutex_unlock (&m_mutex); + if (rc != 0) + { + NS_FATAL_ERROR ("SystemMutexPrivate::Unlock()" + "pthread_mutex_unlock failed: " << rc << " = \"" << + strerror(rc) << "\""); + } +} + +SystemMutex::SystemMutex() + : m_priv (new SystemMutexPrivate ()) +{ + NS_LOG_FUNCTION_NOARGS (); +} + +SystemMutex::~SystemMutex() +{ + NS_LOG_FUNCTION_NOARGS (); + delete m_priv; +} + + void +SystemMutex::Lock() +{ + NS_LOG_FUNCTION_NOARGS (); + m_priv->Lock (); +} + + void +SystemMutex::Unlock() +{ + NS_LOG_FUNCTION_NOARGS (); + m_priv->Unlock (); +} + +CriticalSection::CriticalSection (SystemMutex &mutex) + : m_mutex(mutex) +{ + NS_LOG_FUNCTION_NOARGS (); + m_mutex.Lock (); +} + +CriticalSection::~CriticalSection () +{ + NS_LOG_FUNCTION_NOARGS (); + m_mutex.Unlock (); +} + +} // namespace ns3 diff --git a/src/core/unix-system-thread.cc b/src/core/unix-system-thread.cc new file mode 100644 index 000000000..9fbd7a73e --- /dev/null +++ b/src/core/unix-system-thread.cc @@ -0,0 +1,138 @@ +/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ +/* + * Copyright (c) 2008 INRIA + * + * 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 + * + * Author: Mathieu Lacage + */ + +#include +#include "fatal-error.h" +#include "system-thread.h" +#include "log.h" + +NS_LOG_COMPONENT_DEFINE ("SystemThread"); + +namespace ns3 { + +// +// Private implementation class for the SystemThread class. The deal is +// that we export the SystemThread class to the user. The header just +// declares a class and its members. There is a forward declaration for +// a private implementation class there and a member declaration. Thus +// there is no knowledge of the implementation in the exported header. +// +// We provide an implementation class for each operating system. This is +// the Unix implementation of the SystemThread. +// +// In order to use the SystemThread, you will include "system-thread.h" and +// get the implementation by linking unix-system-thread.cc (if you are running +// a Posix system). +// +class SystemThreadImpl +{ +public: + SystemThreadImpl (Callback callback); + + void Start (void); + void Join (void); + +private: + static void *DoRun (void *arg); + Callback m_callback; + pthread_t m_thread; + void * m_ret; +}; + +SystemThreadImpl::SystemThreadImpl (Callback callback) + : m_callback (callback) +{ + NS_LOG_FUNCTION_NOARGS (); +} + + void +SystemThreadImpl::Start (void) +{ + NS_LOG_FUNCTION_NOARGS (); + + int rc = pthread_create (&m_thread, NULL, &SystemThreadImpl::DoRun, + (void *)this); + + if (rc) + { + NS_FATAL_ERROR ("pthread_create failed: " << rc << "=\"" << + strerror(rc) << "\"."); + } +} + + void +SystemThreadImpl::Join (void) +{ + NS_LOG_FUNCTION_NOARGS (); + + void *thread_return; + int rc = pthread_join (m_thread, &thread_return); + if (rc) + { + NS_FATAL_ERROR ("pthread_join failed: " << rc << "=\"" << + strerror(rc) << "\"."); + } +} + + void * +SystemThreadImpl::DoRun (void *arg) +{ + NS_LOG_FUNCTION_NOARGS (); + + SystemThreadImpl *self = static_cast (arg); + self->m_callback (); + + return 0; +} + +// +// Remember that we just export the delcaration of the SystemThread class to +// the user. There is no code to implement the SystemThread methods. We +// have to do that here. We just vector the calls to our implementation +// class above. +// +SystemThread::SystemThread (Callback callback) + : m_impl (new SystemThreadImpl (callback)), + m_count (1) +{ + NS_LOG_FUNCTION_NOARGS (); +} + +SystemThread::~SystemThread() +{ + NS_LOG_FUNCTION_NOARGS (); + delete m_impl; +} + + void +SystemThread::Start (void) +{ + NS_LOG_FUNCTION_NOARGS (); + m_impl->Start (); +} + + void +SystemThread::Join (void) +{ + NS_LOG_FUNCTION_NOARGS (); + m_impl->Join (); +} + +} // namespace ns3 diff --git a/src/core/wscript b/src/core/wscript index 9646b06c7..2e4a18c91 100644 --- a/src/core/wscript +++ b/src/core/wscript @@ -21,10 +21,15 @@ def configure(conf): e.define = 'HAVE_SIGNAL_H' e.run() + e = conf.create_library_configurator() + e.mandatory = False + e.name = 'rt' + e.define = 'HAVE_RT' + e.uselib = 'RT' + e.run() + conf.write_config_header('ns3/core-config.h') - - def build(bld): core = bld.create_ns3_module('core') core.source = [ @@ -60,6 +65,7 @@ def build(bld): 'trace-source-accessor.cc', 'config.cc', ] + core.uselib = 'RT' if sys.platform == 'win32': core.source.extend([ @@ -67,12 +73,18 @@ def build(bld): ]) else: core.source.extend([ + 'unix-system-thread.cc', + 'unix-system-mutex.cc', + 'unix-system-condition.cc', 'unix-system-wall-clock-ms.cc', ]) headers = bld.create_obj('ns3header') headers.module = 'core' headers.source = [ + 'system-mutex.h', + 'system-thread.h', + 'system-condition.h', 'system-wall-clock-ms.h', 'empty.h', 'callback.h', From 36a4bc8c4061d167ac3940351c97f1f0455bddc7 Mon Sep 17 00:00:00 2001 From: Craig Dowell Date: Tue, 15 Jul 2008 16:14:57 -0700 Subject: [PATCH 173/495] update RELEASE_NOTES --- RELEASE_NOTES | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/RELEASE_NOTES b/RELEASE_NOTES index ad1f6c6c9..466a625da 100644 --- a/RELEASE_NOTES +++ b/RELEASE_NOTES @@ -3,6 +3,15 @@ This file contains ns-3 release notes (most recent releases first). +Next Release (in ns-3-dev) +========================== +- Kernel thread support (class SystemThread) added; +- Kernel mutual exclusion support (class SystemMutex) added; +- Kernel critical section RAII support (class CriticalSection) added; +- Kernel system condition support (class SystemCondition) added; +- Move required methods in helper classes to constructors; +- Change obsolete references to Parameter to Attribute in helpers; + Release 3.1 (2008/06/30) ======================== From ef5b621566579c23cfbfd919c03074d72fae8ff5 Mon Sep 17 00:00:00 2001 From: "Gustavo J. A. M. Carneiro" Date: Wed, 16 Jul 2008 10:45:13 +0100 Subject: [PATCH 174/495] Patch WAF to make output redirection work again (Utils.get_term_cols() bug) --- waf | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/waf b/waf index 8fd8e63e9..ece4755da 100755 --- a/waf +++ b/waf @@ -38,7 +38,7 @@ if 'PSYCOWAF' in os.environ: except:pass VERSION="1.4.2" -REVISION="223b86eb6a7dae5acd7e964c237cf35e" +REVISION="81764acf62a7c7247901b9a99367b3a2" INSTALL=sys.platform=='win32' and 'c:/temp' or '/usr/local' cwd = os.getcwd() join = os.path.join @@ -141,5 +141,5 @@ if Params.g_version != VERSION: Scripting.prepare() #==> -#6<\%_0gSqh;d#9;X![tFFT;C@^PGL3s8W-!s8W-!s8W+-"9:cQ!WW?W+Vk9t!$OmAVk!K[2m<8^zzz!!"1h&#%g:?XhYa!H#MPaK)``S[,iLTF)sqgT*n,POpsDUDI.lsp^^&54!!!DCgGf`E+9V'+*q-J4PA$!2)rIJr4XMaHT*[[@mSCXc<(eYBY7L*pi=4U!%cl;g*8pC.D&`fA"d=f*:R$G4s&El-Hi:ID5#k2rDd?bJ)F4%S5T,k)h[qaUb?/'MP:]NWi84c4"!fobdZRu7j<$&E$C1.7&#S=X"PR&]D=$otZ"tqm'h/@So?*q4MG+%3YpV-OnH^MfkY;A'm*np-jk?W55)s[12XD70CSfR.+NjQ3rf_;dRnijarQZc08^:sKtgt?i2.$Z6q_k:)Fk;;kp^"lcGleV05O&*CNSiaBe3LS0P3c]Z'P\il+Y+tH6g@C_6qr>'@QY#nRIGR-\FnN7`%oXjDp"aKW10g^IoN-lqW*^MO%Gu)McZS[1kDAN5T(D=;[eAU!^$dQ'k.GraB?S?/p?C_m]^Q0U5QH4W+XQ`NdsO<**koWJ*IZVt^$fh)YH(uJIAdb*h=Yu?mc+$+F.g-d>+*or.+>h?=U\)h:BX$XoUcib*!)AmGC@2P^(0N"^2LYsEbD@qHTd>]To-6i7;6:%QF(J]Y1T(agTnK[p3kJ7k,,amo]I0XqXa0'hY-[3ZUlhR]#D81sjs8+92BA8n\c(#S8r5nY@I#QYA]d$e\f-;C:8r7+=&T%-%S%oMF0Vl2gZo`,!=!7O3[!!g:=f`&9nY2$M]$7hFnk&e?JeP=P]6euL[m?080'\8FX+sA-[+n@o14bq4NpJk;8*t9;1_3+<%>g;&(@h)d*Eu&7#M8h#"EE?.9=+UCkICD8QcJX`Q!.lGk5X4HD%49Xq6kWlu&d3q.V,8s1(G>Y@3.&VRabWlS=V"L&j73X'Jq%*+FMR&&*JPDQ3:l$IE;d^!.UEg1j"6lfa(D^D(O!,c)Y\r^8l+NemtT"-!4_,;DNfcU2;\<,&7WEULHVUhQ$%<_Z/l9a8]oAD#7`=H*AV-l-SS9Sm>?-;>X/da2G,!#ERk+g@d]8s5E;:_kfdVUS(A"@$s_,Ym$*-K/?GiV&D6`.+sH^R9M#fO_fcp,o\OO)@">.A4W]$b\Ut?C5,&WZ*J,#bor$VKb[6";e$4ad=sL/Be1Zh8CD'-N>0QFL/B`o1m&KsM?K+Y-;h,s>9l&%V(*0+=[\49&3r&Y/BNiJM(g8*)7#(?$t>>t%&Bpp>:!*;O[;qY(,;9rLsegs7'fadN?Ub+'1-2#Z9i.<,m8f&Q41a/,QphpC(1TI8t.X_gBs/rc%.Xe`>_7C@4Ogh-F-[?TZ4uNYXr8k/7C!$)^_k[0rC>%ArVJc1praUJr-G#MMar^8nKsoYsKn4e<\3&(_iFEM^FUH(tNDbBV@,L@@!/*MNX,3W1qqqMT4=#.1$_'Rhj*aOu8o2Z>1;OZ8B!6fd,'N8X4h+9rOnXAfDHtR'e@WBP"'^abhX&Lc2+d2C+QD)%.:GTpRBC7$C1F^_*:c&Jd2M8OF?:8/kK3.p8#:?AF(hVF"1GZm*b8DiZ_IFl`YbN&29.$=c)A5t(fd(DI@obBVZUo!bVF##8Zq(DKW[-$!)bAP;75ieL,$C(ng*5%31MEkt;/KaGRC:LQD2iBNZ"k0aBV_R7>@agiD2F@3R2SJTbS_hK`>][^B%41&-=UL;W@D&6gM0orZNSZb_5/S<)eN#\fpS58.Mg[U6#!VC;O!J^C/)(7B[BdXb%[h_b_d'"Ob$A'.]B5+>%K";c(pS;"AG\OVG3g_MaJ@?=IN-V0qoji`INr-K.1VuaGjZKag$b5_6G/hC(3du9X8MuUr^_8'4eBq@+_JidqWU&9[QD0C/'hU)Mlb+`^U>E;C!\+-'HDQ[PVfb1C9j[CfrV!9XI3(-"J_QaP&P0b:I3N=dDaF$3@D"N+FQFU_F(m/OLr?AM&k!BXX^2,t(Hs6rmJbb*-@P7aW,0$nRjpN5EMdQ*OBt0OW:22GL/#fTU(qCsnb%a^[$#8P;bj`>0m.[PfmM9h>F%M_LPk`aVUfN3O.UaV%NgbqRg^0p+9WZCEMT3ju`mi+B[+*i4eOHNID6^*6;Im[VWts)$PdJBZ6*i(F9rPBmOLCmX2Q[_&PhO5nRM(:+;HXXW/O^PR8Yn7CL1QcO9W8`'.T6pk=IN2_`lp0'P8Z3>Am%#iD+uNP;/@SRWFi2*D(8Fd85`JUClhU)g$sBDX'gl4)1o`8XrH%r/R3nKOs*;rdXV$c?]90k>$qUrp:*t;DKUriRMX"LpAN9JYsr*3_lYu:N;@h+"@7C.AcH90L`+&l\fV5OW08.X7cmjX!3&k.m^?9a4h_`)KBESk"&bTAf+>ac1NAR!BA+H([9e7n)t.eGI/jp?i1ktM+mQdk<9oWj9'HaEirP3GN.(/21Fn5g\t>MhC.I1b.',a(6I3HdfaEtF@5SNJ9&*WOaDG29^nea9G*g`,KD'!8"$,belb`FmGqHOo2*l/#q4q80,>q6G]m<2l]VI6O0i]Kp9p9Gh3mQpR\hrRRY6hN7R,CscFTjXVnk_W5,o5&[pJoTdjppEpIjop1t@_^L%X];UUaLNb^WTk.hbS1'/rdc3MBbYYfIo_l\sB=d]IU'uN9SnEdi>ioSA^r*cQ4q0rA.:XaM0an^s^&?X+_2*K-+sDoMkrQ<2C1WV!AgHUKCqlg]I?f5D?i2?TW.2\*<=i*kpjKXC*;QsOms\D"0^g/\Yi\fRrk'k`iP//3;_@L?bSpsGJ:lOF8q!+>t4VHC+0_)'1-4rG>=?Ngq5"0R(\i`'jDDgbn:^%]VaWL$.(]hTSE'@nAQNE>^(-i?gZXXF_2ZIZmrQHK%Z%?_Y[ST@o2grG$:\:PC7Bk,^NYsO0SR2r/%.qWCp$A?\;aFK9#e6/_;)-HK"lF"lP`drL(CSPLfXcZIpc(IV.%kZbh%dGNGjFN%f]0j(%[c\RM0hVnj_d4XK>rd_ZG2I98mc1RVn63pPXZpRd$<8Ufo%Z_%Tdd8(L)bgS^@c#WmV=-/?SRK"BjM/mN50WSgZbWRb72,-$^?.ek9gq3IT[oo%#[5=l.7Y;.N'*s9aje.I;7=Uf\XkQ7Lf(gtY:"5XE@sXC?+-H6NCT*JIhNK)p4M[rir.\74s*sMc<@okHeYtn[emY%ajq7GKLS&6pZF/33'>tJ6`_\ZG(1%uBZ3N'k#JMB3qqt\35jPUFfk738\(D9hl6m:K#nR+:@lGgnGE((c4@hWZUI=Z4G,g:E-kj)n0.U+RXa;J)(Nq10S4Qk!=IG[2eZXSU29kfPKlYS[mu*LVrlckB2/!h:CTk>d5;2U?ZZk'6@Nt6em$u#LrD<9g50eiLNZu9:A^@>$k]ECC^Vp(+Jd!aZ3aJQH-1ff,WG)^V[)>6T6h*EG`bc.AGS!U&:<3MZ%P+BJSHND(Y/@LfKCbaf9ja19=d4@$#(5H:7T-k[RhVq<'>-i2Uu0!bd6\S3l[pFg=N.u>[rAC[-Kl!gBti*/JFo-eNoCbeg2UIC#8!A+,>fmiD6@nIb_ss(>=pS'3fCYQ>n_'XCTQHSG/h]W4a*%gkOq9OC_n-1]CUrF"/.d-q5ZDe3aL<6^W2T*Uo(n_ImiA4C&O<'0a7d)a*#.4C6O\iNlS5ChDMbP58W+lU:dp]0`F(A,S];3b89/$Am3Aa?/PA7[r,SM*;SR^pO>0]Ih=DX2HT?5RA\A:o_+YYVenf,G+n"f3g!(KmhcbP-B5QsS%Dh_%ZkIt0ZB:V*bm$oY=^a6JHfU%CJ[BTZ#1'^.F,9hjPEh1U@6-XBS%ao;o<[VA4bQON2=`c,hrZABu4Zb)$>W=+f.=,#IF]do;Zl<\&aZU;s?/XmYTV$m"&JO2TY)#HpUQ]"0)GabS>db6&'MlR$IjRX_Y1U(alL=hrkYdGXr,UD@hUg3S[JVVN*+i69hm6kS*@VAL)<1`qK^C^q@Nq"LT+]!:#!;B(NP)=@7irsq4rbj)2m;R;0NN^_6Hq+P%jbP_?g@lY5_@2PXX"f@&rb7/PQUeg*P>;)F8[?5Z@0*`%*.b0ri$97t@Or!cZP7HLcQ$f8eV??u_\q4kEjIPSnh1P#%\^ra*rPF[]b"EF9M#'OKG?%f9&!;g7#utT(H\Z54J<^7:rlEm;(KmS]=QrCDc`'LZ@$<(9)!;p)FPDMJpB2PrBP<\Y'HH]:q6",K91W#Zk(9+s]"2oug&X1G]H!W.0UKN:mIT#*N)8M2p1C1M78,m/rset\PSSjCd5h^#HjJK2oi:U%@sV@I78ni-8L\Z=m#hVL`:e@/CeHOD2%GEtmh]lO%sOHNE^qW$oGc=MBYG27U>1r;RSd1bq!"o'c_4-B:)p1%KiD#IH@5L")@sWWRsJ!q\@Q:14:4$&:kuNJS^&_YGYL^>pU3@q`@jtMmoB9VaO7dqA,Sd^6WQrK`JL3l'(Rf@fL?LqS*^4Xq="o9C#e1^5,`BAh'n*-e*WM2#(C*h[_c9G7=XM=bYWT@RE>dgWgNBAupc1Kc#,q&)1ufc4f@,/GFm\kNYC6nLseS\WKl5h0O!o\RLB7OD5uoOQL&5:8->(6".[DJtlS!XdK:12^S01Njfi$43W?K[#@-)a4?`hhtqsr22?dJ#/Zl-'1]6bmkRR$986Qb&/]Fl*+YrF*AA.!_$*:LU)p%:D=%2b#>2pEWNXk!@0[@A^F3!H;\N!]6@qUY8@O4f0e,?6l.=?h&ES5G@/Fr=^9WO9$)fA:hXL)lkco)%-f[17U>1dJmOuQ#"bBU.J2#:6#gG(EA7bF<*NS[HGOaL/cVVCu;S'&a[=Jse'nB^7?@)H)YR;B!E-lC%_'G0W%$8=m9PmQI`V1QOm;qd)bt4(`No(\ngf6.jhOSVi<937d\sNAZ/kl"&W5?%DHE*$[mV%u"HkV,fR1E/Oku/pu56sTVh=`7k)FBNF]DA8t.IP1gkjeB/M4\kdG5fds2/RVYh`&&0Fe%Rc[DlfKf.V-.*J8ls"HXr4(i0eh7)G8a`MNTcmjI&u_)$>emHuDH_ghu,JNU68-HiU2H>B1p]7SMC6T/%9?'1(oe@Ej'k,9,PO>"]*g16dFjp1U-$;`OK6-n"#Fe5kMVZ1['F`(IR+W8ktl`_&rXdj7oN.5462&JSfTHdE)4Jj76NQ(lcg#(.8XK"Hoq0%Qamr3kGO_q@O]EMbK[jTb)S+k=cXWSG$_`2@XGYM>=I'ja[N>:SV$U,cN]21,3*j-X)LL3-=0.>@(;p6^J]NQLVT3'%cn[M,>Yo]?49it!flW2#m*F\aO*7/>aQj"D\7B>f:_%S>l3hG[8?MV=JM0%rANE-4KF7h/W>$f,]?[0pK&qnnob^ja)$>B4"WF^YM[)Sd`g_Dj3,u(Y>b$C9\7,o8I`XiX\KO9af(rc/ZH-N:s\Yh/R-!9kIBed/,t9lOM8dWWLu=lRH.WD:J;Lg9Oft+&`KFDuM.GPtOtQ51jhD;MEXjq)ffiqEE,;3gEi7\Igbu7!k>/l\dCF)paG&1-sp>F7Cj7fquR(Jp%9[aJV0k+ML!5cPl,sn#qBtf5,#esHa9Ng8jhFXGUMD]e3fmFjY4-p`mIGuYi04[C4=Zf_mXVu:rjc1H`T=rPpkN77g.p04)u_R9b4J=5&4AQS,hKf#.dXmo)E/7J^E"eO`VJkcIKqCc,]&%W'Q'E_r--^rBZ)RkX/=L/'^O/P?3)UD2_d24%dHgUI3\/NhI@_4sFUU#E1c/%N+UKn,P">pj1dRm)RZO6-l.2p%?m(])j`"c(k@'GQ&2^r!$9[m0N1H]c0XM3F/S0`hW(Ol'^X<'/\lV=N%;`b!hqTZQ*oNV*=o#DdpiEG.FrE]d@594*VqK,4VbFhh8:.nIk_o(.p/kof#QBo$BgNukcP5*2:rL0+_p4+J$<*3TTpFA9J^h`^[7[X#h[?UWm,aSYV`-;UPdTf:*5`HZho/e=(DHg!J))kR0[6go+e#*e3'jMeqFJ#W2nqNJaq[e0,%X0A>Tr+JP5UgB,prETtP4QlH)X45;@%-IrsS3gKs[Qq;AR6eYKLqeGUMc0UiECJd:r8"=eRWNV2;24kQ&H$l3^@m,Z.t90OgE,s!hOglE<)MjJ^SEqE%Zb#BruSFF6Z^Bi@gU;_*!'s.b_Och/Yb;e,$/XV!pJV$S2KQgA08iiC1]Q1o6(6:)5-F5#-B*1Wp]u5&LR/IOO*TV8k2ph<[HHIW,NhfH3.SPooeA_V.Ab+-K]euLj``KC21_nd;NC"UFda78PK/!m)sXFF$bpE-Z1!UhG5JjJBJU75=$$>)oO>KmNuQ-ZI*Ndq\EJQF'45Fg*H1pWjChRZ.r6&Cc'>gTO5uc7r$9em_p9`i9^`'11hC3tWO+l?%G6J-Ap7X(^kPKFS300DI.'-(m&/Z(.h#c8L\FlY[F/M>6:,j=j.S0TD?job3`68&NWq@L6OP51]$Q2G\)/6BY*1&Cq;Hiu7-#afN:epZ$:+bRmNN5Zg9OG87DRT"VATImG"jKqI36cSA@jMT*%$G^4aQW!c7$PC;*H1WTAcjGau-eupMCnY6b1``B`rtm=T?u`2,T7Db9j&s&kupA:BD7n7IHeu\'f33m]%tU@g#ckjY-ado]`?D=SV8$_Kh&Lh1R+S[eOP28hi`V3r(R+2OTtm"2!a'_%slp'N.mc@gl%.Tl$ThKHju0g_[M1Vp*8UE=llsFNOiYRKYZkOU->mMKe`O=T,"B8J:5fC:Z_'9aJmL?aE0A9KaWqj+[%qIjQYlIg#RCSIg8#ILL,2R4)_*ZSl!q^!43h1%5&*=('hT(:c(j=7kl5665Mu?p\`9P6F02F15rBX(F:W1f5I]"`:f7c`rb,r]):lc9H2,+;>rCR=)n02"1BW0Kc;L,JEUkY>Vb$oF]$l4M0pe'@sO6)WhDL\C0EpH?!PZhOeGjUUNGKYNbV[j]H30YJK;ck?J`CMBZ\"Y=mTG3,L'+k\#^l^2LFVUbZ@jne8q4l6DL,'4V"N[/>U.#gN$rQh*dKM:$ps,_J)J5i9#+/Dqi<]Xl[H'B&&?n*If/5l)o=jX!@ERMXGH=Vodu;'Q%fq(5FF0NLnrh@Sp[9i1`Q9gT:[:SOge.o7jc[4`"\pZo&cW\Wf\s;TSV0c>c8h"uAW\H1n5^L,[O!>A`BB6>8Q]kDsgg^D;(hmhd%o&J-=7KM%VF@-ggNII^6VO#tWNWZo=_\LF"FVjA4e^NgtO`I'TC\DPKXnoDbZFa)'@EBdQf9YuQLV+`=uPAj/>d02:1/Pp;S&#,+@a^CCM>rA"]$@PEoGP%9Fs&k;AkD2;$kSs?[H0^HNRIZuYo$AE>0B(LtZ.*?@^mL,nmA*Z+MATe;F7XDi>:Es5f_&t+nhWW@b.;bt\bAqf8S:g".D]YbrEC+gs]1*'[uji%d:[NC,<1'Ugus,n\`#ZaQ+<:1u=7m6\,u^N/4c2XX;_ip8-4e^*_RrZ)cZ]64/&&;IG/:WsF,3aDh2ge+l)Z_qh?+D/jED/+.&&\eKBh9uMtC=/P`"7ZaE).-T0_DI%4tRdIPL)([1@pe"QHFZhIFK`H4SadLI.4$gR7h6AOg9lrmAI+.2p:.>jTf=':IUZ4SIF[>cU&g(84a[EK(_rbB;"sT!Bm9=i=9g_(9Qc!l>YpWb>&&2__-Dq\j-;kBu1HBC>DgpooU#4r6[!Z]/:70,'(LK^@qm-`.-rS';)5iC2oA,pnhtIHZ*]DNWH='PA*FROZAd1;P+L!_;E-I7bD4)nUl,\M8oMi$^3^lu((^j-sX"1=SJW/2mkX0;F:-BnP]mis8tS3GtV-Mn">aYN3(_lVlcY:1H>PbC8\PVGSO.a@rBY#%XP\0d^*.$3F+'P=gcBOe3):;**LTgKN^S8Qr'F&k<.W<[C0O7A\tfaD2-K0Mo-W#1X:iMNV/lKqT?<+Pbf,l!,F$EftV8R]d!%Z,Oom?/'r?R?S[*7O4l['L_W7'K,&@O=M"gYnumrHjqpal&rJ)YUtDL`+8Qj1j9![DVqMFNr>>`b>lPaPe5?NQbTsM>e]I+T2tVCfl$Lg:\.LI*QH'bV,?#pQMp[""+b2d/F35HCJkWU>@SY@6U61V6o[a.X0o1W&V;$h$fNGJH,CC6q^^]^;9U5#Bs>Xc2n%\Dr3_gSF=?nE$/Z>ID[NP3$O<7fC['rNdXAH*p4Hk+0F.nCOY5m1q)V;:N#`(5A^@c45a7?U:q34[>,jC\8r75FQLmbadWK.:NJ7bmen;JKP>:9-\N`8SMO0hUNT!ogJD1\cY'W1rT1s5LIA;+r\p(Oglp7&i@;k&YcUg,p2TE/3V=ID^%1$XoAJDL8:r1;e9V%2[$*d!AF_#5l!T)\q/lNlBeOpZ+^d7DA0rK>;/r_s.9$)^WKV"Y312',_b(<`1%e48s1J#[)lVE;@bUWiaD*dHJ#PX=kr-bGp`BI<)WFF;B24j.BgDAD!c\JB/@6Kj"-Ghgtam-i23HKsj(V>^t>kNYFG6"PaH6j9Y3]fc-D5'O8/ck\K3O5.dIfd0i&k$`dBZ,p-A+=mbFm2S;WheriTFM5ETT.q8WOrgo^KFB\S1M7=)JAj8C1e)rn:f>iBYXP]0L1l%6-UHnce,n\i3l>Yl_LY+bG.3hpEl8nF4;W7FEX5dNX_mJmiGok,dLLbQXIrh1_+Zb%^.r!Cr-=B4'Y\c[(V,OBL,kq.MkG+ZiNT]8gdoiq"F],h+Uj\1;VPma`+;-umSO.!F;*=2*#)f/q8^u(daNj?.n0^]4U(6AEN6Br4%p7@PKHKg$\B+\&WjVetj/ArH;K*7_3+JI$.&R8HE,nKQ&2`4sge3m'P@^'eK10.]+6>HB?#sXnF4\<9aBRpk]'?oVqW:R,8%gRI5.$C+C(8:lkqIkJef>o7j]i`j<3k:jR[`]:7FAd,Et"MT1EX1nCNl)s5T\[_f!C/])&_P[s/#N)&i@p3"i7;IT=hR@o`(uE'393m$hrh3=KEM6n^_NFqc+_9,?`nG3G=f#&^;:)FfFP7._$1>/&q_D&b0+3^Sh##_ist'bc1`PINb^=AaZ-f;A3t^V.][NWJVY"d#Fi[EbaDXVahGQp-I?'*)kI,r4YYPooZht>fcS*Fc9A?t29h(\'p\E9Abqng"6O%`H+n0-hU)52)hR""M?,E"(=(t8)`0CCCV+F.AUbQH59!YR0&=/A1Ouf;'MU`<4[5Cm7>X/+l)3HMZOcJBtPmWj.`!Q3f$r)`1NGs&rN\k_g(\,]&9hR5_*7Ql-3?c2-:er)+I>(gR&W*N=dg<[O'!0jQAn_)ikLFRpbU^/B94cZBlCT7\S@j$e?EGQ&QHD7:c#ajSfAQX^0<=_4qS)R]$]4sTl(,);^j&((&]qOk2Ek?+oCQ$^dKZ.V/8Be'q#VTp;&naOA6NjF78q8<+DuRQ[\C!Ap@bC346iLD@k*Ib@I[08^KI`kmln]lX.9?bG=gI]RRf#S$K*Qa,V\6p^r*jG)StF)BeAlk<1nM4$89'UrkC*LZ8U#66trD%GY\bs1*WJ)((UYq>uH,qu=pR+EAkbJh1GKBFDHB5!OUIc$Ve1YcEis:iV/=t.OJ2n%"$1^W8+V1N\n7J^e4:/.gY7^WP3cmSC0;5Xqdl/qAA:p!1)S9;Kjg[.fhe\"\Xq*1?OQ?dg"N-R:k?2(LIkk/Fnb:@q`MH>,-UCag!TO0I23j1q#?u,mE['qd-P(WWm7bsg$(V;SR2:9Z1FF.%D(>[5:Vb_d>3j>d2Er6<;FNLI@W(P'J-4P7G)VmQkI9(Skg&;hFH?9(+O'8YV_AV%,HjFk+_GF9Kd.6Si_sD.C]?Q&NhbsIOn!S)F+o(0R5*"0W5_PuC"HqRu&!(At3FNTk\!P87Xm*_*rklVNWrB`'KjGVrAWV=Zl@`tQ3Dr[$?E^60+,f8_??'hIlIShTl-d#P>g4q>^bNH]F6+?[WstA;,$S-2b!3$Ie9'jFftMrZHBlmpH.DXBQ%&lUG'XXpmA:\JFnF=U2U2(Kc+cKa%XPUaLV7k(N)\6f.OeW:(Is]NHGWe[:31Ae3Gi"`G7coaUnEfKl/a:U8mMBtg\R-`FS(WLgF5Y%kg)c7mB4%)UV[cq;Lc0QnqETlW]>8B(Rc4WR3FYPVq>BYn'K'=Y,'h_(Ju4Ol:.n*GgBTC_S$Q-B5G./T^]B4Y7F(jaG5N`BJ'Jbl.QTtOZ[=4Li[<:"JrT;gP;B*c0S#+0eQQH4;2#)4SL)PRE5`&'Y3HmMub8%8B_3(dta[Lb\=4i1u6&4@BZUA:3>_G$?g0rN@t5^EQCD#`,1AT!m^*)M,'kP=%a(X>LUhOj%F0;dqlV02^_XsC47rA!V;g?muoQ/@(^Gs:NT2lo:%843ka#gX(2:Cs<=r0n>[!:T>I(&$!rOoc2B"Vf7*homaI0OF?)cB5^!I$'>I5/mIaeP_F[n^JDsmF7fDpdOk;3E.R0shbU5B5>hou@-Ffh6?S@\@6.Bpm+1(ijcWQ&;#S;Mn#Y1eX4Pk<<4?^G4@;0KKj\,cp,W8NmO>!"V-MBetI(AHMM_'1e-scPbJ'CY$I6oE-2169DOki7)=8#k)NAp6O<[):O,njn47XjNUDYMc5LZ\KG2#DUe`l!Q0kKSL-i4Ee&hbgdcek;Uu1pJBL]hftj$U0g0P4UilJ3-i+kN,L?#BO2DYc9arWIZQ$MZQ2YKNbrSNNu76_``URSCpC1PDannNIbbkHq&WI@KHZZ+C.S6B64&"rLJG)kNnE!`k,=`2d+>)T9R9otXj01Q8&ceYCnFQJ.#HM"73nZLct/S`\YKJT0[kA=dd'I7fDLNYI2g=s?-rV>rKOK6iC<61P8Qp(>qcQ4dsG]RV\:3W2&d:GNE$`s;u/b(g0fCoS?V8DM]ob"H^]'cl/#+:;!Y(P8VE-O'..B/^>9M?9;AQ&Ub,0?3_Tn/ApKdV+EST*PsE_O9`R]E*D"?FbA?m,,U$d-?NRD/UI+7mE6"G_C@MQ.TMZbooeSKIRZI&DSceU6*!R9pBB=Zs%?$41Y;4"?\n,HH*_iM9U)?+5`LPmdt/cHT+cS"d[eu:d%e,Te-_Akdl7Fhd/.klE@ATHFr.?jXe)iDt<,Jlb!#Sdc'Tf7]q$FENV;B"cg5!gPgHDW9>Df^OcC_Um_Mh@q@dgUJJAeomTg5_/Z>YS%T.UCo"XlNgb%h>kmu.jf#peH>X>mWd"f&3XQjqLWB/d4Wh_jqS*!co[LHD,#['0pN-,$oX8T/Ia3g@I,iPfGG;]%]://-h93`F?I6^>c\BinO9^A8gX3R4b:9OO8aCn[#k:(!`SP7&^`N6.;:Z4*U@!-0_sjCW(E\a?r$>IB2`"YtmaMi\Pg2qs^$%hKW0#>*0)BDK$rF/H0m5\ur@EZ&4!#;2hYLXgn)kk]Jf5,`oOs3:=c]<(X$2shq.UAKF\Rjf^T1518HkLI]-N?$U?QFG>]F9Mq71&PqbTQ64NPQr0jgKr/_s:8Vh>@d[_"FFOo0G%^S]Ct1QHPS7r>pCfYSdD&$)MI^l*<>4hA^`^AD:,M:]LI3iad6P`H=PnN*_0c]ibS5C[PFAS7:R"br/=olS%\QgK3-_NN:jP"^(@NY))u3`G4^9@!lAlEa))^O*?T)^jJ!lKTdU.'/sq6je@#o+$oqVTcGbO<(eQRPh*X8;;-GHAeT@8B`uHUV/4M3q4J&S(X=^Cn#TG8%`D$"ugY/>5P/!9he\g@#"\h>Ci?&kG(ht'G"NM!=Nd-V'D_@*NoAjX_5X96eSHAW/YRk1cNJ..+D#.P>%`D7-^#hBYoUX"`UEc]!I#L-N^iHQr)FiLl=m)%]'U_(gL(XZinBR&6`4*AcH!-Gj:,BR4tPcisc8W6A-BF_cO>=DqEl1RbGA*6idmqIni?>$gqD5E93jN_lt,9_;)E_Q52hic-djRPe[Uqni?uG<<;>sU$Zu!&AE0)t"?Lt5J6]p%(#/HO9/nHX,A\b3=)-Ft:`sa[?c'UXQ=k[uW)hW2W\/B%=UVJd"Rqc=S0@K9QfZ^QT7APY3nbcu$/;?\Q>]0K=\E>U@r3iXV'k,[!#7\t'InO'%Y\EaElhcMEA0ao3K!ifnX7i)X-n\&gPft`ji]Uc;NOU6dgmR01D9R6Ephr5(@idO1V<%m()lZ:i?6XB+!='q/0SE9s\XGZ$+R/#RFOS^KP.@*7BF!I4jr=4s:O)9C#e8DmA!)$29MQ''F1>3)*V(jOel@EAH9*N]BTZNLH7U!TR%o!=uBmLGp_Q0(B@/<;imrEd]VJ#DU']D1r`TO9k?VD&b!u^NU1`!q87e"(4DfRp@$=BU3KZ%LIXPcl!S6[logAgFO]gRi-Z5m?#$UF'J$gZ%1`/HkEF]_FmG,d/Gi>/#C/(,jSWnu.)$+i0_[i-D%X7G,I/%\0`*!p"Z&1'QLdX=bJ_3G8EL:t@fnfPV=ZJVQk;Y0J@Mu4g3fr9$2E-_V&LBA+c%AX5iKTe.8gP`npDJgOa0,.r1W/R=m4,E[1W79P\uain307GO/qt@s\OM>\cA`=m:n6Sc\d35a$euHnd9s$mV-F?IB8FFVG.FjmeVlX"KMU#jLC+i;Kp%I!R6!P'>2*fM&l%i/==n]1-6%=3!)am[qdWN9&SUXuPY]3Fhjodi+`Ga!%=b.Bu^ntQo[iNOPhkGp(G.o?KmN&aJ8ES;if3n!F8Ft_+r7s"R(@3i81(g06rh7Jg6Bm%Y79ugdp)/<"Z8t_ZS4:$mXKW_A[`$I/?W-oiPGgW%"<5rsp70pZdgKshQ6(8Lf(VQ,OFM3mF%[TV2B*i!(-QIiN".`KO&h34fAQU6PPO&u.qu9M!$.IS$c]m$P((QAfgJel]9nn7DtfGkJm5=9.Lqjl^W`a#Y)Pl#G8W1HD&hJQ2gf"oLHc+TCL=@VOLSb0"rp$LcO+iF4o6hK`4_]Q`S%JMOY_n7$t"9W0BEJ0Dg/h50bDEX!uNF3OG'#.,a-3cU!FAA4UdR\6_:49/_5-^.*iVSa79&-A=O`AOH[8RG^3r4JGfG[]2<#JVaq\7%9l+:8^=t)QV4WV9XX6\G'62>Va8Z!jGu\2qcFLF=)Q+$)A<0S0CL`PUY/F)'6:i.)7/:EUOK.iT3BaiX:\s[=pHr9!d0-'_ILiHW,7tCZS\+C?4sni`eO:;#"XoSQn+?2:@OL&\Ti&qtoU-VC\:OXnh?(i&Lpg3V"@mk@f@*nalWY.jO(/&kp:I2i?@#T",X]At6;]%E"#6iO%Q(#t6t-i#'?S^$X9Db:B9rI,g%fXu4ih8-H!LM9oX$dF[Z@]r3j-ql1WV%$ip:GkZ?5mZia7A`k+R_s)gGh3GEYbfNc8ktu/g1d$F%oB?t.a.J\b33rj>mj+'&KOY30gCd>G*QE/8'J]ABi#n]Mj,W(oGs8PCKJH6A%n$),T)9/KnbM@eV!jZkc1BiNUYIa5U@L1a0UL2Z3@XP6NsNB,[fqOln-1;W<#\O_ffXLD$a::;`IglH_%j9R.r'&??Z#fLNS@DNu>:])6'J$NTohWY8-\H->-*6Yqp5c1m%>LTrU+RIlcK*iu+cRR+=-1gtIPEF*ki[&p>fnHMV`gXhWNQlf7T/"4XDY5&JQ/=$Q+mosgVcF&:@[A@CK3oK>UdT&aR9dGHuS1CTB^HZO`sR$aRYb>]!k[Ar)YqkoJ6?>V=6W"\i"gnc:NJE4p2TcT>pP(`KQECKX2=-^r=ZmR4P?>,;K7,KpkDAPCEdNo[b;m9&&Xg.?I@tTlk]IG8>_Ah.>IUN^32c>heC=q\p>Z&hm!:3.RlM`o:;[m0J?16\k%'ehc?]&Eo+;:@Y(9H,`OBO_88#RJn%4;g^?>gFLI+I(]".kEdiBkrNHNpV/%M6&m!V'3KR!=WY1B:0W@KQQNZS3UP9'>ur>*ZfL,r]F`BojTI6k:Z\+@*_%SnA6mO'Y:b<(.i#1<@A790s3'mqs'FWo#XB$kWRN0f3[:!ipY0gf*Tbu)W5IoTmj)fclEhIh$:*q2aOXUAf<0g4d@#V[c"0J1JY[m$uOeK_TXFr8@mFhR;"]NB_N3u:rY?FD\.\I1LqpV(fP?OL[(M,G^CQ(004C$I@.#"LYL!Y9[#as?JkUXb@"pkc8W^(5o@gGd(i`I.P*niFfFQ_[T$+t;PZ-Lm&gei`3g0B_'$5-+6.3pH8iQ.A9dK0g)>[\K:YP,i25>[_rnc#i-&^7Mjr9.'273T!JZI83aRo]7+qT&j2_54qqq..m#jP)N.PBaQjmh"bO(O!7:%(Y?9YD*,%K4`tfuRC7Ib8r5l8?9GN]0._62T%mld$F#5`NL3Ca`lo1EkuB<kk?dqOOG)/>unG:Dc>U5s-T5@F/CEJM+]t@i!/%2msDg0'%/RVH0k.#c-qu4LP*R6I5D_DKfUMsp@),oRuV4T$Q4s!][cDpUlA`YGZ_Y)EMVoEqWNKUPEoSE%f(i@r+];TMFTj_!3>qN)5pZKDVe\YKuX_!0-Q8e3CKle=Be5\U":p,MJk,uE/Wa+bV_DYnA.[oYo:$HtXlebt9;^[Kc*_&YYGqT'[l/0T2&&,b?EDrFKr/L7BC#N-gOCqQ#:Mh-qWCiEm'HKRI-j.4A&gVRTT=NajrYGL,^'&uUMMS;H1Pm!\kfb>tYs1C[BlH-KHXmAiT8T7tW4`pJ^_"JlNpFSNS\;PEpN3"ok(Aha4\r*d2ZQ2P:lGO$8R5::qCgnj/jc0;DPbfgE)SA37r4.:43WW,k(p9!?#B(Eof]&l\37X$0?54U#VUg-6D4d5br\UcBig=EjS)]c4sY-l(p^+h@DcM/HeoQDE404.t5'>8M@TiQ1u*+.05g%s]LJj2F080l;;p=)h5G/<^<21sp$N)UkZoHdi2p?qhhW*+?=@Jsj+`^m!>lp;`^Z-rCAI%Y!5/eAmZjA_\0=`ZpH6r8IEVJeiRhR`$3ReLiIhel6)-$a5eIanR;qSodH'Z,!@a7lRt?*3aHXr6P1F_N'_?[AHMA]7]^MKq[9?DBV.ej8=U]sO,*I/*6pj[XX=M>'Loce#fsT*b#8+l,J"AK#[<`;0E\V+qaK1k&\#]k=%!R8)@4K.uYWfa122_3jjjIj=@>K+6D"nSb`ppXreS*Br";^?E(i1_S]gRO>*:5$U,:7)sIWjkWCQQl?8&Sn5SeYBj1m4&d+f`?/T-k<=QA[p,jeR]i4@U\%P4j%`$hf\qn!7&7Jfe&gdtlf0RLNjibbE:;9%'j3kHNmFFV3C`nU(/d%_Akidl`l(_2R5$Wr"Nm5iWOUGTKhL?]iQA44es=b,S`="Bc>&mpSuoQTNphZHOgEJ'edNm,h,-A?m7X2E2B'B9'kuM2gScJ5.o%"Zs&.)c\eV-PFi'!el`tPSrF5i[0s))*bFlQe*]_$UHqlHWSZZ_GQ<)edj6dFGNUNVja;7#"J20M="Osr>+E6^NmW(b]-7J_5c,%'Z2\nk20-+T(M[9)_ad_&U@h%8k4J"*0".1Y'6oIG!A.784c;P<\?ZDptBj]5uVKF$gGQ'&S:]j4rH9+&(JpL+Co\b8W&7^W?!3Ws#"CYLEa'c>%aC9%9hB6KeZeX2Ss8)%0..D^(&a]ge#D7Z`Q#^T)dqKdTR54)[QiapATrKb%?>k@a1Vn=TY&oLiu1oQS<"`rSUam`:Me=o)#fa!Qf>[M!O0e9DIF_o`.CCdV<<\;-NrG]'f]'H?Xk>OnkXtNEd\K]6+U!?XOp/L)^'onSbZ*ld-o@DuG$L:o-g-\rDHHb?rr"[u7Uu_C1nZr,^(%8["e$#]dMp22Nq2_49m?6$s$Wo;VQ:'sk,0"Nm.u2tU4@hV'r6U2_rW8K<'*F>]K:dh@n+H$53tY%H-;BX)/?'sE;Z;geb6V\7/U3N?eN\t.L(se6gX($DO'EH_Z,[5$;[F4oZHS6J>q1$dcK)PO,p1'j!1JHGo>C#R%j>#*U28p]i)u>V!k1^,:hVoc=J8l:Tk3\O[Q;T)sr-Q)<'kZX$'Ls']g1.<]*ctqfJBUd8gRr:'OOXb+!$@,3n!%F%DX,CUrfH/#'Aa59RBl.][r'Ze$'[_[,XjNJ+h#+(Oi\Wsqg>SecOmV65hWgo\)E;X:7RHb?%IX\Au5&71c7Z9dt]ianC?CU06h:U?4K)M>BJ15!mi;OZQDU4agfMQif@ZL-,53pqXt40>'M9!'&<'q!U?UNg,].OW[SQ*>IS:<`[sb&5g9d+$nndH@jU:l.F"O]#Z.9POB!IVTB(K[WS4%.e`n(6E#,fR8C7j^GWf,.oTWE(#Hu!T>@O8HKs^i)'a9YYcDBP:Ynh?l6_pir37-VoicfE"bcVAr==)V[]",Je(hMbf"qbacD3>R8o_Y<[NZH.=0$SGLQGqK:%L+s.<7N3(!nTura,0HS`90ssDUkJ;a\N^S6/L.-&i.&QP>34GdFMk(U6ZXX'S+JABS[,R?pq\;(4>K"/h;&H3qLg*)9Q4%]293]92>0D=22aHKf)ejO%]pAo4s5#>gAP,sPu;5J\2D]-VCWO'PWKT->86b+i/o=%h@\EZC=Q?KZGq_k[RtPOQZdRF^$'NIg-['(\ML*uADem-^qh]m7`7=nU`W8@26WI;\9;j,JsIk2Ml3rUWdKOENNq0A9e7QQ&O1We5D?%T_IF;L#q"i1ZZ2MN2:+<,]_@<')8S'FJln95M0aH=r62%7oYQOMP[D;N+`'/#S1,d.gM/F1n$.kY?V#:"cT62(>,p^(c!e%`M3B4NaVT8o@Pj2Zjd2/M%1orl!bX2\2.40[/#dUu6&s+36eOacNfb@aUdC7!sf9MKl.'!<3:+=2KSA%'7h4[J:nQ+)cQ`]1g?cu[WtP&A/Rk:tl2kaJH+4hBY.flhYS4e3nTaeC9=bJc"*,#WZ`c6lcOs)K56X)1YMH*>Edd&0V2`B2$q+T3%f.s("tf/s#L"JtX[];8l>2fF>pW\f_$-5/`_o2T]>akC"u'n0k$A$AfpfRDHUs-64)suKI@g:W<@[A!Jco=Z'0N`jNDCnmj'Ml1GYLP:Vh'=;Whu(_.12eU(U9dk[#;ed@8cbQmb%Xt_-Ysk95@BZgu#a?5,N"jB:q(TQh)7]^QK3@Rr?D\Ac=!j@J)LcCQh!jpZbS\p=gp?[:Z>8V%/dh]bWA'IOuB0,;6O2?Ok;Vg_*rQn%M+TI8Ud+e$pt">:4nOc(7K-uJ:5]YWkS")-8>YKb)_*IHSY-3%:`J#LDJ`^d,GLhE&4nTu:k%1(1_RdA8<+$0!iDJUC_5n$*9rl.[Gp*qL7lm,^mXT@m9#PM>hD^QnuH1B!PN./.,/j\9B7aEM=RILCi??k7EJ.gr$uQ>tNjH]HG\:otY#t3TSSrRBsWs3t/!Y4rldj^rMX_#])cL7#D7m*O>pD;%>QEi%@DV)ts&7Tt2aJa!]VHD_T,)+&,6^Nh_(>1UX3Fe@IP&[AP2Wk#IfPE:co9a'?2G=6s]E(GY?,1T)F;kF/M?6:,l/Oc9nZqQ-`Q!f]@1D/Q]C_dCkqmn`94CKcAB:@>Xj7i9XsiS?),eqT!S\Bej^c=$f;iDI.2TYNe$28bLP0;JU=,,^82PRX>N":gMZl/+aA"0sQLA.H?]L2#9_#MLNE8jW73ZQC8O/mo=2X'HD'Z+6c\HVRWdR:77W\fenK$m9S?s#c"4KKQu3li*>V17487d&)ZN"I`VP(:PPlQFmA+.h=0F2&:oaC"NQHnG&_cG^J&eGoR<;:-V"o8:YP?S1?"kWP(eqd-\jVdOD_g):i*$(%dhnDB3RP8_u:6B^1#UW#$iTKRA]CTVQ\.2!"YJ?D^<"5Dc.!'=3[iDQ@E%$8_T0R%6)`nNX/V.mm2aRFnH"p`W*q,nEmVqj>ZF,S/,!cKuNE]M!]&A^6C4Q`g#7GB@+1[-dRfMasLQTKp9;k=YdY`qIM!.l4MG3jTsg;YEAD=aQ:=oMFeSVaC;[uW6d.s)oa!X%unD_f]H1$M-U)Vd+#:e&\^6jN[\o9JD&\,l?mYlH@*TV$E3odQ@HfJulo3%AnY,ccIY?sJ\9^+#=P!M^hb.9@o*kO1.h=l0T#:OHHjelEpRlsqibriN"aQHLpC;+O3H]%$>/DE.p7s/]+mjaL&)p(3VM0of/64VT7`8PSc@)Z\C]j)e87Wq+,6[R4pfu?)M(c1RM^+%F*iW/J"!48<(2*#B_S[;;=A/Z)MR-Q--gQetJoCost1-6[8GBr9jf=M^7XK-U-$dChA,XgZNri=Bl'O$2jjSLKrQUXAA]$h7`NR\:#U7>T%4k]UWQ7mVXeoBJaKR9X^t3abN+68'e,(.`\Ma*RXi!bK0jr&f9^RQqcchR2^!7%tU3rYkEpcJ,C%F.k0XCt0DnoOC^S@:h3OEu7FjaD9Hqh];(N;M$#>!Z*1fl+DR!r-*h_7.)Xa#"N_>C(&GEgdg_(=<23SXE,j^gNbC_KH7I"n;;PLi?iAtkIRj=?ZFOis&tVX^27]G0+W'TrWYe]B2VE3kmVi?j3ejsBq.[bS0r0J\_Y^_FuilJS>NciiB]C5`;CL8*ZG.o@27Rf+;@L/Q6B&-H$3'kKjdSW>72;&C92)!@r3[oF+;X?_Sn?F;?(_:SaQE/qKn^BgqQ)4n)ZEUn+]F0As66d?@AlMN07^%1`->iFW?DG4?Md%$e$,cRrWA%ga3P,^@MKZkV_U&U8.@MReu2Z4l/]bMIBur!ZD=8IWj#^!Q0D2Jpm$4Dh4\0CLN0YN.u>cgPN7/e&0@uR>]!fJ#og7&W9pSQh#ujl%$hm3)P*d@EPe):h^/fplIkPhdeTAT(CDARrS6pmNbe0L%0cZMU`c4_ft'J]o(PF1N+k\KlEJZQg,0WUPHQQ9"N9o3T([0_;0ecE^JFYLZ_MiohLRmjH^fiL&.sZNpgaiZ\5sr]Lr8BpUV-X$8U@6n5"$Js$to]HaiX>+$&H4:HqRE['k28+/<7C]1m$Dp&X\Z_b>\Hm]7lWckQ4S)\@Qr;l9A.84#JPTthI2+iqg+=W@T&gPC&=ehVRKU`>eWMJ_M6oU,13TQ\.AGm&MY=X4X%,_7'Z$0kBB't&\Z7M$(<9-lo>!uOF*I[$?B@In(C3sSW3TRMBTR6bDtbI['FK3fm6.%j#3b]AI(/i@n,B(9eD;L(5%I98c2LDaQX7L4Mg+&%hsQ&!<$:RG0]G=\ImYIR2!fBUd]7$knjr50MD=C"LPcA)#muo3"FIM)%@.6rE[qGeca7Fl0sACMU/mc9/Dr1*!HVaA`U".O0J>J_8MTW&C,`Q"F:;8`Oju;H&nR0%t@?o'S!FWd(DUF*aaVF2rudD2@=uh2n]QK^t&*)nQ#SW+m.u!2InB$'2I#@NfrP_]b$Pk(IkuAakKI%]=dR2pkC"h1sHor=p`EB10I@#elA>aXT=Da4'?fr-3W#^L?U^7GP(-ZDS#Y/[5=Cl\!7lA1D&\*5mt6N&T*/)0oh3%%'*uE.^oZ8S4OD.7F?^8Rk+4i:O>+lfhh'_08ISJA2cS'')YV-LQ5V2V)&@^"2gWoKZ6>bQZJaG)ct3h&IB266:<121_-8"2/o.O/82P!cO[oe<>&W(EKI`LTN&/dbke1FLr]n].U+:R\1E=G%C`3Mi9'I7?.VUi`6EKprP,fA`K%kNXSo(5(oL`I_7qCE@kYNe'4l>M5JWJ$1"6G7[\*MENHRoUI&5i@MC.1pQeZ%3d\@&$cgea&1)4<`%9E2UDaffGjeo^/PBD?ZNmI@/6+/![+noOSs3Uu!A>kN/:Zd-pbAdiSGVNXl[]?T[g0q5(JdgR8]0+kc,i_8;GR4#ug%"bpbr9cULEFLW(r/RnN<)nB9Bkj88`86m-'Zjgg/J;+K,,0O)2K"3DNq:H.j$URe(\;kJ%\4Z#^Ui*916_*Fk':CSph%OE;TGZ02HE$U;1]\akGc(O;Bq"9Ct04a96K"%$0FtCgN&iHLE``L'\UJaD\eMH.l2dj?#">&-"iT4B&aQ=NWS^:p8JnfJn,4jVPDL8!B0RF8\a1S5R*VH"G\g5Q2f$lQ%#\SpHp@qMQZtm/_T91LB^U;Gr_M:g?ZXNtHBVY($2m)5AZgC3`eI]!R!MW./cmF*6Um`-CAP3W3QKML3S/o'7rYAfKpVZ`ZrkHs4YDu-BWl,u0F`^(WH0#YaP79q#.>c&jIgBYkq7D(ord8bh:sX@S>AMF06#u'pL;I0HR7E3@5g;=m8%\\.&POF5O(&<'E/65Ma5aG,T$c)DRML'm3uNQ*Q5,EpJF$,hI*jd(D\rOc`\,]&)t6^;YDVIGf$uA2X[mU;aX.jGa9V,:Q<:!#p<+e6;:]a5C=K.2s1$C24Weh6j@$O&p1rdDFcW0!W\l^r?%B(q1%H[?etZFb%SHfc(3FV2R=Fmr_>#]rmUM3p2SOo[B4@k+7bP63`cbY8!eB)Kb"[;+W6K*]u9"<#,_:g4tm3PAr'h2i,*\)PPQj)'PYH1K*JR[DBVUoTk<2>OrcRD?48fNL`B7euTADC=^Z(I*RiSi-cRET.DKa6>#8dQdb..JLViC?df)Dq)/MA:3,sOZt#Y4aJD=77i4e/"Ms@S*:O#rYB^4O=1-k>%rKr&YB95e$H16(&aaEDYQ5F++u[`c:Xad+&=@3ViM9`\Kt[HVZJln;%cjSX'Keo5E7V2OncPN8%6niXct?9k"q+AF8.-'SYlD_6[':"fo.a/__EsT&jO,gdc8sf-^4GD!b(_L,19`N+02dH-125Y>>-dQ9\L$A=SU)2qdS(*nD9Zs*U\bJ]uqUT"]6Za.=)#8!,RS><1'rKKD=pNY]m9kWZg)4+d>=Vij4mh:N?W)%JH`UbuD%"sV0D)k##9L9ti+Y#%>t8H@(ehulj4*#`0=\%fX0rSE>uF2??gaSPcGgkG2-PT+j3<($X)h^uM>5/##NL9DVG1Rhhda)s=UfY$(5;^+=Y'f0?um!mt()raB`Fd)Z3$9oQCXSLuE9DHbZc]#+Go-'Un&BDm%C-;AOD-o4j9HR[a7Sr]tjg%]"!hp>rm?On\nOdesUKf$\$2Zcfp7C^DbL/>MUk1Q#YZ4N%9^8WBX,k`@ZYS_#+FF*2UNF?jbs\cruFPMCr9;$!sKZGQ5NC,"MX1B1=)0XZXu_)M0ZOP'-gI'43n4qmY%Zj#V`QEgI+XM1-.\NpE:"\P.kX1]$Ys]G?:Jjou^!nbgiFd3>!kVI,*T<%c,Tq>V*-_Cu+FC*+;#r/28VT,Q?pYjc?c/L&TWW(T+Z_'dRs6D:8lJtqOH_Bk\Z\mf(%A3:9g\;gSh:0^G^:-Xggmo)IL[g%_f1B-3+BFXbi5lKO_@/N4ZHB+Y$o]ecWVJs5#2DT8;>fLd7k7I9hrSumP'bgSom3[J?"2KbkUK"O`:lLK5OZ&i<\UD[^DA^iJ!MN<*Zt:1cEKK+>ahife.bq%2eKBtC=0+Ip[0mbDAt*AU.N&t_idT):66C280WqVOu%=YDU*`R#p^<3q(9`(mt5Ki?4k_X[jU+rU4R^t3D,lZ5T9OBt6d,)*3V&NSO3T/V.qT)4=I.31Y,c.>L!B+ScuSBO[d+lV-"nY1mJLGS4eCWS\Q6M,I[hN1t7I2l]/9b-R;:dAR?c?/7"qGujq\h!GYApi^`%@`sk6J''k?%O3<=8Z\nBC7/g;lKm8r#$"6%2l^p([%75q)VHosJ%j)YbY-cJP(.WM6KrrB11nOEB+'<)PEN7$ln!3"GA)NB'=VDdeN[PI.&$O:RRsq-AGsXd(Y2*aJ1mVK%]P,SS0%^^Y9A2TE57a:Zf,e#6Pk*34*?Iopo9]Z6H?h[e?7dn&bnWG[,pPg>6c+X#^&2.EGj9IFH"Jh_rR2_K]p"_#k;MYGkfTSF:6>"iFPaRPb`-V;@0X.V$NO:Y6;rc4=Pp8mW68ak0X^16H?qTH#`@ZN\lsKeZb/faWf/l^SfdRZl"9kOLhS:p#>'ZFh8cZ[k:IRo8/T.R.k0^LAnU^[J`[iSQY;]RE4,^IT:(=;SDcA(f9?&&`':q)T0CM@h2::ojVNJ#Wlq2VQ)=Y`QtWRfjI)Z7`:3_(#HH(VIJMFB/!oj,U1/s"iX(ql"qg'N<0$a&,F![m/IT8.m3D"[l'To^R=epd`B5:sc]!.Yha:^?FO#Fa)!I?e^!"F#>)k5'eq)]JA,kKA8?5E7LKb!Vc!M:fDpI]Skt7#<#>#5X@d)nW'5Wr86UD..!'1\_S2U]!k8:W*OPf070C$VC,RC'%fLe$5HJqEA8AeaKO@Qg$[=OH19*HMWg7o657T;SlfF+7Rp9JL9hWDl%oCB!A4"5c@@s:_%G/PFARs1sWdU9%`<,7b7[Hn@Ya6W&`Ni;Do(,]=AI`15dE-_8g:8C1fpsFOYR$FIOplTsUhrX)[K+Mpsd_;O,2UbSOFL)Z[Z$dY(5IcSq]#n&cVe]4PqG7MV."F^$,j*2^.'rjTI-<.sltg0HU#^rF?Fj(@;OS?DXm:/rK(\Om"l$0E;f2>##%OCoBH%XbJ3VE!&5dQCbn=='#]Qd4*9.UT*-='3G*[ZmaTGj*Ta7MYc^$"j%mkVW74H%+=A%>gUJ9fJ<#SEYFl*]+C#4<*KPQ+?fO*#%KrSlB,XO4i3(@OKFl!?V$[QAfCIc@tf/:2Yi4*n`4EQ#NS)LMR`K%C:?gV;'=)+%>@2k3LH,:Z'/[NS]#T?RkiR"iJs'E7TtA#>D4_-#5;3,BXMG17^N(OQ$jTGLQ(Mb]GIRj7&X&p?6]_&DT/Y>XoQ``6/Drd,E!3i_Z,OF0I?T`3t9Q'bG,T`MuY->Ne9JNA5Sc6=X\e;2u.9#r.^[GPnNfP%o9&[u['6[Oi8)i\>>0$iM4&]UV-jRf%>/$X9O#q+:V`B-Q&*e[hGF/-#a`R1p,aW0g;]C`MrmP-AL.Rs+cT:fVBj?lg$dmNbFL_RINRPuam)-@4CooI(m=]gZgSpCRc[K"]QT3lX`TE.P\)KYP7_Z_et.]!dp&*1O=E5\RB(mmKCeg"bUW.0h],4pAH!6BX(ugIn*b-,W%nY#+si),M&S6"fTn/fHQl@`t[0QZ6)\)LU=8CS)b2g3QfJn#O-&T(O3bG_Hr8*P>YLLJ>TA;E(A>;b*fNk;r[IQFQj':-bAoH-p=SVugE4k[.&TbS6fUN@oar^k"W6>R&[abP%j%)\J?SPdR*$p.VfUUhjaB^U(so@7N<^nm]/lcZg*$Dqa2KR&'qtHrE@A8]Q63P3qY8m3^3k+$'-sW&#G=.l_Sc')qL]dZnpU9kds\pa2?,r233F/s(ajY"GAsCmc[g!pFe5TJqW8`[86=kt@)d<5YK"AWVacYpDst3^7?rNULm0&^P:rf;l"NrMM@,7h5(bU@;QGDH('eChY7/ge,^<3pVJ*%g=Lm!h\XSrcsGYA7m"KOJk2P^D+r4O)Fus&XKYpLT$I"4*\K@(FMp#%%GIt,_?:\$;aZ5,hAEY92o48?,ZW8$^,R=V0nr"E=Z4EShk!>kh>Mt";;u[mF@1rlp.LhPo$_[md<1;F?(Pf)TbUi*l'=sg-!,dN-'2kHbi:Q@C[KdMU.tkrof17IGfZE<8&Lg[:(!QZ9diD.k$AqFG2kNn1tLhESE'.[-^m;hh8GJ+%=[./G2jfdAXGL[-\8KtbTrce^)OM%%8boZ_r@fqfk%FBP]k.;T3_(g&\,t%/X@=5bUQnM3R.,)@eOdl(!HDYgC6ku/]BEo+PKQM)F+&Qd@hC;KikNk]=2?R[)X#g.mY&=bGK9I5<EjUblb17V%)h:j+NqepG7"DgCdL#M`!*./#Qtcqb`kdq--?4b[FM9^Zk@g;o6;],nT5ar2YV=c=Akro:gekU^QH,NKerUnN/RPiKVP*<%uQX^aOF!H4)0I,STB@BLr,UM@C5.'pf:9/U1[AM>?9pJkr)^^#J6ZmI,^JLHU)S6,5[\I''_"O3U1[!Pd!P%eK1kiO/.oX$rKNNi;"G_;Z1=s3%"L`alV9;h50cj>97)%'1,DaKENkeVSFS>:0LOc*bMM!dKS2qSe15J^ARf[Xt=e[qTeSUokeo:\d2C[Pu94!OY5c>9JNHDFY-,%Y::pN=N(+@I@<^[?cPk+Wk("a![#!bp8]a';5r741`WY-H)[MSa]XU-K7-E4oHK!9T[8`PCbiceNGXm%ChRQA7gnIh=kB2f$U!F>?>+s8KC9@'&>G7Lp=qS#Or4sr,"O)2fTLO'6XD($p1h9GP,[.fD>:N)Y3LdL`X9<&=Gd26+PbPK:@C)[Klj!jZmoM)0")RXD?#]ijpB]FX:.[,KRZ%=d=WbEE\b_Ebb'mBi/Tq1V@Oh[Xu;E7;;be^8(`?5O^S)/eDmr0-F>NXT3-$(-U_`W06O+]%&&ea'98Ao.5nQp_I\q=b[AqkGNS`?W`VD"QUT/r8E=CCE@1LQ=SQ%W43D"A->#3A\E2--/M,.=S:ZbX@!1P[@+(8H(YEb@rWQI5KU2o(3Bl(00%gZUVWlUOT9Fsf?Cj'FO1[ZUjW2Ua4ZfeE2&Y4mjlP7q8pROsnd+;>H&*lZl99r4p7Ap5tMrO)W?1a0(@TeFeESSeipYs_kl>7RDJID;E,"+]Vi+ej:=BMV:`WMe%[r7nm\Oe4@'8$8_7oBO4Q$58`Xn'R^!KnW?FsF;WV,(R.-*aj_5W;Y#;hbZuRSn;I7c3R;Jg!C^fuhKZXh&W;qLo6gS1h#qsV2gTQQF/bX6T;Yt_u7i&MBD.jNn?C*O]m+e@B>g)]9:PIVS/m[u0W.P?9D3U;mYQjiOD,("B7CCJ82uN0`IqcgPr'O_uI\4nMjO'hlo)nn;npXB-9R`?'oX]=S#P98:Rt4r(%#OhQcs!Fsp$C$oe:ufk'3@/a[(U_2TtE8uBSYa3Xu-aN6Su%$!MH&jr5%<@7cJoo;ZB^]rZh_X&iCZq_6b[0N*7cK&3_i"kGc)YLNFCa*1AkjOpMEj:\m8H"k80nPLU-:s%p1Rm^@h>b-&QW0Ht6ig*sT)PGLeom>+dYI!M1uU@r,`j/p_G#"R:jP1c3?PD61D9TrYN7'1'H-'GW.,.'RreLDsom!%qA@Bcr7^;:ChAXGb\2bO*%RS'e%08l(5fj%`d[6XoN("2Z@G4_!]l/du^`iF_j<1#2pB-2!!Lm30Den!HU"uI!U!65^r9_qCSQWsM;">Ug:%1AYE/rOKK#kabRPMtoQQBkUQ=[USUXU,sas$^0@R_Z;JdFjL+/k>N+1T0[<.C\'n"ehVC^jI:B*mRNk1WTm=P#@\PJkV,mlS-7Oop6Q:KXFLCLPm8<)aCWNq"aJf[A#S4Mh9'#`U3T\p'\%k3CEI32k!\$%p@c!]sZ-j@5`s/e5Z$$I2!bN0&W%uW:or-7j)D?ojm(M"S.ofP"+aPdZemP]Y@7(nX)_%6eVQC2RDQ>MfU$'.!bn&O$YGV-s7\.`Zdg66`6!fkS%gM^ol#Lod#]EeSA;kj[ge[K%8opU`hZ$UPPFAS6`*ch>^o+[F_5m35#D_@6s0_TcE/KHT1B>Xc66-n5e"Qo2<8+dg(b)m$o2OJf2UW&5\;_$]F\*0NBtVr(]2s/A\2F1n[#dI1SYq(GeH/j2aHhY+ugBZ(T'EHWYX>G2?(5n[$k8ML&Hp2K/pB%9\l@'NYf-(bg*+`5$Q*j*+>?XQ7bHHH7:?JYt'`84;i:HW1W1pah`%4_D]Uq7g"?!qFPmZ9pc-VClXp.sZNO@kMAHBu&`n(jO,ciH8\-[*&5iZ"3f@(=r>-21J8SAYqPsaMqQ617b)U*!T:Ob8P.#^RBGXdGZLJLlJFZ+X+fdHmj.7'dC#EntC!-%gCS91K>2$q(FN^8s9=,6n@pnq??m=%,7(O:ndDl)AQ&hsG!UjI2bR\Rqao/,hG2aGm%H`5lr41b)H$]8r#&_;[>bm:XD=KseMeqaQJ-H5=S);98O)^I1)Z)Ke]]Y"L;#q8=;IqRp@&UIe[CX53-h=l@H!!!%"uEAJlgQlilWq:te7H8;+3L`r?(&Fc7KKI$'g'-!oJ162j$OcpRicX)Q[7WFkQr1r_]\!rr?8!<3-pn&7FZOB;;NaY:nXKX*sea?!#EqNm^pbegQR%P>TK=s3q4lYRNA3?Z47Q$.@=GCG$0HgY%P$[*/l\$qLkb$\YgUNL$BQWln>8S(`*mEeheq0$Kc":0_R68rULJ(JV7))`,BD;#Cs0qF`XlB>6`2hPtqn\N(G/#B8WGf'pPa-YNWo=KE>\NU3TnV%R8Qp.dmL8&4Q9oKomoRDoHj4GbRe8?X3-le*?2!([/hBMSE)=A*H+gHXmaU/(k&f6:(/or_gb&_!^L40_r>BKNo;4ABm7pSuL;NouXMX_$,Anki:V5*m_cO:0G='fR9lI(\R@bIBCR2QqP;mi2WZ*d'Q+&jAO/i%J&G!h=;PGL3_X14LlX+d2+7MQmaW`Y4_AdY//P#>jf7K9i:f9[h,ZQlCYI+Lnj&>UEZ-\=-rgI`"H;5sag4T^j1.5pRCDJB+4:a?sQ`O<*+r`uXnZ;[.WI@'jYCmC..l-[.]Qi7G8":R1tH!`;DgddH[#!,dAO;_50T%QAhY0;N6&E\Q-a8j9TU^PdFt'$46e$#g.F*0dgaX=-cI`XD3K(-:h[7.eo;sht=F4rpHSKUCJWf@E/=;E,o^G23[@Sjd_0^B7%')%JsJrGPf=Ei>`688NNTl3D`cG5"$k]7:n*r!N\"SYEH`\X-X4T:p[d>V:NGT99P!f$Q,SrZ+s2sN@T"`lNnNBg["3r/nA=jD54WI3Wd3tB2P#3I%TNbRr.L*6qh`"rH6j.sjs@/>T\^e-@hWE']@%lDTZA?sg(3j\\15BE=Eg3@g*b;u#"#C-ar0RlV%1n-\Q\X,N'Yj+;B'QB#R_+l-d&;-\c-@]cWg:]\ZLCGLJfteqq6DPcFQkWA^%G`j/BCRaL1Y[fio-+C'FpI?gcsmN2)B49Q$iUI^KIKst]05>+b'W,6oOr]j*=9uhe6Sj<1iV\1j/"rR?+LJP#HW]6g*f6*(((o)C-i&R^lup\&DVLL1`fAQSj;0I/K-%\gd2W!O>-M!Kg"!jAX0"$p&%Uhp3tULC5gUc+O-2G^P.+Gcd,slIU.)AE%J1`'JQabgH[UtVKk(>1]raB&g[_f4*4ncfd^K>aE%\aoCgBZLkuRKIml/rc9J)O2Bht9JOe=rW,E[(K0j^j"6M0j)0ua&:k-5Lo3WDlo2^3CWU^\mr6mJBq8(f*l-">d(l>j&@g3i2Z`RPmIl7%m27,j[K(J!RnWO:='0b>rk-R!!'[Ke3Ob*a^KM;I%$K)+f5AOhrr*Sg?H5E5(+lL%>1pp"#;;E6Q)@m;Rag.]kh_R(Wob,cEd\f(0=$)+m:2g7E<<,Q7(p!3>C+P"uJgZY9=VLNXTnJL6\eG0B,bcEJ)BblqYEQl?r&D7&2$,!baB1ue.Vaur@!+"2H==;VES(;gJ:e5QJ=1kFq]%S"T_!_g2Dk;X-YCHqGRDM+/U:`;2R4IP01R.aLV-eE=,/Ms=F)b!9l(`1?n&09UC5ZR,6184D?H3(,g2YH11gP,e^PkS<+0)oPGN`ERd@O?='[;+6]&AZ,_C3_4HHL@mH3lXVL0LW++cfLk+Aqt\[<`tWGi2rW`A_?RHE,>_-rA/]:#A:.];U1),JgF#O+BXG5I8q9R7DBl6$?Ulou5+$u+>l.b;UfRn!"Hi$V2ZlU([3&;K\'NbN]&o'l,XrXIb4853(b_%s`TS-81(%,#D>(.lCld2]g::Eeqol,9;NpX!fk%g@K1$;(GHo*lr:i%m\!D$F/!XJojAf_&?p\W9D:T)8Kg4jARk%!I2abq8i%uae[72eC4Idp%Y(E8AGBkjU"++WSd`V\!%Qk[;H)[B>C7>,pU,1.7b+/=>1;GX0nq1:;^A-bMu(s,MI4R:re@T;`MRT'C/"5iaB[a1Eh[7@UujSD[5+b2!YUeiRZ5X'm=V%C(0EW&963AWs$.`bir7mkr%s"+&f\E(>/V3js6JP"ulfC/?D#,jipGUBCQqG]PDXQ.kc:CnI,L0R2XFqQ'/XkA=R8%d!$5S1M'P9Th^(Bq8+_@6LZ1mp^>:,b12qLc?@0opt7?Z:Xb48V+OLn!K/U-P`!M+!5W-C7>7>;6^F_5+@YK5i/E@A,*&L]h+i+QoHXF0`H;=)?A$m19Boq1kOBXupa&D%]4^jdqk:.\j(Y2Zc6O&a`Pj:SS`XVuu)f:IjstZaBDO8+f*#".?!LpL&5d$L=eRWMaITGc"pe`W&8AFD&j/Zhi9hc6)&,9=6\2ec!VbBliR'[VF8W4n+TGq_mR@UrE^Ue62S$[\s@A/?c;Kpq7-b+R6[T@U$*V2;agXc4]u1-EZ8'H:bHC#q?o$.@O@BWHlro3FNC^2E@Tu6T57HDJM"iB*VmI-INd&F'8Nj\1aXt.aYb-#a8Hn>"?=2"&-bZn=Tf8!+a0!Y(Y7'BYs/X[g'r?0:M5aV>'omhDr7R-$P,(eP9k21;Ee9)/Gkhi+X&+80V+2o3B/ZKbGXEAQo$1pr^8W$<*9]DXPm_fpH.!#\3rhtWe?3o<=!Z\%m4#AY3_R^\';)AXJS&K`'M5f,B^69\1&s%VQfcG=*7%<@a9(r9KV8d(6jU!RQ]#)]0?jc1r@ESXjpnDigM3M5M&NC-7_d0q5p#Ds%nL1or0*+R56=?^)@Z=NY,Y8;_IaCM7m0N[l>6&?Y@?q&sfI'q=L1^-Z(\AJ%hRfoKd(9uKNdh.>f7gs\M!E_,,.$)4E;i2m]BSWGarS?e>R=niZ8k4S;nD'_'$,=RKWDdSPl$["m.OXnqWP]`FRH`t9^;HW$)U+/M=Gb=)*6&YMBn-[`9mO&3PY,\:2"!KcLPbs^HHSNfDU]Pm?_%.]b+H^6o)eViq.N(ir1SHOk5BR]0VC:m8;;Sg7q1.Gj_)kmu%,>MtoH2Ou;b]^,i2tZbjdk^Hsg.>u;aRLSQ,WA\CMJYJ!'QS)3;?8Qu,j-Wq-;3nG/rQnM-p_*l,(``1h9,KT]:XSP$df_#!U,"H919th5Uk6Z2k&MusW]/JdEmeS)9C>-`%^h`>j!`O?lh)k1dlKM'(Us:>]jmTbsm>8D*2eAQLAj6/]e.AQCB`;pdpLc[GV=p7_/pa!gd!hccJWlC6h,/%^g::qRbnMMSQs$%0%,DV;8s%Q;EX=/9q,"L>l(fY:S+J6S3*2X/gR(_FBiA0L^LYut#@eSbDf2X&)dU2q?]CH"MI'//FRuBZ7Y2+ba:RrdEL]X*D+Z_=5tp#hPIjC9/S$YD:i0*h-%/4gm[lAoD0*\LeS1W1%,c<'&^lh9iPH*H;Y8^DY89`r=luqZA%u(%XT*/[iI>Jr]33A1*mfGohJ(+[;p4et,j:I:=7E@cOjDWYR-d-PAAOs'm^"DlhDi%q_Re2V@4+Ii56TgmW/e$F4>3^J72`gZB$.EUA=rlsbdDd2a4r@W0%$OH-;.hY7NL,caoupG)':8[3Yoo5I9o`+h92c/f3J98G"5JF$.nhYXHF`#E"AqG/p.Jou?]P&m))[47(^Rh94\lL:L``h+Fe2W-*_+@!kiZ)'g0cP0E9:$\+!Y^8D5M2RHheb9LQ3Pe/c9,0s,LX*`^J[Pnpn+'7WIld8XjiQR:iOg>Bm)FRS5I>Mb.2B,n7WcFn(FK$X6crj/JT",Wsr2_sk@;Oh;bW$@"R<0OqJq\T4ZAI*!I.IUX\M/m8$03-r:f0g)KBbPTBW4769G\G'Y3uHHct=F$6(&-?!mD7nnBgsW[V>?(/>?4p8f'ce"J4M+ho#(?lUdR3j\:kr3gb#U;I$ac@dRdUMD+2!69lN"@"qkk'5IF_CoCeJ_*AuVD-!WMk(*;3Ph\YGS]jp?P]8H:\baM[&#Rc-*=7`(9`XIMOF!G'(B;;Wqqs+X)g##7bhXs)dA?lX`C0'5h09-$fRmnZ3u!s^'7:82WY=PY5nIiGc*hjY3TMP8[10T1.\#]meK-%fY4_p,bSk_RSp@5U`7F%?M5H-Ir-*i!eP.S*4e0+p6f",QAu1_)bd/uB&1SXRE4O>pTeob/1][,8=0,1o.id]3aZ;,%ZCBTA6!6+%A%h:8\O6V-=Q83p=JT2K).H->j(bCc1l>EHAn3fW+=./r;OU8e\2N)l/2g`/4[nW!-r8u8^p#eE\]LG)W0M([\XL,^$>6Aom+LG:&YQbRE1l25$'[_%)#/12,aWW05Y_SL("!r*q5rN1_Uql8L_Ea;Mid,hF*bN7XJ84RaTjd4C$#.GbO^peAgp<@[49aoT1?e[Y7N%OcCkSnoEs^.^%;P/::LCa'rpd[oHPID"XB$3WTl=F%6ZgLD[d:N.#R,e@lNmQENX!prh`f7rars4A0h!#li3tf`JT!Dkd*eAhBjt7Rk'A-:H[N.I7)A@[lBRO\P,']?.:sEMo:IJbaDg3''O.C0&@5AmFM+3B"s9Z;08)3R+ahRKCS.:[hqW;Z4g?4;BH7:V;%f7e`e02/nk4ON6?6CS.GnoL^km0LiJM%6kNl9FVmObZM2@R)B]lGFIK(s<2-7_%?Q%ma3RZkGP9Y`KDW6]&])WMJc2NVScZLqF^RG-5AHdYLGdaFR-=DY$UN.Q`SOc!<1&q`X6=O-[K-=?"QZ]\o)^+U^lZ/]_.@DtX"!@0re@2KR;\_\%AdipLhm<(/GEuorYM?`S,Y^ndu+W-]_J[s^09`qGrF;!mZeloea!kD^AL0:-68DD(?264lT017dTSOFVnr$"T"O:fJ\kJT.+]OEU>8F!N,KT($Dc:*E<%9ej/O`$"6LZ?SE=a@&!IkLgeS=MhUi3-:^<)BGJJ"226ZN9;'&ZY"gIeIdOjL(h,PFpAX#O(TgeMm]WKFY&1O)i%BL<,Ib"#68GhMKTpW8I6VhHe.q0D1%s%;T1_c,jZ7oH%tZp8hAe\F0k0o1LX-"Tl7dQo*gJ0o3CCU20ZY".I(0of8>V)uQHPgCQ',SW%7kB$_1a_b.2+\X@PZt.Q&i$k[#WnS<_L-F+^paT0OT22TdZSYZAT&,<,]?tM%VA10?X;tMqk]?Lp(i&H*+(GkT,"S)-$l_PBZGUaHFRCeK_R\$I'HTV6Uf-3X+M8?:i.bE/!^PbdK(UgL*$&%Da;34&gY;'rWX%rdJ3RCd(ZZ$1?NK?ai53Z)6ns*I8PZ]H!PbX-Xh4cA'k`eW;C-!Y@nu]r%k2XR@P.3j-r_\%Mf:g`JB>+M)d=9(/s"&qN&5I0\APlqO@OKBBr*]Yb.Pa0bq&Fq%)(#p[CX.n+VIR:RGB,!B.sN/83Z(G"0WOqIq?FHn^FjZH%)uMVqu#[AMa7/8Fm)0LN#+,_s!p(HkR1gWcS+&D)sjF1'87q/bB_J,fW=X+A1JP`d'^M-N!SY=?B6ZAE8A)f0kDqeJ<AQQ:V+QPi)+p\>$jP!1--R`!o!PK:`kL4"_QM[?-f8\[Kg,\j>:(T(`.bgb1q6a5A8.RS7WLBa.I["SW(H\FG2Z%?;8LR&p-c:L9]m!q7VD4Bm@/`4%[<4b;R%N:q%pK39GFDkb3ofM,+2XARo'^m8VDIpe`.G6s-(m\Tml/fbBQZTq)-)[BTRP%pS30nZtN>g3\6TIn_Rs8Ll20p]Gk[YEP,<'p)@N6c(IQ'Ks09nh;fZHt->P]!%*c*,ek@HL.1RR%l+)RB#l,0%d"ObHB.MU#ch6%_"gCS2s9BPU?l*3/:#Z4#k?@HWmjr$XVA3s3UatD,,RP4Wi_a*fJ:kBC.k&'n+:P[4+JNncFc#`6E4trQjNYg@`&l*[""U)_L!gnj=-5BbL^*ccX%=[ide1U!T!XSbu'd9KqmC%^T7Y;)i1q[VJE_3R],%qg=Y,EJn!s.b3b5?"TOp.e`SLa:<[7*p?^\!HSToVDsjG63<*t6CC_C#S8p9o'Z/&?JTM.=\9fY!(E>=JcU0M8f7Ulj7KR)YMtH_Go25JTSRdXUR*`[!mjme_F31VPffIE%B5Z4RbQY6nu>aD%aPNj+%YDT%0tef!H9>*"*FUc)&+5>73Mk(%t,L0l3$Rp:C2c&q2g&iM2+n7FK*a5]e2[6K+)1L!,GAf88q%@0;::K;?>[PFZG7QYa!Q[EEL:6JAB(CdT(9ItlSORd9_oR#C@#t@hcRKj=Id*jI3+pODAC!pU-8/QW*bmIGJj?\t6-Vl[jg(Rn`@?GMp^p_OT-719/Q>)n!<2\^&p,0[#+g\-@)'[DVlOVdq5W(.KL8!Q.TTAE]6RRJ9A4Zt@;B;atKujOo#+"2/58$4DN^=Sg8/&g+`887.p4o!4Ui7'fKJn^WJg_Y[F7e`%g\IQen.:+)-N2*.W"kCI[%t6"q'r<_HYD93Vu@+FULjcEQ(HGBTq^fOg#9j.iP?q0mfu.aDT%36mH60KLYa_SHKRZmB^TI/p@Q-Np2qP[-*o=G@-6K@WIcBSJXpZe)PBjcIr]ODlii'Dn#X)2uYY;uVq35o>)$C.oIPeDi%n3R'RPj^@;k9gU+57RAN`O\X0e\uk43lE?u/UOInS6)me]!D'Y$U$tC1Ys>-M=jnR>BH*rV5nN_)+Z^.(L6Ec#LYDt>M=58d>=DF=@#R.G!JHS6M8UR%S.Nu7J@^Q>Dm36e/4.>2"]LR\(a8(qo@d^;'-ZK^&;27TA0h9;n"2`,Y%(\<"TpJK620*I\,TbA*0O,u3j)kq4r(r+`HlfmeT_hq6Usn4a5^j#q.hmO<@H>jT)).7!>,V/CUtZ/rj6pA1BfZI-gSro]nB(m?s=Z3W&j38Ij+):4Gf`=JaG_VRnBHi>j6Tqi5=':.\s\5<*OA#^^$I8J?cS3hEFs%"6%0+);]\WZh*,_h8$a6p1ej#,6YkX/IK7&;3@!!]nDZ+NOV,Likc*N(?2V7RduC8#>D!+S2UH)?A[8pd[WU&$1iYc7To&Y/hCTH>GIS*OXmPf_sJIOtm2@,9h6F%#/2d#\($ZnF+d(eZ"S8\#2Tj`p5\I$Ui>bg#LB36FWuH/8^QT)`).b=f0h>XP1q$WKsehBIOJm5!Mt\OUU`@.!sM?!%6JOOAmJ*HF02cNp)LW:?=SKUl/[SDQBJtH"'6p8tqc4?`C!>c`K+@0B=7*2unEc!0]5WpO%#R7AU8&6"8XaK3JmQP"Hq;!2,P)$:Q+mH0P;L1[fd?T5Rf1TW,oW6"`rd1,.9k4BpPn$_pCMSZ^R7?)KQ4"(K9k&4m:p0oeMV>!Q-K;)!_fTLDiT6Tf8U2$MQW\k!b0k9>5RqececpLCbGiB]F+@%(O,Y4S=]n20-(nbp5Ic21rkh,GQT"4%*VK:o62nY'Sa)8llB=W2/"/*g>P9`rcSo0]Ft3(iAmH5(CV^k._a,6%Be+s@b['E\5S6lLrp,3kbEIUn7e]SI+AN$?=u,_3=p6p)X$m(/8aP!4+PlaQ-2$@%M)*K"CKE%V=[8#\SGoqZmO.2ph4c?VSn7ghL@k4*kurG_ZGLPZX1*@/B#UPGm>$77X/qqMq8LWgpp*!Pj:AQ0K[o.pVF_5]:F@XTX@?.`>!7"nN*"<'G>p%8#hVX!_X"^VcBbCLPmln<`b_1ECV^-"!VA?iuu'h2[F+in$krP4UK2Q!45XX_;)QIYI#gZE<]*6qfi\A(A4KcJl2BrF;:4u\*93\9K1CU\_+8nSB?e0Hq:X'H\Rh:1rE2L.)\$rG4s,s9NY5tAEjdfCWQ91=,ql"bT;_Y-ZZ,1DI+J1'_TGsH8Rg<_6^]@6UfVq.p'%k+m>Ju/Rh%)@3'+[83EpTlY`ruciA8:Yi_T$H7\J0-]l^ENF>OcfGa[ZpehjuX3A5:4,UclPR8OAHVpQM[$q-*D&(gM<%>Y#WD*lO:?2Y?$;rO6=rK44Xkf(dVZ-+%PQ)MPPqIKZDZmSF@4k<"34RH0[h@-dJ\6k7f-b=TnotLT.i(X%P/3*V#k[Vpnt?CX9"0i8bB'0\5D"5R6p@=0^mgd5gjoZ/19uJoDm),oXW7&l`D(pre<'5o]',:QcRbt0ck1f%_Je:#H?4[n"]5Yn@BOHC#6d_nc(I:fQ(g:HDs&WKI/A\3+[_Ibn:`Kea+Dl=gqW$.!lQp4,gHb3`TiP@A>;()k%Qc]582Sgj0/ETU$QZ9_C:QJE-C/M\uPtcugLeo7=WiC1K(r)9r2N`Z;&mkZaD&C*qqQ;;M+oOR6^57!M0`M9s2:89sFE:]S\'n&J,;EdG^'Uu;IV`aWf+NBbnK!0=DI1GYbKSl83]=_;*/Xb0lfja=:JJ,h"0DPQa'a;*8Ot5bH$F#/$'k$e.ci6KS4//-rZE+-dRe^;<>96kup`K66m_b>[]VA2L-(Rcoc0%np#M$$MfeD24+EVo([J`PV[@(lCDi^)LNm4%7!?Q`:O6H&kT&4$BLf'rnM8^\[T5Pc*K5nQu^M7+o//7!Do4/OKLD5J#jS?P#rnW,"'_oQC_P,+m)_G1EUSLU:W,gY:7DPYJ[us1cY1&DqXCVoV]&ZqrmPAT#gOGckUVDf3jq]1K;#]d`'^u1o6YjX*HOc_:tp#&o&^ln@b4A*!WMIT[lV;N]m%\/LXd>MP@,N#,rm#"pDt\cu71Vjer;Q-]uGU@CUI.DGCPVJP8(4lODg\=/'ngh;jttr@%inn+Y]$4>+^A&>UHMTVtha7R4D9)M4]6VO5M$mpP)Ih$j\"5d'&4d:IWGW^/TO)$qC)k;O5'H?g8*JZ$&090<%A]IqOL6=rgI8Y"UmH-S1U"Y&#n^5#=`<7*Z)!m-EYh?XjMn>Bu;O2%k)uL+!,Qa4N#RPP4#RQo<;@X9^OWiohD$pjAicq#FOWFa,%M3.`U+&n[h,N/IkFEqecgp%@r%k$k+S8jTXrFm\m@%$A#G(._8dOq;__YL!f#LNq0f10;l"h'L'oB&>p66unKbcp,?,.-LnXG\)Uq82[Kb7S&jXp`&_(oZr=.7ba#4>\*](aM@tJG]+$A=Ct.#D;EI];,9!4-R(V#..s]C-b5[ir:$IJ!$9U8gm,9msOXK#]OG7q[',?)m6B&%-*PKbc0+NRkhlJo7`N%VM#:!9SG@sf?]H^[pg!dl9gUTXoc1'W+B-Zg_N/r'lm2SM/VH1Gthh&h%C`_JIR6s@8$Ela8,,h7A*=J`/_S$B0]]_;:L77!!VA;G0rBj/Lkh).3F8JWVpNcA.N.DmKC=r1KFW6&aT,".Yj/D=#XY@8Y8/`-C4%RTREOYJrql8@R*l.-lQ%0+JfPcC^.egUNBYLi!3)q%DpRH"VXN6aJsB;G_;uU3h2f/0n=&5A$9cRBcoj%ar:f0a,(:?gOf"i"U9qG"2&.Yg1W6r,LDo!L;R"uh^BWgkFPNV0;)6qsi$K08#(D1_pUL)O*/3D;%Y64fDq\Va_8n!9n<6E*3Y>7@Je8J$N/^CEH?cPBn^M:oP_j$CkOE?cF$H`#tTo&Cct9c?\Z_O3CJVmh1l*?]:UC=hCEY:.FPf9''"<8XS?Q&?A.WiD_lR*]B.?I\;kg5j[Dk>DW7M#%8KF#ENC?@$V%G6(YH!SY,4RX4eP/"7-Y\[;8UgVK$4Xg)oXqAd.c[F2TqCOT&\M**6p_Nn[=OG-@FA\XgILIic?!KraEcfKaU[t2UfLSsj^'W;GAN7:a>2$VK%]:D#f)eR*,[G;RUBkF+kgVpiiDXft;2Icc,LD0=mpR1D4B0a_l:PWmM`^-Za8ET.Vkf+5^$\k$&8)a,))XY=Ld!f0T1If:hNYfj\33Tja3S5DeRd?fF6M2bg\YBu]Ikg&*63bYnI.On=eMCqH=/S.2+!@Jn/`n9$$-Z:DeOg0U*BJ-)b^KZCNrJ?q6oRaeP?*tUQoL_pcHV4CJ[".4B+>oIe[L_<"^2kGU*KOA8V^qP$6urnHe12T@g40=r&M[$Ih+liKp86V>tc>+ZP2ui7,(5CGg(<`KdYiD`dPscjJ)B/rm)an@)'V,:*r[hZfd.0+qY0$9/\eKDVK0mni\WO.^"*n`qgiD)4jL\eS)C17`7t;JqtUWBE7AjF/KgbC&;_)aYF1eTI#dqV$4A@e=T^>TNr43+m`u4_(be(G4Kr=o$tOmo6`(TcLIhj4GnGN`5nk`XQq`f2%`TAi'Y&K4BFlJk21_p.j)kH*SLJLuc)#>e*_3Ku3ThWI_'8c5rjlRu/dSlStX(Z+EqsQnLX`qEVNL8/G-TZm0mhD6X)?duH(h\bdlm@BI,Y8OWg*G)N\[=e6R>qX!N]kb/W6"Ptj-7r:3g0_n:Jqt6BJeW]Pn,VJ/=MjFQ/p)D7/CBW30\r+*<_W`[1,\F%.EnoH;2[]Vh)b,a%fkC4g!0YBnWCgX0\nC@Z0dX^6F!_LT]'=HRA>_,76'174++-8_em['RL43cL(#.S>;h]-\Dk2"Q-Z3_`]jhJGkX[GepI/-#Rak[ICh^NHW4Q`+%N8(P\+:HoZd8&/d)*17U6\53Hu8(.0^8m.[!`j0upt`rCNRliQ5/#Mir;6jn_S]-9QDYn]U;AY;R\YLG`^!2E::8ip%&sgnnQ,6e_Zt)l$Sj(EiPuEL+[NQ&Tn(o()^H,B,TTu#WPaM\6]^9"T&moH*Q(VlIrp;KOGni`^bXT:qb@DVH@:-V@#bPDhU1!]dK^*u6`>[unA>I3[#nKgU3XYf!D$%_ba#F^lRgh-]Z)!k=!)cR\?;Ode--?'UT,c&d_WoEg9cVn$jQ]Te#ZB4H^3dh(3^cl4XJW1h.YAKI!%7a=25"l^J0sEF(i1cV$&Cmm-kQ+1JsZ^BJ-r@Vaka]iUVleNOM7<=`M9e5?\`bKJn4%"q[8]pD(HRp%L9Mp??4$k(lc2Cg,I:`Ve9`8g!#CfE(h[7:T\%E>aOq"1n66^Vjc-ih5\=,6qQE.(Bpm&;#gX/W3^:p",1K-1d"rW^ndVXkU+uL9JU1k6ner1Fnf?>C7CY5BVk2#os=J`!I^[.C&!t^Q@t>B&oO?W8bD+c$#R)e5MOW&WA4hXBFioa.VSJ2AmSBaHKD+\#XrMMr`A>2D@+*Pq!20n5_J::1=_T:Gf->cDgToE)FUC)It#CI`&OlVq>8;m3r(cM$arn1]j43CM(MJG\.IC10FBnl"E,a3^Q;5h%53P^+_N_%s0:sPLrGhq*?D6lE&^M1@@co\n/[5_;gC)N(bX13>HLHb&d%LIq2m1-G5'#'JoVnNQl\RKhg%&U4mi%&Q(@1%JD(:kXX;:gnkmfPIG7Mt.@h<-'te^FO^`GHqd%NXlj1#CINI(M#H3*Y^n$]@5H(M(9$Kb=>7IMaXU'$TDl;[qs&+e&cja'Mb7t?ppk-&THaSh0stoN!?6);HeB6\,D!*:mNdkL?aIK=fM?F.M4)r%P)T-h8HENS7&q[qJK\eVb%Vl?0^P73'26E^$]C,=^GLl9'Tf]h:#<[%>g-$*B\7=Xt+eN@ufTIdkn.#dSGXCCG-!mV"uMTBr&,s]r2b1LES0]CY47n=@FBd_@d5RlLp2g_,=jibWdRUF?n3`e)>);k>B]MfJqHW75XgJe?`'SS.94L#Ra[`D'jAKf\u?V1S8JfIX7[o$+-L%[9=@VR*'-B>HqF*N1/'!eMbA4,>JcNA^\`:ms&^+65"2=LINomn6)TP46_=9@tTWVY>#/R1e&7T^EWfRS.YA!NBKHbkK3ji1!8J5,,I=1cS+nM;Ui0.6._4]]iQl05GFa&$2V=T,l\-)1QlZJPPIl886Z7/Kpc)r@&@[TNSE,Ih+R6UZbeG7-\i=,-^r@%]McI3F_e?i;+eBd\RZ(:ml1h0in_*#UP6iube#*]/7ch:7a(@:H(tWH@OhY&HRa3sTK;^jJI3/nW,b=T9=aj105>]c;=*5[ekQc+P!)3(T@4MfD_dQt.I&ql`Kd(>XfJXgcuAnp?h6LB0%nCdqW;(EoR_"PVOTiSr)LKGWr]BeWMBP/.*Sr)"lntRGZ?2Va,CfWSU+.n)mmUIrH_"-I#_#[pu44j`/rchQOQ[35mN!hpYN1aRa!i"h,)3%-eg4:`+WIIjCT&j_(PGsSdC'B7E&EFGf&%U:Qnj!MclbJ7$b->%^3#Cb@=j,A^pL@;2W9^NGXS40TTqYGE_)GVeANN[@GU'J`;9E>S>kl&CI@XZ+i"rp!u2!gQCLVf;N1LQfHIH@:;7FnJJD6*3pS<_%/Oe6TUQ+E2U-rN73jad27382G&%n9nXcWX`H;p1aW?mm/`Y;5HSA39mo\7%6$R;b.tT)!P[Mq`LRM4<`0CaB8Fl;&H?h#oKYo"pN0VEORiOnX"OYNi6[?ZV97/'>"-A1F3L:=L-BpG;A:k+E4D9HOp'u_m13rR&1es'>_b>rnO,T)l(<2AZ['\f#hNP\B4hC,sZaA4=QkWrHJp#s2n)j"b?Y/\OcWeuoioLgadiAga3Nbhp8Wt?OkXgZmB811NGdcVq0LI-D27bcf(h(aO)]WYL`=lmbaZ43!CO7E\F"8!O=!JlWX;NLUa4rs5h"]Z'.eT:kC%*Q-Mb.Q`][IN3=rC+\U1ifq8RZ9BkHZQl([/3H3qkigk5&'89*6eB0l2Wj;LeZbbO&E'KDDE+gVo@:Fk'6s27\&H`2O-#=kJaAYQAgY_tO_gl^7!E6)(Q4+1q<'?WUTFpn(\/Kb59uqrC+\L.5.HD0T!X><#7a]?-%@"pNbU4i'!)e+7mS:iI<^]qf<('SccNdb^:`tY;U*^tJ(3kDE@,]HkZ*Rpai>W$;3kDh?RPL]&e-RDTPa'm>&E`7@(on)QfnROg-(9UOt#Rka2_\FQ"AgT^`L=?'XDkBfMLcB4F4QOWF'c@qdjJ5u%Cf'FdM="eb4UU6W,TknJW=8?%*:GR&^PU7(Wd$m_$F<##Qc5`F3#0IFb=BL&g)^EBs,Z)9_WrO!:gTesUN9.Ul3(.f!EA.\m:A[%9C=;DQB)p0T5.&X@c-u$[VndqA3h;J_Y2F7/N>s.gh5YC9.T&EP(ZIMmcY*nFcO`ne9AEqC'EH9g(6eL8j+Z":_herhHcM7%bR_tGe-5mQHgB_nZX.X*BpDe0a9>+7ZSGF3^_b6:+bL;Z1NigEDGj=<,;R)t8jQmI`\WDpsZ>/=&i#)[Xf[f4+3"p?i?:p%[8LH5U\`p\GL\;MGO9$UM^M-g;m""[@)qM>_X=(K/K)[O)cIa_@47SihlXmNNaMi-'asK!,1cp!YM>e:90e]81Dj_Z2*7>",_IR'H`!#QZE7SP"pHk403M$%,XrV^(G-]:9J?6h*q?YNW#lT'o,:ep#X3VRJaTfNf5qX0s=i1b?)!X_&7t1'%l>`Z1$qL_iT+'(%%Ws8dhOCCsDhV+I@oc<.'L[a.K-3%b4-0GYnK;s.&3lrA-hCd&c--FD)N*uB$X1UI+I0lkK$o>F&8Vi:E'm\\:9\&]jFJH#_N*'2h/C%t/pSjeMT!V=WhObf110JTY`g(P$V_1KM-X9E&tETlTk>e/<]KA`8]rZOJ4Ii%l!DGDo7-t8GI-TS!k&nt*O[)=$bJjuc4<#Un0;?VeW7HlM)@lk%lrQtW*O#MgXk"-'`E,shTn;N;p1=8sX&Mi=-8lF]#>-eT))]Jp;.#]!nLp0_m+BVYFRkmH#*D.RiBk?rNoeY;-MFB%;g_bZIj&d>]q*0W=o`$+nNE^XnrT#SlA&`P^g]qLd-YTR4D4q]=7V\M:Xkhk7?u(9Xn1nrZahY+,#K/^#fm9G4;0g*Xd+*"nT17Um*/BcFg/,of2:!"84f05rGKH@h8-ppA6N4i[30`hdi9Sf?UDW0!ErT&^F[pJL0GFTf[t.._nm\Q28JZ>LWCI?!4^^(O[pF@_\437m/o@B(B_#_Z)ZGq6`4Z,C!%qJJNQ7L)X'=2:usH3i1]*6E'X8^-C6V-P-a$I_eOs3A_cm*ZSu_SRMa(UfnN'$-N/R0'7b$=(1:Yae1;Wq/HrJE+BbdS_J)%#8_R&JV?7IPAQK8T4#iqDG%3TPm%<:bY[KH;5fJOtLR2%360Fpb&3?OV1)1J8Lil(pS]6?kW>FLne^B*&ke%&F:"7PJlq`43Ae$>:*,E1QlM`ilocV@qj"ONNn@AoJ7PRB"WfJ7c]?;ha=Sl7H=AjHaF-`H'JaX$/20E'(h*M7mO,%E9*n!T,BWP2K-jT[E`/'QX&dSJ`W;SS12/dQsI&G8YF_Nr2>:"!m"sk+N>7W'%&]pGhUBne;d>DbNGl!8jO^H`FF&WMhJoB)DG4g1+psV7$bK]V&.NnA90X58GUTIEqjsKhO4q]8I.*cn$^,RmbMDCmd1.5krTi)MGMc_F&'=>_!C8..Y(p7r34SR(ff\q-+N5SRPfJeP'$T2`OaNkhW#\hNoCr#!u1G"-4AIh3B,D#?HQ>mS)Mqa:'>eO("6p]f".8]l-eqJ?Hk`h?*:=Z;f`*utI15XtGBW;=O3eL)Hbs8oZ[$7^%/M_05h\P[i]91AHYAlrnHhf`c\h[P8_rp/>X='jN1s^Fb*L!d,>XOLi]qfM)XapK`0fhP__2V^H`W,HTPD.;?i+kQ%2sPcj55T#$;RJYn-tn,XNal6t8.X:j*3XfB4OblnC8H*sR%=W2hC6AF@lk8QgoSM>+g@1)gTg1[a)aW<0&W.n$8kR?C`G;HI>k(:Hh-Aj[Fj`.H`365E'"PT\D)@RDSQ&H`V8qVr-OLRVUQ[\G+E[V]]@C<9MAB!Z?OTs1qm-)L=LfAc8&>NFZX[=so^_eq\p])(64_VqFU`tI)748.8rgW1C49HELk;H./SsXUP^iCVM,CdHj_:!X;okJGM'BRg-((S,p#/UUH#S"id?PnBC@1S^h=[%>DMiA]B7OBhIr51?G@D!o0b1]0R#nd(VmKW:MnI*t;P&)X$Q\:%3"[Grt8>h7d;^b!N'Z:?oZO7rTUrF%5^edo['.KurOk4'EQ5D9Q"EPsdZ@<6s4Z1S.h8X"j@XeA.?8L-CLNmTBdha)Z_/`]F;d^2r:sanA@1Y.1oS8(m1"jT%dR&!obIq)4q;d1oOK[3_GhOV3cGE$[9G'2PX'eC0X/SL$.m^AeE0J`STmd^7opZ_eIX9:&,g"5/iMjBMB.:[PHU4u98B8Y9Kh0^kKlEKVOMYODY:-!+mT!c>=;Fu+I=C==H)Cs=Mp9l%4BVPT_uU70Lf2V=8;j6NrsA[H0[C'L.V.9TY,2XsiXVR;kZ[rm[q8g`*Wdd9_mH?H\gCDDZ*O(Ulh?\Y]7_:n3!br.#Jg.P#;f#`e$Das-MdL'`'VTLgRH0:?dMF]%"Wp:t=(8\DieQ*t"ZjuZ4H2HagaX-6G`M-4[JDQc>5!WkXn.`9/bph0:"F0j1S:@PI#nm)DQo>""UYAbPpmD'E$f)htI85uUaJRt/h>Yq+VbA3>Z1FUg/4]lQ7=69q!D'.YBWW3l<46X>R]b5lFFfouB!GL@;/L4ffiuO#.B&-J[4Q,Oe?hpsK4Mr\"XZ"LUt[5!W,3h"/+o*,Zs.4O's$)#1&dl(3]3BN+GN#'n7SY+?B`0OEt0l.CfGX='*Q[%$OH8K\Eo1,"c>S359m$uqnDp4(B0hUXHqWZMcHF1,B:aQ9U.raInDPl)X:I+>$Qcg-0[gP.FLaTn3gS&rME;HKePiqmp(iG;d%3O>81Js`:*pQ`_i;$2Lr/#'\F1\;K2]$QibaH43r2_E4X$279EZQ2]8-33Q6@ItisZ'AM\<@P(k@(OMZXSX8N#("5fOHK0QE15qWTjOiQ>)`jqJuWS3mJdKk.O`(EM8$;oE;cE#O9aAdlL3PgE8WG0Y4Xs4j[FhWb@LCMu57=>6/ftEl#Ir.te_8'Rk!$FXUV-JJK7MJNj/$U;F-W];FijOL^3H;jH2c8qg8EpRB2-Vg-gbV!;RsUn/][+qUMI_N_8Y2:I_'G2ecB+6;Jd(/@X5>7"HlmUHY5]qao6\%_"j.6/"i&Ic_CLTU+'iEM^L&4FQVC+O]G#>uHZ(.:6AdkM,m86VP.jj;:^\XY+GI6rE&d0/sl7-5A,cGr0j2"*-WCU9C:k"LMtpjgKY:h38[E9#4l'EjU73__Aol(Sg[#FG%+4K"iVB;NKr9C7-IKE7>e:L7;3W+_;)ET'V4lO5c"VQtc:O"Q0&8bW)fIQ*q/hquFEnt)E$2mej$&Ys4XkMgo=:[P'gAZ4ZpA,7)D7J),RAI3iT]^#R]fC65t%Mk[na/k_k#NC"=]PY-K>$GLsQCD0TdFUDH=pfC@.LR840g/WL=WbjkGmg^sW5"$^TPOYlB\JL!k:997b&>eceA,q+V,fHA]=R.4%*tp23W_u]qTS9\b];MC/NL?&>]b:Rd]8_-plI?+A2T,F=aeJU;@%aNL2-q9>97[!@h@?e]/o"B]%`B[*4#D+GC$9hW[b$Lm+MiA.A#hId*cUDK:PB)a,Qq)Rj-RTRnHd\CTG-t$7/TpC+Y>j=uA4];/6Kt4>u9aKgkd(;qSj7k&)@O?ltOELklBA.4E?'l=$UjRo,RVT*9i-m&7Pn+co(5YgN0+d_iR22!crcaW3@qm;pog;;bHBLmdA[_l(2:)%g=j.6$'M3Y="gQc)H,l9]Qj7(]-r)PTl@.2FE>QIMn$"Ta.Y,>>RlD`-J]Q-s2A8s?oo"Mg^eiW,/L@TdX_b6.NiPRW^umIZ0/Xi$=s(2Q&rD7^8"!^m]tIWT_E20#XrWiE)!Wi]At-ui5<2b=_2+n`4qBeB2?K8F6p_Mf3F0`C`$TZIIIRLeGiH=45bfn7/^2BWch&p;k8XuiJ'[S#Yh9ZkITm^Ud]\iZ`\k3>TDSP%#&gobGS>3<)ik2(C<62D7N+,`+9!uOh;E*%`TM;('0&r7*-+XBBP*PkI6LjcqcX?5e;mZ[<_%XjmB8tq

_''>Vi_$7OJ9`oegcmPg[RE`B[E\S&KiPCk:dM""YZbr0Rb7-IkREG5[1A?E$U*gUUCIOJ:.=2*PHTpGO"q>NAsA_\"n#Ri:hX0rAjJZGb-X0*NHYn_FVe9n-$r;aYtte_B(BcPL-%KrUd^=iS7T8Zgdd(?BO)),nDH\H;KL18J:bba:98%b`ACVe3JqrkRg[@"k&+L#.EiTM5(:4N*a#YWiCZUZb'CLccT:IfjZh)\J?+$#:FJsM9VS\C4@k1QP^@88r3j37gB@[:=GIIRb%Ws(Zp2GT:e^_m2q5]!7IMZ<"TX?61f^3!<2Ue;@usJMC&p+jYY=aG*]i#"/(Ql_<\PHTU%ue,U%fe%8;F'*iE!5LE8,@KT(lAXoerm64tC]11`U=_"#.P]dMj'.jiW-^eP8:.;(`Sg/5mMIC_%%@W+r*$`qL4^ZgXG2LTl/Fl.B61a5pG8NGlDScf/?&j[N]btTFq6bB-h3C*0>\O:U/:)CskkYUKQ5`#a_!_E$8=rf%tL2;V:R6b6mN#u:83>$oE`,"ZnA](h<`C$`$Me3[.E;kg2d@l--:p1+['3SKSdFEao#UfeW:aWKBM/9;:QRoGjU4UHpBbVq2PPb/D3haPeSS6t9TsA-YNQ.)T8ZXcZp:R\OfIXIn3FH;($pa8?RMj3rCo&$%JQ]rsgl`S@"&P0oFHERiKNKZ;R_UEW,S;M4Sn6UZA/6`\$A:!4U9/_n?:u2r(u3^(]J>/-lO8Rt+q_s:_f?7>m9#@97NgL'g+oOPF_L33F4MCBNQ1-+cY1mb^+09D'h+gc7n/I_o>4aa78l-bEitu1pEE@O:D(;(L9ho1n>Z(CEA9Ck9pnj6i(i5CScKVqAtH7JOF=37R/@MTnoC15XZ#,W=ah:?qUN.;.3#3^_A*oJAAP5Vs+(]\!E\N#GhD-8J^>0dObi;'_$^@fjc3P#bEc&W@,`$A@/r7Q51RCFe"HD)SQNWblU6]j/Y?!>#XaM+MnWFWmUS:!Qjno,3Amhp2krE/1OUAZ7/WX'>dQcY`0!C."N7M8+s>8Jq,7?N#GR#;+WrCdQ+TA^s`=a,_EoClJ`sq6d_\?_Ml94f,\@CL4)3kVc-<)^Y&1=YBhMg@Q)5iO3/H'PKG"E4m51-G[8dCi`1f^sb_-H.U*TuJC*nQ:EY(LA!HBP2QspP5J]0BX*3S9_Z7$jt)Il5D5R="qA=oGAR!3DD:82>4E,J]3_#4-;m_JC:#iu'^^G4OGp=8SYBCbZ1%chlC?gTF/pkTtmr5J8a<>e.nGPL[<`/RMV')Zulp"(L>7:uQVV5DP!:>81ao&j=!GqR%Z^584++qY7rrI7U+RFdJ%V9[j)A!S*+G'4*^"W7tsIrm`i%Vf8.9pE&:7"G>7c\q/b0TTt;(VG+C'@pA2+T'8J+m/7#%kl-C=JJnRenYu!Pd)-$1t4smU=RSW.5P*>2J%ulM.FdeHbU`sR@A/3q@a>m[jNE]E%GT`h%Q-d(sPN6:ni!4NF]-OrHC(^UDS#_na[L,M\]k@QDd?[2U1+'F"aF$*%-#b3XBe9grotRFR%^WPfP(Z&Z]L/C?kOa!QTKfARqXHr;\'f^0md:gY2W1g^F8I'5'Q`Hh:\ndk1tsD`AbiuGSHD!b..LjN=M;Yh%P?uPI'`A9./D#d:iV^'ja,7^lanOsQa#=)^*0[@K^C-IEJ?,Vj":OAI:C0`EBEeBrp+s\_97X2^-KLX4oS-n))O^KA[!.C+&_NY*Ag76g,F/P%M9H]KUr>cONP38+MoYS4`?$-mX]V3\$oDX1$mf=&n@uK1]j4NNu#h)Ic[)1,d9J2?qm`'5],OVc:f@%?4'hR5Cm[9r2q^-'=okZYF'Ke?q-aCmJd.>01NC,#,,\^%^[@kkH9^k4_)i`?PrM[m1\%bX5cmJG\D!%:n&D9j;;=Z;mjX;OIg+'TbXG\ig(/VEuh6:>eW9?B2ZI9YqM*c%u[":t8NJV^YktlC",:nSFZmc^qR(rgu#M9O06r/SPkC.9M)Ae9d8)6Xnefh;L"=d*#]e>Rto'g9]9<>j4%_K6r[SHFDkj`sLUd1HqJ"UU:Rg\SMB%]"Z_(n/f7F0dMCe#22OSlWJ]VLieB>!?cSm],&&Y0gI7>2Se$m"=K=1uHJImIlKlH?9*36W=+U'eU'dsb?Xr7q'!gLS(Pp.r5"BSe>3q[[plJ$qiedInj6=B*HmUr2\(RQiCbPGZ.R\4pH$0<9@,D)@pSNgHqk>.d4JN/8O1`EA*US(?aE0+ToAO,P](nu.i;g:,rG7,o=NPTZHfC9_t8gl`:3QN0\gOI5Wf!,@Oj0MAtBO@m6e2cdP@3i1V,?3?V#K8A=\TVdp:'p]S7>ClHWeKp%ilUnG@m;"#^:H5oDO)";l\(OnZZ.fGL2_9fk[bD4@AW0&Xoo(*_t*X2#aslq*T\/_k@T%2,N%p>[aQu:P^+1o_ZbGmN%KupZp%[N4sA7*jF2IRF=j3gEB<4]]a0&F!Hl97\(Z*q3Z!D!ZcEkULUX_jI@nQZ4fhsW"/58Fem6:A9l45FQO.(QYmY2>/=-14s?@A^A`Eg);b[4n\HqKN,:_;LR^;h%`;'H-GGHJ2hrgI`e10@96VO&5!7F'Fss,68#(`.`EK=K@<\04\qFVB]I:[;l:-lX@5,ZT8jpH5!fS]W_+GqDJs3Fh&Bhg_:GLhj"ps)pTip^kS5^LGH9)J!/(mdO*DHir=)heGp)++-7.lnCt]-!,u4;XV"@P3#rt+tH8a/L\VTC<9mQ1>TtX]$7gl[r/S-[o/]T9!J<-0M'8,i38!8SY\pEW`$oA:_!Wt$jkjFa<[noU]+ao.3n4q+DW/KYfT@+LjMP.:aB*=u[^t?jB3bC1`Y+V_n1D+55.?<%9_Y?IYdT0:]E.p91'dMpI"RUHI:/P@6:?nZlBP2Ea[B-'ZoIXP60!`^V-PaMng#57c:T/3keO\5@%,k;u/fVR^bcDHA\4g`[KGd!2%X<2?>S"K3^"P`gM0Tl`Z]I9sQ`<)K8QKeP%/1mE_+_[U.5nW1$#6FR7Z;3nDcIIfp;\0sPXgU&GhZ:.rXqe-io)bt_8j@(IETkLXX?e+;fO;IGbW/MmcR3;i&*`DM;0+,r31bMGBP8\3#_Wj[F?'@D8`L'/t(b,"XTt&I1\_6aGE:FKl[ue5/;#0Og?a\?BtnfAh\D^LLrPbjIck:25F:dZIR'AF]QB7hHnJPcTa*4dbZ*hiBUZ%[NqBMhDujCO7l#QSbU.rO/dBPPE'p=7=i7qp.D18g8MeqPOeYL7!1m!86n5`sM5/=m=OK_q[Xgl1A]9ThI[S?1r*d*G2Xa7*u=r9]CFf0ae+&s!JMI4gNj_1G(C=,\6R!,iD$pCY_A?EN+r_+k\CYcR7V@,OX*Zq&/L-(l@2HnqW!6\^jd,KF93>Cq5/>f47!<\c[5l:GWEM"TJP*Pum;L^t7TY5^InL)hW\Mlc[j3.^NSE-kt8F0`0Q0W*inpBA$\D:o,rZjJoaO*B./5jn_W6a]F6pg2g?D82XPb=h>#qD^7UFHJKHHOp;Y?A9.WE%r5^fB@;-a_**UgMfhs#uluM#q.IC;W6k+E/"^QI9VE2FQBt'SB"8PVp%N[ZO4jgik7\7)m%)2/EF*MtA`77=Bq^l;@joX-b.EA4n&#!;V#V7ReDr9_:?bOH<$8Ad-&/d*+'C;8S`_P8PMm#UmDc?reS\.T$KY&-r=D$P9K_c99Q#mjH!:Q;S6g]F?7\8IS9]VC/)1KdXq7;thQr(=_?[-MrTr&HR]o7Ic6+&5pR,lO3o)_hf3B%IuOC91mBiemYp/oNu:O#>,l/f1n9XZHkG5&OfT*T0Fgarr=s029n#)9L-N:Uh5O8p20PlgM=EoYeIIr=oHcJBW,&l1d:9$PJLc`"`#kqq6i8pXTSB^]gEI(4cP./M'1Y&1LN[-?N\MCGrfYSP,_HhfJVmMWRNFWSt[30K5U8/]if/]VG!6Z7]p@=BnJ&q.AO3f@I]YK%HEdC=R:p:/4*].iKg:mI#d-sm?[]G,9V,D6&0Yn"+s$tgHt(a#F2C5L3FL-BWq$4m=ogg?KP+9h=>1(abuiY2T)SAGP!ks4!;5Qbsj0Fkt_N:QRh\1hrScLkaFg_;6]=lObhYchT]lPgn*1_sZ,%Tq*ue,8:HI3@MtlI0ZZkag!0shP__*7XToL?EKLu^cK"=V0h#(eUe>6PHY%Q?\UK36D-R,-(Xkb_I(q/nG2BW/[F+\4I%RI64c3Z:aL1GK/I;RQnf*6]A/08np9+K5JX29S[XX/<#D[]^mU:dQmq!!Ai-a9,!6j/^S:b'V4q(P)U`WT$#I6256+gW0O[`:*:pBRiMq0@7uc"RaUJ3hU;gWZS$2#^C:!BWnr,@"\pZL_)ft5]Bdbe!,rDS0a;ohlu"OrWPr)a)m5aFXa=]duRTq*+28MVXE8I-,$qu"O!!>E9dIaa*\mSRXm:b,DU')S-cW;0V:#$bn*n,G/Luu\^#ZAr30lAQK>F$[qu[^Z#*3JVr">n+&Ed_TE+H=r2(>*Y_76?m?q=H+4>_gA(6_Q%+RP<6rq?Clg(G=sg4V#)s`^8Brmt+.*<6F-:`XJIR>F;/WIc8^%pG,gBdt+pfBL-[\7=\h&Q"'q[=p!AX>+(nY:_!X!eBeYE+U`Qp`,ZUC!JH5VH/OWlbX&4`81Qjqe+JTpP_\OQTM,3\@Qq+eRS4`^nfM2$m_71;_2,NDS2.FuQu[."o$`'QE-dUjoVcV]*%I@B1&>P-TV&YS,T12VbbaO<=)iZU1?k#D+-nUs)BG@&jP,YUDJ.[bD64BgU.Fm#p?O]cJ/%hO,TQ,3]^aTRm93;$%/c>q;I)Asl8S.GNP=R[,K.1;]7'Q;*b/!e@?tWCg(UUrtV.<1@B32Oc7#.:u2:MDe(CNAS%K]'nbQ=Tb2M"4.EV(>@a@MqgpG3"HfZRJa*QqLsCFrd)$r-+\4e,sS>BaMKQOGt#Z1[QSFJ:#K<@mff4'pVDH,!a.-=r9aB*QJ)au1VP=Z/`\2b[j0o?;`\lf$T8f1qM6l:_r/Rmqd9OUg+,AMn+mD);5UaRr5,h*2)**/$RAWnr@AMrFk)$(0h`2=$=$n)lcYbHq',7LIRK?@s2n_8"R@AaBpEi]q01RfgEVOPf"P2V)>-R"XQT2mtb9?J9)MAb!M6qaEXq'I-`^u(.XB?>mQ)P+<&R!oHhA.C;p!hC%1+s@<=\u:GG,4*b_R<%B&/squ9E;25eOX?c5V20tG$]ra,d>&!u@7%Ag.3-YNFig8nRAP\('^N0+KHc)m8C>:k/Q`053^GiEE>$>kOjabeBE5lY#I$KuM1K<4aTEbRmLG80#_OH)Vofhj9G*sHV_8$*)*GdXgrWP.Nh>>::gF/-:rgfT&Lr1d6>%.Ni;T.rLjQL&?N5/7U9qqnT<"`[^`Be+bK?,<[Nu<rNt02>t*E3Y!DokrDD8<2_*>;8b9h[R:P#`'9UQ;+XUNaYVGb$fP%Zr;9/uSMu`q`9IDL*og]80+/5q0ZiMDP.LHgL!)H"p_m;]L>=A/DH,n(=Bu\``Jk";p^!J/"7>ZGW#bao]mfQ(_Hf9m4"6XMc:3uqmbn3j)W4*f7O6K'k`lRIScY4fEj%cL=,L1&3GVfh6?0c'Wge^WF\T[/*H+eWnQ.fTBi$gU0]#Z$&k.J4=h90pC-%Y"[;*h!0F8I\;1;*I@d]aU:O&'i+qu'b+VN&V,F6&JtLE3#"jb(:FpM\RAAQR$.On`3PXR"JuOV6C*i]A5Y<%!n>TR\lRpeg@;/K=,jZY!5Shh#f<5@R=H,D6:IC57G=$=F-b%5J@1Mpc+_l^6Xco&j;EKgj`-FZZ>?Vu)fs:78/u2p[\\XS@g+HXUpA]I81Y$sZ&JcnN!^sU&M6KLM'Aa]J7'i;d`09(A-3t\XLP>59jM&,9$;0S,&\"qagg0jaSM:"i6\mkY(U,D9Mu-c.EhLh`:p,ems3",Dt)#3r/i^Z?o)^)sY+k$lgn]4LtfFImf_[a+d5CtLueLo4WoJClq_\b-O9"OZ'jDP&5Qq)lX_-b:RPgOi'Q9*rX"nD4:6.?cL6mI$P44V4C0=&4Gb*Z=BNZV:5]S;YTj6>shW8O<>EKk@D0&4'1'GE]#]tbk&u:dq`Y1qek)qe4-5i!f2+^JV"+D0pI?9apR,B&L*=qb;(%gLrg#aN$ZJ1_G\HKaoc+T$B\dCQ^L2YOg>Bm?-:Aj0Ju7B+DmE^3ALZQ@gQ8Kd1J*e^tE[DPE'2]&V+XFM3+M[jK(%$*/7T]OWq;%dBKI5&Ju4B<$90e`0`+\WAR3U-:/Ug"V!lB2m"]!U/Y+=Mu]k-,gAcO7Yj`j9s1\)f2b9;p.p>%=0J7bp5bm]j?tdf8%fFZ]:L=QePcl\#TC=?e2i:5W!#4,V'mFs/6IuWjc]k"GRkaps2bBFc]ffE8'X=)VENf5E>6B>pi>j%QI0"-c8c0;>in'4oU86Vb=g_;b/"/_WRk936+$WHE4`*()'bX%?B\k[V1\V@ll4k32]QY2*qBMi.N35&,QcFK9_!'Ud(=O=Kga(^j82:7m/dl^M'E>HJWY?m7b\+g7*S$M&-rN]J\FIu`b$s6?S[0")L9F.ofYZto?]Z_ThkC#P!q`pr+g^tp?AD*N+O@_Z'A3EZEf0PHWGA.jtQ#W*h5(FmpP>>1ecaXO3)`\s#uF!g:5VGX[:'[nde8qe*1IsN7lg.@qD&V;/-!i?6("\>:-NQGjT&O:hM"nYNHEDn]T5nF*VuC0g<8&RE_.FEKSP()HBg2CN+=eG8Y4ut"p_>l'C4fko8\qkKK>.;!f#WqJHACH84!kTW"2^%!A>Q`l6.@IU'Ule2h[#\@nr[oPOe`hcd%,-ntTam70[U%s_2&gppgJJ9MD=ZAHZUBF.Vc-8)$aJ9f_:Mn=-,`<,>&l$PiKTO/Be=*H*WuGgK)Y@SjhO+L=:_A93n0eMIktF`'Alm]>RN%J?boh?9!7XI6C6E,ZU$O0;R&YSo!"D4p6iq!HYE8Z(IVPL+oMt=Zq)7,(X]hUH[\*tBC9qVc9jjH*D)H`fRrT\"%)b@h`HZi%=[<&W&G4T[F?$$BeRKHNHrXJJMp85>.5]ccnU6JkId^,86aXoukR33H5G0G?0IsXO#3+&ZjR7PP\8IV+6=1n<+P-`7%X:NVl(ne+io5eBTb`>"KqARL[8f0VWd!`65V0olns==Vu]^UrUpfSB$(jM,*O&p#mcK@D3MjD1/dp>Z(,7H(6U.&C0AoRWVgnn#0XrI8/ea(*>VET5cGCbPVXYP&`E[kj"sPL1ta3`G*'dBuE>@Q1<"/m=p`[T=4^lDT:e;6E)u*9[Z@8kB&*<]QCYL0BRTpi>6cVkb$NeFWgrdr(E5I!!s%*;iI4)$:^Xeo&4J%iqVD6C,#ae1?TOGNe8#CVTsXM"?Sk"=GW,1^Y"DAcLM:HUH&2TM87@Zal0l,__DbE6o:B*+Q=\5,FSUTAMiK0;1KaH"pslfG,d^=>*I]nclM;IgW["fM35(+h*L?C4NI!q"-;?s`jj'oqelgGGVN/A['*gf!A8FM2DhmC'J1G#;-3GP*qFm.7D[#dXg7k*CED>8AiH(q$<:3&J^370QG2l+ur14<:=haZ:PN>)ga!\gE/0GHe%R^+;>)8mdc^4@?`>G^A"D+33nq<37*Ch0V6+"N^6qKQ0HkCDP+r2$p"I@UH8o7O^V#^2;(<(rW-G03Cf&LMlB88ahN$He!$8&Ah=F)@$nB&RmegY_ouLgD5("Z>C]jmfLnEJM>NHio)t0V#690XVcNehYbCAePF.c1DOdR17\o/NK&bc^%V0jQB:JK=Fdc)3d_Fu>J)3/J]bsXFc3cPH^:K]LuI]"brSTF+^n!Q&0k)Ki^dZ6@stpllK<3\@o]E:[K^ZtG1r4(k58Q#\X>nhF@^"mkBhQ)I,^;6(,*ZO#se]'H&)3]#D,'knAtAIYOJcA7*ku9WtBe8!^WK_^MdCsJ:8ONGB;JKZ%+fW]EgfoOpT1#`00JucPGRHV"[?,F"(1r@*k'#5q$leqZgi!c*N&!.#j-+/dZNpgc-7Z:$BU7=Z<\Gk/4/p:q1i^G?UD4c=P>+]\o+3$Q!#[%Ih%s3e7FD?.O1_^gX46:IJda]!IEa-gWf,%WHN(fm'Rbj&hb55;SHnDs_kTA**aLpT)Q^#qJ]>Vk&OJ`RZ9M/uNJOb$#V7o&TlOPJ0ce7C`mF*3+!%,kje.f8r\@%Rj,&46n7M0#5&fm6r?6:i2$aqSr#aViQ5V6j/Ef=6CcaOOZs`Y:_rA4,:o+6t>ZX6!Mh,h#oe.;ANaH:6k;n(/X#)s.Q[Q[o,`3.mP*cfT,Tmfb,Q.i0HGn-4=u"&IZS+#?+/n8nWe-cD2qDptW53[ieb:ud91=7h>>pW]PMu>`@\Z^1o-TQ[,@JX/\6rtV%3jh7ZmJI3KZ3q2CqAfnjsCD9Sd/iq_LGMTGh:=-Y*-`LWd;@I:PEmPFAfXaeUBH$T^SXD9eqTj2`jfMET@g+%'#2*Q&-h5T3ca5-ZCi^!DQ$_NAfe4hdX7Sq-!mgb=#k][`e5!Ba>]sd5.mgI[]PhU+eio@;3/"r0p>]R;Jg:7BC@:Ct7nR0F>/[:kjt'I@]?aA"jJACD6F2=$$r.oH;Ak'!k?psBj!\/F6'IY&2[/;K%IeC=\(chI7=QXOGA_l$(U**:l93%RWDe^-Sh6^eQbLEEcLWtn@rXn&;e6jd-($M@%k^#-Vb3L(')+4^E`1ecN$Erdga`nS;Q``iu:_A#H_"CboNG9k@BWX&_qKg;@>bo7pj9+C=3YE&J.C_r`V2QHro9SAL7msG10ddE$Be4q"U](\`,=s&O>$p7ZLm@Tq;0GZJ^XqsHL<^`,Jbm/OjpjaF-OU;LtAD-E$7[P8Vmct(5#1t(ec5i",!H!?&_Gl*&sTsL>%TN8?%I^6@jt[k!?HaCHuF#">nN;bn.#Z=>24?KgMY?:s=QY'ICmaZNb6-PnRn/ZK>2u%,1kn9OPjGmAcJRjeA"f0PR8#8OPdq`L,A(4Em12:*lMn*X-VuaDhV>l=Qo7'4[q619WusV?s`&U'Tjc@0S!1.-r.Sl.XBUaJhSqQ`gVWc+:Deh71,ZG0QeG1G*M^]<_ZOYc"DZ6_OSdGT,]Oh%"TroGD`V;MSN&K4U._^qlLS&njtlRQQCd&WADO-(2t'-OlN4abEJ%Ec,q,jk_3s8!m+n)dF`k0G(O@=Z&V(=R+T6%-\)'iAaaI%:g._`1Wjd1NnP)$h_EW.BsXOGpE^S:)^LCSES?-Qm"LmL9O(?FMr-2"P+HV!\g]>[a!cAi$;E:S)[6t(.W,h%oiLfZV!ui8r%;g[ZV-g&uH+GW/Sf#F1$XD?pQ8p$973)FrD?RL`V0pJB9i\83K>+DPK+#gn!D]4i4$>U^FE2]<\:[mQC8A:4URDT;%sRhh3mHtSbGg\]%Nu)>-Q3"!7O(rYQLBNA1QRH4!7*;&=?u>@^8:N#XFK78_@gpV)Y@oNc#0=GM%-io+0,\?f-'O`rU0%/#M>4$.%=Z^!us4K3"c$88@J@6,58jj;];a+H%A<7#Du%!47!$&.nAiPbKXG[gm@N_?!8@$`<9tOPUnMdbMX'NKV@]XI**E99$;d%SXqpJd=og#$Y4[2MkR/Q*bD';/I(a.Yo4(6^]*+5GbY,_?f*T=-k%e^A#KJ--SP9;GD/+bW%aguOd(2RR79R!]EpO.UqR9C+g]N1FcJE>**O5#sotmhILKe)_%SINaT*+pSck"`qe@*u%YFol'&?N1)fJ6UD&K!)3e7WUH,q$uLhW!'Iq)"#YIJ2^*Nd4BX'oqn.r?OT)"Y&k,OBWb=9]bhkRtVIl#pN2,V(gEdJ4'fK)>1mp*kC2GfL"6(.EDiuGT<%r>hb?a31WaK?NQrK'^I/Ln/L6q_g*+3"f[=OVA;)XdlM/?M_c-n:S;]c5n-+'#pMi0H%Qh%9P]57"1!0uOJV7.'J:Lp"HMPE-F6ODls7h0VW$?9DhRheJ[rnY\HpUe'orER+],5:Q4\/T.Gah$*Akhm12A2V"YD2Ons7+&=YeXJ&H?m,1.<,*\"1Od\ne/tUomoj\8!t'='g$[41;[fZmMM5VdR*!R^LmqsS(eY^G0N:I2LTl/(I$kEk1oJ?5NXJ18+bIppKT*P-@V-422Ep0F!;_Hnc3j$mE-RDKMGD'5e@&csBcU)(^5.2:_GK$3)lONCp#rL5/#+fWpU+mOUE6l$'"+r\Ag$3:bZJ?5?YC,YMq.O!X#@e(BqJfSnY+E$1*K.'a>/c("Kn$QR+_LWkRc?(qPM37&.$T:/Tn\n-nuJ2B2P:kpMm:3T2.l%b'#V=3aPIsHp4*,eU]SPRsI:7%t?FeR.&W[DrF$D!L,k]MIBdr)58HS*23jN!EDNiK^l7TVLmRND-4JS.&("SgNL'6VM]o.7KS.)Bg"_sep`/EEX'8$5UX;o"s4t=&K58V[lrH5s(Z?j57<#npTY/6YCUDl%W3l-VVTm3$5.-comb6UHJ?O?nea,2Pb"M]>:",b(g@ClErr)F>0+6tlut%mu409slrpV>h.h'Dd/<,\#UnT';dQQ6o^.1C@A1>h"5t+&:oAT+cKcM.s:<9.=jJeCm.3`*K4=D>a/8=a*2&0u0PP6b;^0ALWFHM\CisqtloTo:J2?qX5kD=gtK9*D`DEE<+ujas#q^-U[ELQ7)u0p-V%"C142F8/dDKJ^-*F&]kW`j%(2\NEV[d]8t"68#MS0`>TE3+G%)oMrY>S`0*G0^-Q%Qgh)_86lbXi]=cjg%n+,9:hNh%jIdg8SO-&'r&$4H="pYD-a!Dji&eEfp5S"<17_';,n,\_0R4AS]p!;,p(>W1&N5&nnA2`_!?g]>>nkoOhKP(=]7W-Q>lpkO,uOjNDUI.QIYS4U\ipm-@X)='EH]2Q8T>CcNk0VZISqCfR?5'ouLRI^0E)M9C^3:R+\`[3g6eR)Er#t*^qitb)Ei^BC2NV+^BO38@XS3S@FGu"<8;#>'D*h96*6(\,(7PgB#7#dCdUWqG2-PAah_P'C[]kXKB'6#9V40mJ`=JB&;hd#1&SgeFP46nj?iI(LNbYGhZ2BaG]6"hs)$%dpS(a?g=V+OcKWgI\/#l!lC-6;r/`p9upp4dhNb>'KUlI@BFle!sq87=(]`eeD>8n4N%JkR.'NRn`36?^LodsisK^o"+<[q*3Jg;bo2_RP'5At(s>XGUZ\GuOIN3[>DK2/Sh30_'kR"!lD`kjXn0-d00Z*U*rL*[Kkg[>0\dAOO.p[^YN>6Y-K_S\SZ*Un+msU2]jE`NE?S33^o"KL+]Y<#$b#G*c4mU/gX>RUS?BP+h\2;1pMH\@3>Cht=8&#:N!ummEWn1*i][_gQGZ'M:>*p!W]CBQ'E4+ERNo7f)j6@o[0C@;C<`:*g)O0/UQZH`,*GaA1M9%l@tLE8_]H[1:@[ae]IkTRt`.B[pb5p*kfVZ&W`V81ZiXZY%N)gM&4a?,B$ZO:s!b/q#-*NitB*78=K>F9rIV*SF_#%n&sF]S#>,G*fER[I,(H%GjJ`5(Va:Q@&qXKWmu5QnQp9mpN:_FedJk8f-bt6!dk@l8g!4+:`+MWh)4ceKi]c[dbLX&5Bd,*/l7#h0!e'&k#0M8J;Xa'^Xr02utoOd1&b3Y+.NM2W&PK\o8/E3C2bPIssV#=r#'Za)(D2;N0fmd+B>fcC>e^#2!)%.d8P:6(;#FC(/\XY8O+/*p=U$o^Y@I!,ijm,[nQA7q6Z\&A.4[F:,!&kB_)m[b^C]:_SFX--L"$]B/*B8F2+e_FrVu1*1nUpeCGnm-p3'K;Ttj*(*Lm?6u:CG>f(@[%EcXgu,Hr2AFIVcS%IaI*kPajXqWiQaU4BoQd>pYk88nKQZeF.JaP,7?efPhcUJNXQpq:$,$+BLr5J2%q@"2rP/fP(K\t50Z=k"IWPr[a$(o"0RHFp7/2Z$JVq.9G9`j&c$=-$FY[W;rW%X6fB32[i:Vj<(*6USAL%k=HZIA$4&-;rV>3$+C;H\K!NZL%],-V"O^->KF^aU79qEYHbf6rH'-X"#8Vh?7FYk=:moOkL"_iX2$fl@rtHbRWBSU2ep$._VC24c+bR?20`hFPOc6I,lN`.4!="qOoNukbt#7DIG&oo+GAW]2`*S1>V&qD^7?[C/pm(3Fsde/jq;/UIGjAOS,sbZ]f7OikiN#58De;3M]]d-#c'WO*:gBNLbM9FP^8Io$odnL8!m"Br,T"Mg1e7#u"FsbRLXl@u:qPT/+*`.Le'5jb?M>0f*S,+^FL#@H2DZ%:qtfZ3MtFVscE8l%T)IGK5^i8s*/'^H-[^gfY'LT%cr5*>DLO$MI"rB%o+m-:bMB['eh@@Tk1:K+3ML`+'&_+:MdMAS*LLg-no,:#PX,o]*9'EVaO-EL3&e5`q8Y&1Su8Hd.[5gBqXo&,Q^jE[#nSuKc;1d@uEU-Y1\R=T!n72aZ=T[XJh!HGUa$].7S"[e"(B&H1(BIP-dYp%jH8FU"I0n.74XqOYZ6ubIPY?6GU&=Pr/W%6'+3fng?a9OAhfc72B?Q#kt-J`&VAWMb??))n/RG]S7!TCTQO2BF7YZ%cEO-9+M];QsR=XV7-3;,u!p>43C5UcSDu9Y"25D"V_qm(Dmi2,)Y(*KS.ZW+mJ"]jPp`;DY3[eF-c.'b[[p6Gb-oKPIXA>@TZK`V5fI0`ssJieno>n_\JQfQ>t`WZCI.KN6?ph9Xld]$Qtu-LK_iBiKJ9u.&H.i@.VfhJO=..9B)MfWM7<]8\f&-=\CX(B%?i`Fj:to3SZ1;"2!U!L>1QkV4k$aYeH0MjFr@Ai#NIVS9P)QD_99QR;GT#D8%j)Pk3Jbe7FTlVO/(GJ-VlEQlrO?FS6hGX.Bj)D0WeqRN!V;M$3SkW)AnqkDl+;V0VQ#7jX`]U"nl.tXc9.]0G1IucFPbn&ahKr_B%'jo1_@s@PT!N-NG58S,ct)n:A\hpu.gAR>5?&GSh9/'W%?so:(OA.eM\^C[ra(53REDUu+2Zqa_ukM't>B[&e(Ij_uo:X*[).\*IphRD+:85FX("UD"Gk,q?q!0KRmN*GntA:d/nj,_UD.#ncn3EcMC'q2EGJN%sD5-TH6.B>a0:Tpu`oQoVr?_Ea1g6%g)8n%*J@c\A*.V^-iOI(finPhA?pO<6:;g+4V(8kg2)LH;.l(jgQ8P_DpM/s$P`\5b8Gf@LohMnC3c9@I(X265>IT2O5u9iSMW;BQb^!2^m87RTMk+t;i]QhL9e8(#5l0\Q[=$.$E(DcHBa!?ap&&j\@C`?qD1`7--];G!W!fr!26,__F/#g-^O$n7Fk%?4mPul?A.kmt9'R"JO*+o\4*SN2-nD:u\J4Tn7]:X%Y]uoUIS5Lf!+bM^da6Vu`gY*^&JAXXn0?hlSO'Nsg-o_^h&ZF99-RlVCN@'-'J&5\>-h**6*0UR\E.0ZtP!UN#Vc>amh4-+-)d(sjc7&GqQl0u?+s]*V8HKN=)aT7_\37_W\)o\/9gFYd1YlrD6-D\s+(;8BVFE>^X.mMNnU\8e,_ia?7;iCoh>%/gc2eaqA=,nXHSu&nZaKGfhk,uT0uTV."0g@46>_u&#d6UZ,GV&.;W4*!Cm2[/IL5LuSddId"jG];9]o>!RhboeC3?tdgceF5i=`5,Tm+i&&?@&R0b%H`E=([#&E7S1!)7HLr2DDal=0K`1s+ZQNO2Q4e#'UX#"$#Z/#$+E<@";l]a'bL\/Yc6dN'fje"(QHV3`BoT$uWnF<76Z>=mDo#*DAZ>'YFS^]ES1$&#^RFIU"h\X=1.>m?/$!)A<(Y3N%;>+Vmc/@'oc)D"HoTAPRAJ[9nHU>a+,hJ,?28-oDU-=QJ`Tg=H-#P:e>HT:*G$!aSO*a+YG>,+LGTGl>`KT2i6m;U(eP@^JG=H+Z>'Sab[;@u%1.(a%1Z$K*ZYQ4"YrG2FbjcL`^ZORa-;fcMrB=NM:2p(-qG+[9Fh<-X:Tuf[`Zsed)3lV)<-3I+EStllQpkk1VBW/KMR&>cMU9T)W*H'T#5fs)?+,(qpPa9H][;h#_\4[U'1Z,OSiP4AhYWL4Q73)ZrUtVS\!q.3]f7>=4Odjku#WHUQs'$pi^;-=m$2DkaQ^657Z!XPGKjB#+R1rOQ'jTcisZqn7=klBNn&^2b:r,:AO0H<=rEojijU,Z^QW7T13hW)Y8Pb0[QgR\7DdUI-\&qEHeJgiNlu!D^=]87Dp4@2%563VFuhjLEsfD2rceU"Vc)@nOW3cSX2&PUf]p@=ceJ'>Uc`6BmFbTO^mMGSj3;$Z,sb8BZDpK_Bg(XOGTp5ce,K`^k`AQVY@h1k"cS3RZk#.'a,Z*Q7/cM4<8:5`8%HG2e<#qRflc8+YlN[t//I[[JZY\":^p+d?sN&5"[EBes_.8t1T[Eft73O'@16=\_#6;(XjLrI.Gp4q)t0S25"/,VP[(+N2tB8ierXitQES5go&(m?/d3fpotd7Wrq5\e@bSV^94e$].8^9C'-Ma(p,b(6RuGBst.%@k%L:(qQcarPVh;qSg&Ck4?Tg"RUn[*rP1%LmLf4e\8jk;p/N3k]maM28$7K54^(f^(Eu3$^15!K`I&UiF<8fm(GWJL@PIo4Rf7MtK.e"sU-'$0:mJVnMTI,CF=GZL/lmW*>lFQ-Y4.FUpj7"d!`m.`(GZg^6a[7*q?u_Am&p31dX9C1b*'fpbPi*[8fp$'.Q;Kp2Fq-2s*Do1/QH!6)WT9C\OY`[r6,=-C*sR3L%0o/K@W*sc)SD&f5fOsY].I,\.s[JXLS@R3Z\Hf1r2S,OBr'sNiVNqQ.PNqm\PWNlaqCq!LI\;,C4/8fULfp=?#Vj_LFaa,oVc2S4.pBp%GYBBQqeub$T32pg!hGh63,@M,=$K8R8.?DU+Cn-,$MiPL>grZlBma*#u2u&(.lk.NiZ#ZPO*Fh7,3#LM[V!l0]7Tci=,o<#XH?U8Wf.A,9S4oZ#te_V/cjOed"K0LU!0+(GL^`^bk8.I)Vc&$m6O!`PG0DTLL)/)ifIPJRsq)_XU5+*F09-aD%;4JD-D2"X/OV8/df`gluXUor8K%Rg-]=6tVhmaU+CPc3:/pLr<'i:OsW:7K(9or4ObUbXK:)K<\leN^WflR\+4PP:m1/0/T>I!-n2Tm]Mm/c4pEtcm>*[T7kEN]0j4rPXDC*Lk.Z23]GuEOe8Q#X'rj"D\J3eNYSg1+t9Fp`8GWTe_9Wf&mgf*aJ>;%h-HZc4iKQ4(fQIV3)'R;*\WlSbVcBBnoO;'9$O=.$QK3."f%l))jO-.h0J%\UABK(,n5uFO<',NPc]`(c%Y>h\<)7%a!2oAu!Us.<]uH4F6GufplA]o=,`'4Wlb&YPEG^N5"3T6uCZ?btciuc@nK:KFDlm/An(s+A)1#5#R9:O^kfK,29:K12&JhW&1=:'bZOq8Ps206Z3nSDS>G7P@b)W6Y%lJd:S;L>cOg(XKjflV`"Gl5l$'=08g*7o>n3h;u,=]SaH7a5IYn0W=Re.iRZ64[=bWnfeQ)p;s"2Q,9hZ0CZdrd?HoC]GoP"5i?6pWoT#.o_*BL28PA\D9J['-1#dFY&DSN7:'*b^q&/s5CNaJ=C#*$G[^Y)gmpPjF_%4&PK=&%nYkL\!Ob47fLlt?0.kR6!$)/#h!jS/,`:,]8,fYC/R4Xtq;JB8_]X=SPc.A5(f!6]-7958ljnP]H;lCSVMOS&JK6iqs,U$%$4EtI0Wm9]a+^5o2UK2Q:Nhd6.i2#-M/n),rdo"t:Y&k*Co=M&-UeTBIHVQ=3;_9Ii^nd&2oBXB>[aDJ%*K-VEn&5e%_k%=c2RhDW=d^[1JEB^BPMdaU++J&/$Zt7?LZ#IXU[4EiM7'3d%2o?gSDU!)aCBnT6a;4TeBG?G3>l;iV*dlM5o!=GWWjdJ4b#If5m$302El^oWDM.D&6DY.DeUdak;;/XD5sk>pa-]_QL.UI>Gh,*Y;_GAMcrJke4/c^u!c7hCPMXUa0R"6(1)2iu#(4^V+Ail'AqX@?-/(i,K*3C-8N/CfG')QeDYNh@6"eh2fP\bu)+_jp];D9%GSI?bHk.M[YED_O[Fq7jT,XN#!jUmp!\V[q#H4tP#4R!GB=R,G3<7Y=nV^078SXZ6OgJ&#]if?id*Bts'!8XDho*Pu^CMi6MHkiTFUoQ4$g/4QE@jOI'[Sn,CCb1CW/.t?R'qtq2lo5W&H8h"*P:g\s+M4gVcq;&1EmX0N@^lhC/XeD96o!og3n]cZn)IUKXqlK9UPuX8[//LV^n3FNoa\M)B^8)O")7?OTGt]>o(33Br9,>f#^_^2V$S=7OUC(b+A&1qmV%C-0F`6Gb!D.Q)JopAKL=t3JToXUQ]aQ*E$P$Mh-9]LR+Xpf$uh;h$:<&p2i'<&i0Jsp\JFN(9l%0`Z6KM0tZ_FdRMOE?5%BaK8%u@TgZ7Sqh4nr"Zmtd+ja$f7>O#"tLD:ks2)oIaf`.01jLa5^>GaM>6,l;m$oc/Th6Y>`-/mT2[+pS"0d5I;UY++?\%f]3q,*Zb,&fuNB4l:=@*WhgJfLc8tScf7T9K\H[>=ET+%kg1RKF/OXQ2U5`od0^MRj!?$Q@?LN2qXT(eQn5*>^6[M2,dD+p?+QI&`k9Vdta"d;i#e*epWQZ^mKW+a=V/\/57Man''c#%`<[;aE=_I53<=9-V0pJ1U5/G.8=*G5$:L*B_#I31Y^f!aJ)MPAOR`Mo*TV.9RY!@A'1iTL[)W]Hq!)[mKZ+P`63/j,HoK/M]8Kr@oFuFA%V->OY;3;\pU4>X@!WgtG3oVK:Lp8f;EjZG-O:B(-rHRWl8.V;Q8YZ05Maq6iJHK'3"uo+^q-)Jd+a1^D>V#2s]tl5BoL=kfm6V)?N-bWsqK6mpWNNL`i,_Dj'\6TgRSA5:3=">j3S76$@Ssm@2/f`q)jck2^,\Q1Vpq&?Lge+*Y-EN[S8Jnp\%qh^$=jMD0tXqZ][:,n\L4IdeX>7RS(t@rZWT["5j(e"922J=kX/l`;1;`&3FW_KM%L2'M504a[A.3UF)h9BW=\>).%T16:Qg$&Oju=gE`mfRV&m)HK"b]N[h:W+OGrccVf_GF:\r\eDP9Lhp(mY1ih3R4NYe]T;okm,-a]b@0Ft]e`gqP<,G+'WKim>!FucJ!P%9o]DM0llJ"bLCR+ncoYD445S98289Y$4VK:#`'1t-!@XKod,,u(2`5`.lW,!imb:_8667(q2in\nE/OSC;Dd,D0%L[^.oM$`\s9cXPP!3aD,/Lc9E(d@Xg$j8ee&7kUB*/U5N]/iWIg)M,lSb=A>CNht7X..Y2IutfX9Un6uc#Kho&N^:qj5Y,)PDfmRIJ^4hZpmhXL'/"4OucI[M(h9"&m%LL1pg*>-d;42AU`5lQDM(M?qd]jAe6:TidrLT1Rgg4\C19q1/f,l8SEX56caY9/pcm)(a)l,Uf])VO=XlO2No"3$qmo\IFQdP5!1Ak:O+QdqX5ohg5G1T.ik?.#e36\?Yrk:b3g_u9&&5=>B=5f1F='7KaG!/c4%d\$-<\E-J1>tjQR5&.ki4U#fn0aX,SfZnY=)-78K/><*TF%Tsj&sq!bi@lY^tbZ.Y-mQla@WN1N-$j@oVgkBbuNjB/b\Jb.M+_%H[GcL^@u"GA%L@mitH<=0qdQrn0:HWd;N"(X/\JIk(Q+I.H]8?r+))%^3fJ:9/6+W]a(TbKtXY)U1TmK8(cBF,2kbQV)+YIp?.FVX!N)-9a3P12,M+ZNG^!G_ar>]OefE]+<6(R68oP0b`Q=]?mFpr!ou]SG&Ypo(CbJ%i'FF7S4cF[&ijg:4C5'3bcFW0@^D=q\IG!dg\a7:)LVr2bkY'MWsCeh*4tiJFsaAV.hP!mj88_(4rm(R:o:6`l5Ip!XER5ffIiaF0%_`l/6@#:Ha1:Pqp`_F2:V5aSNaM&i<+X4EU,X3Se9B48\NG]*=kjQt-X\L8DSM4=Z.;GrcG&ELXYX@qkbdjWd]DhbHYq6+_!?T7M3&J1*\84bR0rZjE.=r'?%06gVpWn(t]01Y6's17UI3!(9D:[$E2C?4dCJVu(*@U_cVJ%N*+"?(T)`@/KR7s4lHSp>0V"r=S)R-%%Y[C.A*;7W*W-"WQkUTZ0R?ntEt[HE2c17DocTCU5KfG"7#S9R@$#_.1lJ:Aqhgj_TsZq@b2$#`6E@bUqjHN3C3`i8AiHqBn#T-g_&s*ptLN"fPH@RKB9JrdAN2^j%;8gfDi525o2Lb'oZ<`(Ms=F8LQcC$R-3OCu-F$oB]7N=uq@ufPD&Ipm[b\P?,+7W36YE'epTQHOP=ZX0[>H7kWh1U]&Uue3P7Un$$0CYiYi8f:\p-7]K()jQgX--I$+blEOH(+<$@"BmS$MLI%G1,8rp^B9W;!mg[:=%pe,Z\5@M4f9Mg-722Wg,/9=SsRtCbm2o6)Hgj)*I;??#2_TbSrd]N8aVin61HDY3PT^*([F_3CD,cd6#fWo8Cec>"ruY,RaHo.8\]^qB'OjFbr"r$/bA-"&ClnAoMFj"Q?ht;a?BUil-X0kEfa[PoFKI'i87e9C`pQrZ9eON9Yc`rfN#^Y'I3[g+])*R"ZO7jU76[&++qn&=I*R[&Rh:*.=iWPP+qudVX%Y)j>>9m$>BM.!^C?"?jI*Y;D(KJNEkC(+[("rl&bSs8Vc?Rb6U/HR2jB35&FcU"N`HI:-nl(UQ(7FNF^b4CF_8V.oiFf#Cn?>O?d4gOaoi@j%=f'`+\`D*WZ]?&.Xj7JJJ5P.Plp3iNOS)rBk_31"a>JiLrgF!'`cKqX_0V+Q,CK!<5.A+%/mmOA#DMrJ1NrL"uh"c7THe6G'N+qOe5l\6&-2ItYT,:!ilH&,4eA0Df*!SU7+Kj=gE14kpc&m;:0H!lR_]S(TWXMRm@)*e-XcF/BNKali@;no=g+GUJQg8pqWe5OEAUAoE8W9G0V;>t>gdLB!a77=m^K9j.M<:g:S>.?M6rllFXVoB$"!j8[.k";1tr](nqtjVTC8?1*4,P5jL`WAjgVj8Zg3QHd)BA,h=@O'(\BP\4ku=3iP:XF&GG`Z4Fu$%\(g?"n$+<1Z+ZUnDYA54$4CcFZVMZeM[p?3=oH&M`oF:;:B*&&9!S7!bf@U0lJbJhA`/mdq$JK4\dZ1Bo5R5Xh`Stf$1];AG'iW58/[VXliHl(6X8HaV\uGAQ*lI.uLk],tUqX0&dQmZ)H(Bf3GL#U9YI;-1jkii%^>?%W5-_UT]t;j@HbSZi,5^i(]m4>c4.fl.^6U?FP[VM=,]^DTCSHS-Ji`qe(Z=bBaD)ca25k+?%"n14Z?%.Y;k#K%S4DF9d6Kd=Ve[3n<2,qg!NiVa,UTNe-Vpe[^p$eU=[J:u*^:Dub=1F:T,\4J-tFmkmkYhMk_,pLBqrM`pcQ]BaIC4M!.n/"uLfY9gkC!$;g@masMdpRU\0gtTj3T'#6SS%rU[)T;Mk#2+_OIGjj&h6)n1]0I=LhL!PkmX;b@]sk0;IIln9\)-kjp%@(bpTSrinK)nd^<\sKh;BAOJ,h][K.HBQc*n2WDm,QkDM);;G,ohJUpnZ6H_uJ^Vr)oop"@$+oNTK4^#T=Fc[0g>N7,!)n$h*Lmr%m5m@)VnLMUCo]Ua7-^<\h.]m"h9oAFK[eaO"i5\WI`I8KB>%s`QYfA#Usj4$]q]IqpNiOa8K08#oTkkas;*fk4,E)lu&4mq@dFS1(2h/FBM5S'\>./NX`++&,4hX=\3cbAUSnR!qhmW6&"Df9de?/8\QPe,%@,A"'"PjPO&\Z$T2B=GMk]rgko?@BN7p?AJdh<(>9H1S8RjLY3t]m"kmD,]+X]/aB7SE0BX`m:Qkqep7T\_"K=DmoN"EV=W@q:El(PtU4$p(EfZJ-Z04!#%TtN<3X"1^Q93.?d^'14g$5e&i2"),,UC&t/q8!Wi[l5X:cs8#XO(1J-i.e=IjtAG%d*JYms3TE"rl&nqt&#Qtf1Jn^l%@X=FZeM`)s0MFscct"sOhPB[3W*qFcK1u>&!MBDmz&L&Am1sjW,2*E\u4;?6R-CTocpo3VJ"sho9:ILhTHA8&k1]cht!!Z.8"A'.2TUHcGJC&kASsiA'4lE7-!'T6=a7\auG3-KU;-^Q=1U?q:>):@Ca";RU!Js`8U/"M^BWfM]q5S>_JA.E8mdhiYA;$9^FMg!e,>p^RJ4R/=*;Ndkt*/,9i$i&g/T?6D=gm+EXUdMMPg^5m-8,#_'95RUAU==5O-o&.c*@i0Y'!,q+ui$rKabMbmA(dNa^_>q[":o%Y),=L6t>"$p[Bh$$s9k't*b&!%[`mZ4_ZOKWm)(CBkBp8[&AZ2Ps7L;q[K..CD/Hq=`WCgpQTk6Q#OsE:l/WgU=.Hq)-4nfKOljiZB;"YM-2\_bqp@b`KOdu).GE/1sdf)Asj:T)GHSd8Yr)u$32Z:g-]:@1mK@8VP#J2JVHW^YVOlV,W)766=e2JCkag=m39sDf5BZ3P7#1QLdCIM`LQ5#"0MG9">NCb&8<*;);;-=fA&T!VF/L8KS<@63nc*Ik:M+h*;MDR*;A7WXp6:;bk)4M72`!h?Y8l3_I1EoDdJm\l3&Vu>`'-s91A>B[6Xd[gOJMS.aZ3c.>#t5+C;A)MnC.0kGRPCKIAYdGIU;U_sCmuaR7*Ne2GB"cX/MSE;9h]Cnee#qAN*6T,.jiB"AsURgWC@c6.SS'k%5Ppr$8@jh;J[c$.2'b$2MQmLbdL(^7$uM`dO`gN9.>skL2@P(ZtbFSXN&[GU6/0Y+@qf/V)F.;,u!#C/Q>qVCaO#+=PI=i7]]e5!no(Q!nQ$T+e)qO,,Rhl,VoWs0sO3f:t`6."\G)L$Yi;"A@C3XX=V1E=KlL39h*g#fsYL)/P:`*0i2%iL6SM\R[0.S.U"YDPd6`m=>M.Sct$N`;[TNRU_]@i@^Bbp)?CL#UFDC?e7-eE9pR,jVMo2EPd+U@@pmG`,VgTHZ*J1TfW]0_CmouSUm!@!A>q=>bf&0cM3p1NR5EWdCm-\R.N4L]AO`CN-*`SafMm\777h$qQ7\(8,n.Y)(0_PK5uT?I)[TXU82<)_U9_r[8QKDd,f5(J;'QrO/857h%?"'*2OR3J,2+WJ'1l%7;3;TZP;8re)\KGHN.VKbZstep+XLri6Hg9'<_\cm9"$#!aP/PKMR$@..2#P-7'T1<67n1UR$1E5`F@%<;R)UQ$"GMTU9[1OgG;M]=\NAJ&D9NN8VI=(C-mg#)@BWSUln08D'kK?1*Mn9,b$r8o#3\AM[%9Cm8E:W=c!c0dVf+.ZG%?%@NHU<_]9"Z*b^qTpS_MCbl/_`'S5fL9XR=/J]3MD'gZ/%;=2tdBK*MCg%39b%[-/c[L=k4J/Cp8ZCDs/%/5shpR]&,UCItoLBsJN(<(>E4[aLXJ/Mf^iOD7E4=f&'l1oW=/MNH&g.VY.lPf67(/B\]!M3utN1=BZ%;G>7\b"\k3Bdt]fe5\'-Bs"4(9.:3?aDG'S0eCPmUpd(^fb"m,`O80&gM'8Zg<")`2,r+bRg!WLK4N1MSi^[:/J9J$7]@UX/*pkYRYHqrJKmW;fQ6O4YN2jcnoam3$jJ92Q3s=frutG[PQ%9U)9e:>k^UP6qJ?h.b>kqF-;R*.L]*"]s/tg,Yml+GgU(@k=24M!$X-[FCObZI=W5Ju3G.RQb35J;R9Tn<2[TuC`kdCGQ]c.Ts%eq]91OG2goR#lnU$q`bFVgqH/p$'#J=F%cijNYeK5?i:#bGdu\R9Bha.Yt/CN'"ebaDhe?-eIZp`_M2]GXMC]0o1im=h.usER>u8JAdQ;[,P`#kXj_j"]@dQV7kHIO)NRm[OB>lYj5&gUHY8c_%9r:(-)JMN/uYCKZWm!_Rt(Vu>td78FVjS><)7I+T-/d*QpL"`HNh:P6-ukA1Dl`%S.][oQ.?r>qmR'3UPrdW@lO=^q3Oo3diq<14rZ1R&N*lL9I(gMLhcK=Xgnokk25daB#ikb%Yh/K_'m^_Ro)uuTFJaPKQdk<9oWj9'HaE9NC3Z3,8MQ$Y(>irP3GN.(9JBh95g\t>/jG2\njd76P">!ljk19#bX+mk6e*@k/nFP;Po]Ko_NTCnHGl]0O]`S@1&N?osG%%oS:c!Ar>*i.9U=r(F'89o6n=pEEt$>FQ)8/ZI9-TAIo?\FV.U"mcOqA/@hCR$6ea-\Bg'h'J:*55>h23h0IjS#!\I#1W)"$F#%@c@GRZM#,9/&Z'4=;L'ap;rt]Wo@NQqQLgqu^:9F9ER:Q4uM)muX0C!K3ARAu7rt8?^+7_0%6koI2+)Uq25&D/6hj.#2431@NU6"lN'G9)#+tM<3H(gil]%)JbcC&.(n1r9"KY[5V5>@DHhCD&RePjl*fPr3nM&oe-jIuEP*Gl")6e.QUXRb#_Jr]?E5tpmAF)$0k.&6:93\[n@@JWm@8$gMugIfHV)-FD&?]-ICb\H=!n4>Xrmf7=;s,OZr7ekkU.1j$'6=`E,:6U.n]I-JgG(+V\CX&ms@4I6jY\V]1Pl%3`VEg#r*Bao/7<]hj.nN=[WeYa`T.qH(SFqR$3?U.IuU=5.p]%3/7s>Zl]hU]kmL-*SVQ+XZ0Rl03[[ZNUsC(4MMgN'(KK`c3M<86VI]tmqJarOIjEYBkp%\"!p))Fh=Vba<4ZU`l5rSO#RJ<1($[;n#``Hsh_"L2UdLNr+g5KFoqWC7MP;@n53?);A34>O;q6a7C.$@%XHE(EZt#@[1/pH4G^oMR%"o!+)J+sld^(8p8:UGX4rEC]4:_V];]V;@/.qi1#:0n3HE6Xk2C%q@7.B-pj^UZ.R\c#Qp^qmsnp&&[Y<77I&8K0C5nHX+>YOP_E9IpNhfPfs\9"E#7\Kf-"BN#6`O2.,d.k9FnLUV\HYo56t&VYYS9L88GFRY3gW\d2mk5<3]K/ar7d`A`t6M/aPkG$YbUqj-@Q&Z>qN$SVo1UrEbI#ui$mb(S.f2nO2M-Us?qU2adQaDD8j0doR+>[^#mjLj>S]5K.@\)TCqX^bc#L-Tbs\[;%+U6Na_6n>YT28m,tn-TgQ3%Vn-E1-TpS?>$mLM%_HYV8a#9\?]C02@Y,_n,piIVqBmTd:[P1PLbL/f40ABa<1J2dG!0?4nZC0unU8V2/'DS3&*D%I+K$fD&k#--Bm!G_LZk*S_==,(FelOJo!\<.3V.k3]jHUGZ^?R3[lF11GhhEW(A'a'6saVksW*M/=W$gR'=6;qG_(D4t]Ima((=LYA$jrTo)mTSn$=GU+t_r+S&7.=H8@LVRe%H#ToCl!ZZ,//#pcP9AecPMh7kEpfWOKuV^Ztj9U?78X_lp;n#2B2*"l3=,dHDlI$5oBkO2A]hju!c,G`"8ZZ#H*FfT(,5#n%&8"MH=gJbu-3d4?U4M42ss%DUu3@W]Zn=DK=,s9*;SqSuP6-/b"&"MR==E:M>0A5NXT)%s/PhTD6''#@PL!HJg5kO55'uV_=m.k5SgG&4L_;=1@Qq%;B+R%OPocK_dL/]ci_5ida%7O/Ml]-k4DctjHM*(cD/S^cpgl5ldCY[3DVOZ(Z5X_%C`g2&@&&I4cT3M'$E(571S6D#b#:4V#euR6043j\b?>DA[b4=5jV$^&6F!q_IrW/(eW!R^U+-28YMet&?D9,JR(Sco4RuGY/[5o71C6l0TLEqtFLiX3lXMbN2EJY/;e+i2Q37AO-Dh=eZdH1.ZDnEaR-f-"BG/XIU8aDOsFG/ZXJ$F5N.T+jVn8TBhRLJtO'uA')B;+&R*dGO1O]b^p%7C(-&(<.lLOUYAr#V&5L.K/`BS94md%@+c9OMW[*m'/cg[3O7;>q_Eg>/:TG.<$=YjCPEWeWtmg+)fecr:H;9)L7[5WE0%K/aM-=k;rXX#nF9N4Ij]JRPuIRHXhFAS$qfPNYs]iXb9N.lQBb?)Q8k9A"OEN^W2>k5P7q!\>BRWB+G%$L2OTS/M5Djn&[Xtc@>$R2Z:5WnW#]-41dOaS`AAa@"&Um\qcb/HeiphI`R5e(b:qAfeKaS4FS^=@U?G,Za@N=7mupF>c[Dm)ek)U1MC(A"Klrc3Ou0#,@cP]rGG8Zq^<0&t5A)VZ%XJ5_BNZ`90-LZtQK2jUCZ):')iiMgV/cePKS`MeqKNbh#SM0@/-t8KTl'X/2k2JHGK15`dS>m>WKO&CSK\=BKT0M_?.bCgmYoGdN6S=[UDqVNWZbPaq'3NlToq+%`ola\fqOF%i_fD]VL=.l5!JuUrhCkf5p^38#'@Q^CO8li5T:crN6ok=V1NJ[eeO4o,4npTJt\]Q(EU,(G?e1;L2o!R.,)TgB>^sc4FW?pHa`fL2\KU7o%qPL]0k41RcMnS`P3ENY.=0Rlj:Roo8ou0M=464%)O-UVGT##qr,\/^l)ljhV38&m,pj@J]hCN[<+N:#E:bEN$Kq'0B&)D*EZO&20lKq-`RleUca+lg:K_E4H*"rBQ9/$AcYh+)$.UEHYV,IkMm)o.o0h"EoflRPdUP]3@Fh!BbgM*VB4r;E?J<]/jL"i0_:8_*5'@r%!FsrTS`GAJ``$L()%$R:Q1*lXlasc`^V^VU/FPgngK*R$;ao[rVN=Xc]QHg0+ln%mcOQYb[`A]+:B9'G;q>8Bgo9%1Nr>dR*9#1[#*hj^M?u>9.W/PFTc9/XiD--5]EQ_1o*YQ&fCUJ^+V%nMh+%CReZrdKkC,`i7!8s#3$&1uZ+XT)pO5Bb2-[*&pg?+XA9#kjl@rT1&`\F5pB+3)THqHDo8,O:\dAHuW"+b:mFJArMGCJcd^]s2:$f(YBrK4(+ZlZVgRj]=PV_%4E;g*#X]I[kcOR-jdaSPGRR"r5m8gDL;hc5B]p2C4;j:kGV1`Za@)75M1/qKTN7LSc^cbE95rBTX;"FeUBdt6?K.hmYOBmS>2p_eiVrG0;]dB"E7/ZD+-TGU[R?$SeS+X4[)%,rbL=,;s1'HHt"PHJ]lKo'k'ILue=$Im7n0[S4>lqr"uY"M[A'59G_5:*%J:i^TPf3S.o_pHUgK///drnG5*d2t]H"Zge\(Q*2XL>^:NoDJGm-aK\5d3I1#$7QbIAd4K0\V'KqY8'\VUf)ol,?#OX6m(2,#73lDP(.(R/&VciPkf-mt=^Pgd$\"A-+0Oujg9`!QJ$;.'rg#@6QiRUM\lsk#,hKmcWpe_Kb^K7/Xk[f@MQ")18!COKDgoSc0FHhJA>6tOUP%KPq+gC3optWbT5AFg&.e:uGu2?6JD?ML-4)$QXqVJU)(JD,G`3I`aG6b@_OG$*e0qFF83m@,rS@CfbMhO![OW8%.S++D<7.X"uT*,jZF37?%1p#F*=JZDH7.nnR'&lm\@3+AopVTMonAWr`=+blWUj.S6'l)fkuZ#L#Cq^.$Xm,mip,Y!,b.IO^QGp]jIS`kKnZ1l/C#jQrL3W%o2NQJW#\D(%W!s@W$C0U_@%]*(O<6qihk1$)I;8,g3;8-tH)G[,0:p*2\[#lEL=8F,aXTmh@j,B(DZ(1^7Fgc"g0jpQ',dJlB;8b,K6ZU2XoKDm9L&.p1ZV%Z*L.TDBO7f5Ng?&2.$Gn**TB827b:YYO0bUXG`(CO.7sYL)*oHZ`P>Vi:R#uqLM#;2h57?SQQWFi01H,j9O`p%2glrr%>s'Ts4C4\BBWUub7G.XD_^5:*bPB!.B<("lR/M3m[nCCh'gP6OVRbmIoR%[X8/C3jQ:p\sCMft&^UekT^YbkLm.]ZF+$l^h(^&U?Yl?uhq#DDegtIuRrh&nGZ3P__IZ&bL\QZMofsp3'`BjtRFro-K#N-FbNat">U:fO@lAWJJmJhB3be7>09!9g0rrqJ?m5i/KjKL_JL>?!V2suY#$IHaR8hC("8-V8l(,aZ67/@k)Y7VW2jSgn1rVq70J*)]m1'Br_#\FWsACp[@6KlH(9kq[_`sJKEIFkmYq0r9ZSH"br>O8bDqC)`3C!1`dA_lObk-$pr[Wbq)e1es[d*Y3+KI"VO8L5]^6lImRW(D,?Mtk6J`fq]VhB+":V1fSCi!>erU'U[P$s)^A<@9ML.'T%8Ir7`M.H=t[ROlQ1qkm@O&G%HarY=76qi_Tb(%SoJ7kbs82^BZ['/P^%99m8OG-to(?aXC0V'E[JcZMHBPJn!;C-0`@SaV/OTqWA$CjSYcm8>2hdpRE.2WViJrmic.Y\3Ne$K[cf^^uQMQ$9fYpa"dD^T0E."YUk:tI/DRPs5N`l),o9WOMGA1gcRC?jo7neM+93HT+Y1lI*FU5nHXITMBXf"HD0O``^\bQp`$mB3U8/(Q)9BS=Um[oZ30LhMEPZr=k8"YWWYMVu[`D<7jMc7-[Yn,72lC:H(;K+O,qj^=YE_D3C*U!AH*fEODdVa'(YZF27_A)+O_+eV*OK>G;h*uK7gSVZr"b?ARfR:7&siaO.s:*V`K\VBc35g:aSaE3*uT?ZJA1?UNGXtrt9l+WFO)aT\.HHR8mWZMV`C"KWZMo9f9\l!,s&\M1+rce!D]f1uka3&eT*g*trK"?fBW*g+%rsJr-GdF\2h2`jjUm??i+0idXHcdDLZktqA0E+ah1qL+H`JV@oa9tZ=IaQ#]&aSdH%n'1+&'@0F=\J71s)n9Ql#L5gDHIKLPU9P@RO02I3:!$Z8hSje$sDb>qA:r%59m<+j73ed`R*AK*$f]MOghFT2)*[rWV8K9jT&3\?=6OP39l7MkH"MO](V!)O`-2)@lI/Yb:$0l23q$rj\1B_Y1S7*7Rd1JKcqR>h;Qj(X)sKG5i1W+a'98rp\&cfs2M$O+'W)LKp.kB-J<+TmH:#KQ1$b4`0bA\/n'aU&9)e>G]_o'M,crC0a?JiCk(<5_]L;Oe%q7I,GO#1Caj-'%+ooaUj0Q[Jc]j[NSeIq+RP6Z:2l..J1mNQsrQ&Eu*I[/D5e0Y.10:8=G\6U0'LEaSU&'G"0'W,JaM,*9DNnpq`^Pr>B7QG79Ni8TN[lQ$D!OSng&d>b=m=HK>KoGd-g$Y$eQ!$+k&rT0IWIUT/6N(M4=Q11phJSs+W[48!ME)Tt&"Aru?SHH/a$dC!+!aIH=QL?1Tp*[%4nKp]5-?]8gSI^kVF.^u@X%)GL&J'3O$O"6VD:/=\)77Ps"U*eaLJK5$Q#32$?;RhBiX-$O1dq`@!=W3dh3L5M_,&mm]LX/C`U4249VR$NgMZ6T$"-L3700N;321#De;fN9Y7JjR3jT@OMO,I35%XY^(ZdKBh``G"UNFYBLo#27m;01IHF<6A>B"`]_!2@Y"bJNtBY8&[X+LNDD]WZ1C.Xp>/sT]Z'epijLn,Yo",d_B$"@A]?VersppHID&Bhc7+qXD76j+U(#N.54(-eV$,UA2o)nl#0dp_q1d!9lY$$/+.&&\eKA=9r*^#=/0ijUI\9%<-0uJ>?=KPB"MWNL._ji4qa-*h+ok=TV)dW[50i%im;UMkA3dc$*K*OO-4m7ki-"qFaG]`b!#@mVcI0Ed#e,u7S4u!FrrLJ(bl_4^P-Oc&N(!jIU&RZl5D#s:-BOWoD%^0n_&TPT_>^'<+>5kCat:mk#U3f/cnYq6l;(H1^^K;.)IPh%W4X9<3_%/V-#XSLbr(oesn;t`%b!2h6*$[.AnUBD[EG_L!(H@^kLUS+PE/K_*ha)@6d['gO51,H5lpcd"Z(kI/*-]L?u;&AVi5f>,A&7'/Q;D;m?_N\HiIrZNIXt5r/U]fT-JY8TpFSK*+KUT$*h,VFQl6mUV*;0XrAqHO3LWaDApG*7l,r=`CNU2a_IVs$t+:LTU$_H(@aTrC^Y/'`1*f+B`+SFiV)J7gl+MqUG/ppAKK/Q6oj4D-+]Us3/`&A*#,q`^$OYO9*#=-:R^njo[jUdbKX<08_54sbRFr]gM@92dVZfjL.2pr\AgjM5DKXrOT""B1#WUOsTi(eVH/I`i4O[$,Y&PYjM_U>QO;57<#1Ie_1cCBpT7KYA*'#H.18.o(lGbg`jdl*/__&*NrW8%$[mEa;i^2M%KMjfWT;%/;-%:HIb(2k@:gB?D/deZk^,pDe-iHZXXVSIj6:9F"-DKk7QJ+V=jAE=^DiV`^+VW';))ENT)W!7>Z22BK!=XF@_[*-XZRVaYskl>$kOHZ.si!pRms.uQ:oR%Dl=6L=XOE.ho5Z\u[4peI6VB2Q,]UMZq^f&rs\B7Ak"$UN#fU]7U\/f,f+0D3Jm[]CuYX8Lb!mS8.jKjMl=;u#;+366^tJ*f@Hr@'(F6HS:[gW[J:1\'Z%l-V.rG9L?QZWnh$)\I(hi@._&"f7Dr;B2Q*753/AoF-&0'Dn6=Rls#VT2VehX";-T]L"+TKWj?$r$K-DJ)E:/GY%k4]n7q&Lt-0N%jah^7N0k($Mf=6"=;BD$N[sL&"X$AsFEc_d/.@Qp1[INuQ^bT_)<^:1%1.&)=]aqdTjqI\!D^sE\^4%0Tm#CWrAH^c4>bhYn?gQAJj(:Lm?)-D+J$XmuDb7Pd(he\VBVRhA+sdiT!U"F_;24=Qj;KY(F=1!N<^q:qDeV6iV%@f6oO_F\pNd%D45g.-"ia(-FB,C+rgHHI[&3pOPD2*7!fCr.(CDFAT`])B>D[Bae8MYO0P7NI&+;O@6FjG13G[NQ>V5Q-nTn&b+hG8%<6h,h)D*Q\#r:.XqDXN0D6h?Sf\W&n9<1i_`O't_a]-k53It[a`pJ1\;!^IP5)2_H[Be1)'[<@;Vo^`o(CEhRsI]<-&d^qlPFZ8=+.dYO([G;p"!MdVoH&PlQ$HF/"Cf]8(=3R+X&,RhMhGsa[CpI3cf#8AM_mRE^8Au;:T4u&Z(Pg\,Q-is,Vof#eCS#+`V6IZq*ao89hf3X_+!q180=^LlhBfk0XSM^@,54QS.5jVQ7)"rrPfD3)ZQI9$oR+^hsr6;?Fp5%ncoeKY`#qdpQs$6p?*;,@ho[9l1::#G2Lt-f#-j4)U+QJ$oimH>V-g?K6:eJ',SXH8?T8oD$2ITn'8m

>(Y0MK!to1S:53Z6`JLUg0TBc&1@BZ,]mU(5%8Emq3rZcI*39VW!XILpBR,#6aOh1nrTrKZ_B>SR?H!2/l]?Y2&:Q9^C")3M1s0(6F@rC-T@mnM[DkkbneF3k_$Zj5Of-2KO:FQQeO6EVq9#k>iMiZUUE-a/Yb%)U@S^%TW.64rAS]eP.'VHM;a^V2[*\&#TI6o@plI2idcMd_kP]T(b?afcr/p^Rj=98&f[W3pBpHI'1W![?l,/[dHc#g-(q0keaqdbO.!2ZR2@)Tdq"n(c>qcC391J[9;<]:\Wipk0Niq4Y!ia#\Rb;mig)Eq*A/a6/gGELXO`_GEWDs\u#AYh_O%J6gr4$I,/QbJI+t]#pm#p*q$6!El'3]D]a]->L/$/rMOf6GA"+Nb96YTd0SC'EMT7&]g"Ycro_M.]].Z2e#K%,c_@k[<6Z6FFS&)8lBJ'qo4Ocd3pWrM..DqJ<1iL>]V/sNlAe#^[H*'GVFZ_Wkk[s[rL+.)o!Pq)VNQ]#-.B2WZg3\:h.No!,Ag]ZiDT;l=(#a)FA@kn,T\5DkkH5C*f(&rWS+d"h%lIR?S6c^r09+YmHTI.O65@t/"-=,&bX&%^8eP=(jZWT?8Z,+JbV`P6[ABS+"JX(VdjADr7'4*@2H#FM+KSD*0U)E/Lh6_Mf8Q$_kcoAJM;W\"n71jps[@F#"NmQTkGD(^n5(Wt0-7%H8BSXKkL+'@JX1F#B<(Hg7JrcEj:?J1;lS:OLoLf+`Fmu9qO(uU-LH01kVTOkF1kB^\97I,*NH9+dn;kRXfk_j1aYj[0$h\.:Cj'dqC\X_//XtX),`N-rq$&Jerf"aj,^Y`0MN!,pG3jb:*ADo8,WNUrP7P9lF.3(L5@6W_t\VmFs\!Uf5KP/;QlQq3i!5i7eN?jDKW9q:]'#\MiS<-2kT*PsmnFT:;%A$u'7nW:$)Q?T_r@cAc7GI2iHA3ar-n-6QScpLeRGkP`(YQfdRslc-P=%jsrhUR.qTEBNV@hKpCrWa9!"&!(=Z9'OM'nFUCp7X3O'kSC".k;!q#Vt"UmL_M+V+GXPb2-Sa`G5\u?QAAQ'Z_Cu)O%^Vnale]jDEGBca.GH+R;R>!#5<1S!e[rP0X^QPXjOT[\iBj`(VBFDu"l']9`dN@f]H3k)X-1)2.$//Ws&V5b\L.lX5BKB[.FPV5,2e=cUnSmEmr85pm\PREn;E@+@j+6ELd"`m,*=e=G,]Ha7@h`;\B-$C,/F%B5-iSak.Ad1B$*c=pZU#JrKH3fYE"eE(A$<+psedF#]g\>[1@KKo_EudO5]g3c^puY8J7>q?a#g/p*HnLTCm8'4/X-*gO-E^Fki=(Np^2fp2YRD`eic`1H0BW;#UU`pudDK+Q6^4WA6L4AR]5,AcB/;W_P<:SA=Tn>;dA@KFd3$E_W6H67EM./VTB"MAh4D)FBC6=XJb$dn;$%R79J5LdIs/bgAmYIel^:[Y?JkPa#]T0LuB#Kt6]coe_!$7MQ0*M2iVoLp5)m)0\]HX:0hmfIG%a/C/.CH9"J%&LhN=:h2:OaCJ[5%C"2e)+FU^M3nTb4>LWs8LiQE^qd+oX!<8BUkp>CmWlq4S=[539e/5o\Gg@%Meg1L*tCM!-$-7-@9;K[XS)_k-F%gUSt.W$O"[=*=aTZ4X:`j,pi6l)e_M*>gNOjak8DrN2.M"^N3k4r>2%4VVh%HiqJJ'B=U6%F\J)I#jK<-#PdE+@fYC))MSjX5=feT4M8:kP!+:E4Bo("X[/`S4X2,UnYT%i0dLt.T6R8[iCXs8sQ$Oga-'FQJkL`Pf!oEA4`)DF8BL1dL;UI;^bP#NY*TB?T1BgMK8.76Y*#>412toR%G9u@h#j`s.4dr;S-^Fac."OP\5_840HE^2^)m9#ho_50Y"8Mi21i?Ns<2+>/_qE.u[C?4@;H!S>t`\0j%h;^9#3[D;.sboRANDjo/'JNB_Eul8c6$F07_^bTRP^m(n!qha?g;]d9AYG:+Xq-?O8>0[,VR"p-2]@Hk(OFTl=0;2HWf7[/b[.Bq3R'*J[$;4ViB#'*HBF#,MDYmh9^O]3>n)Gi,tX+b3nN4:";ZAQj&3GRc71mp%qbi9-<4[OfBlbcN!m+n_NI.amj>)35LOo8Dk0JBtfOi*KF,7_M0*sZi8W`WC4Y@cp"VIhZjj%Q-R_V(=fSUnDW.7a0dEm_29ftp#,ICme.<=VN0$l]7NPe!$fd?ap*3+ZSD-QFhYB/X/ih.LHNLi*[GP2KoO.ZXS_RVf$SKYL0k;e%GAaVL$Ue][9G%'g`neT0L@rE/3LpA6bK*\UsM>mChAGCM\[0s#*\^Z5!M&BID4G(j^nUHc9R@6np&4JlP+Ij++oA8T..*pK7HB;I?Aa5O\t3K/49@[E;q/8h:$gX7Gbck(5(!sh=+H^UYV_@E/J#>I?CM(>"8-@gNac9]4>C$m"NTbeV`%!"!C$&QL7%YQOFqc_l8a*7!_`8a(U2$(P@^J'B3bGRkG'G!U691H"q%j]qB_Vb`o[W!`*pftr9jNKbqjZ;6i`^@217"aBdLE"n/H1Qdo/1g]@;tf\+C8,rP>%5YKrsT%(0nA>j<0E3A-k<3_+kfW'/l:2Yb>(M?+U2-<%"F.1:1u>2FQ1M&H/#lko^TgY(=\g0mQ2j29JQ\6!JV[NDB/-)I/39k;2DM36":U,W/*i'Ne,hPG&`mno%AisCKWY\$g0K'fO>`!F?5NA=#N"!N"I?p8'QZYc/FnUVFi-[AG7kn-]_R$E+asZ)qn;'LhDR'2g&9?#]V!"%UBK'X`BC2':cf14NkZ2$/iI_l_6aTBrtC$QCD';4ABLW8E:597953Y%nX^k>k0q1m1rP(pd8s7#:@A]L/n:=XdAUkd[m;l_h=VW9WiWg.)n74/gS]gN:6qs3+UIn5kWk4Q%(K"KBC`$Uao6O>0+i3`:E;/_m8)+nqt0(Hf9:'!4#9SlB0hS2LLj4S<8["_o0tnV8POepGF1_,]*4Na^LTM89$;<5dP0$(`X+WJ;#XBu&c)*dhr_Vrjbf^>.l6%A&Ii/#(5,o9f0"Nc@]YNhXiQR_t[47[5Op%0QQ03YF*X0P:+a]N.UuNIfc5V)2`n+fso4D>IkSccMs%O,HFN$7_1*qY(rScc#Rk+6KTLkT#pb\Sa.^flnN@;FZ9t4]jXo&-_'mVE--,TRX(7_BHH8\6;nP6!gq\BRgg-k`#LB+K=G'l[1u?HE^sZ[MPaNlne5EI`>QV-LFKQ-L%2J$gVHY<(@nFtY1RCb?T1lZZp3(UG6`35ro&Pj"%?oFmIf:g$hc_lW%1JbIoC@&].u0-Y5\rtu[oVLr3L.si;f,aud"B&EF?aU1VHpT!F,4!TjuIG%htJ8f3S-1d@oVEb/NCtX(o?_NK5,32FB5%U64IdrgkCt,>B.n7":l+?8QG\ms3$$&Ne)A3/lR,?p,6NQZ:5?9*DWe.``\n,]*oHakba0)1EfE@0ZD`c)j:^P*QU_%n3716Y#.=ElR#nNDE5dYh*M-Nh>&+Odh@`B;=sqKH/;7/bJ][;jnpf>_8%^_F]b"oJkMH'8Jh[hoH/$(C1ZE7_SQ&I6d%qA"Sc93Q[N^/:aqYnf^KH\sRtr0Tp@&hqbXJh&(a;'*%_eCZf36h9>^I:Pfob9driOi4G,k]6h'/\gX&8iIYLC[nTFBcm(DB((k")f%G=rt4Ns'BNg1BK'19i+s%\\M>^?-e,E"7"ro-KqkXI78*O-ms+l$]gTgKo[NWKOsr`JS&pQP'5A0I+J3-l[Y>kd02T9n"j/LPq]mVe]s'cuCCMD$2pVCVMXWQMuDM>591hqU,=(Xs;>#%>0W\*J1mDOqF=*b"c/A3`L0`.n=t9@LIQ+k711_XVd+^XXaC"2AS5@@'V:C@J%2.Xp(b_ejS_kp4(B>C>T7fitf27L/U0,u",>'rqEFbsRnKY)+)WcZ:[F<.lNRdTnY1^IZDIXV-FN'I%olq/YHXms%&B)XhY/^99^UffEUO@Gg5IKEddbRmL-='[@GsVWVl/VEQI-Q^tgH+l-S?,K=Qp7VZXb,C4]CpPSgUP;B+VfU91BRRh`7:t;&9^SPl0EK&B9b\J-)mb3HWF*ki[&p>fnHMV`gXhWNQlf7T/"4XDY5&M,^0,Q+mosgVcF&:@[A@CK3oK>UdT&aR9dGHuS1CTBPA],4;"'Ol\B[HJMS2nm(JKd*)!?Qb`AjnCNCqa8#8VH:1Y!j$4=alN6[AEff`[6Z2j-NZ$X<:s:gERo4Q4D)LPj[t[Dp4Jo;6EK^b:G^8uDb*/#/Dl%g>],-+`Jb,t5.6Ap9q*u'i%$'.i2S5^[=jF'ih4pQRSn@)p8L;8[-h9-,Hu%JcnO.X`*5d@+C+#=)i]MB=UclrIIIKT5<:)l4'g%>LYqVgXh7;JWd'?Bp.E?mqQ/%>Z-]g,uY1ii)c&&/,SkhDAI*36@>H/F:+r5LG332od9TZFm]fcd*XRH#iX3PGWHJHh(_.(uaOq22A(%OmBA2jg[?sEVlh)T%u*.eT+bb5#*\6_$og^E'jNQr`RAejC0*3D*[[3?6VKTj6/WS2)ea.\0NURKS6A*"eg9*"$;>JN%H;f#XLJfJU0([dTTV4"qQE-7GG]9&J\,F>q&&RS,p^NQfri4l]UU=UGsi%l.8caQM!907i(g(Nc2eeII^%!l&_k:Q'A/QR72(VCpi=J#etR0YdUVSRkLr8=l6BW0-e]73B8'4P0)F8I$0/$Q:a+91%)Q3WqL5;(Of@2\5%=ReH9?9$hWRuJEWk_C`^1WgBPCFQtTNXHKmM!D8B3rAt=A$(u)HrKpY`mO`dl[1=8-OBR>V*-t=02X$k+FVt@9%S'96'9;=5_Ir7)+:&4o6Kl5T)gi-Qbi0e3p-44:p6Kj*fdML-0Z-aLl-H/c+IOL[?!@rbPCk7c`6oe%_@']qmkKl&CD#FD_pR:`Fmf?l=6RQqmj?)a7F`nh]'%qc?I^ogJa@T]f=&WVmTS-&%P\p\ii-bjJ*BP)FBH^[lt[LUWAWb7J1NV>>FOV:L.4`So((YP+kd_c(-aO[X5unQ)0s:nE(tjMP*9sAu40,NpmYoh/5_e&B@4;euf+V*i:3]*KfI/[9&79jR$3a[I.If8h`o)4mUdk9.m=^^IcSmhfY'?#+dF.[?0O-@:V:&F["Q,VEcp??:um^p(*AN-o6Gfj$\m#o_YKMVGVgPj[WF^a)9,mS1^:Ff.C+>eL-s&a`F&u]Rdk4To@2gr1'hq\R-M4umh4I:Nho^Ck*#N9#B32t3`r4D"\e&&:Y+O6u$T$X+8l!::U($?)0nF5c'-]N"]@5g=!h(0D!554^AW\m9pq?a],SmN=hN?]%Q,!!C%kBbVe>h-qWCiEm'HKRI-j.4A&5^NhQAij6AG=9ha-$`!D]e*=TY#mf[M,fP3qri>$,n0qt&`noBSl3O*^CE`Z9]J5dj\9ll'RcW:oi-,n&Q8GkqjePX2b^j>^q4t@nWG#T'6O$<;eOFr&I$U+:W*:d:;_8=K52Q*=b+P<:Z2g)Xf\Y9lR&Y*6)c;n"8X0@],!8S4VYel@%Mib>+N[1CZ7LGtg8bm&NFC:VQ$&j*&Ek!`FbH\pU,TWDNNbS-cL%1DkU>r_VF2an*LCb6VM+E]`NcED&rN2-6A<;1PDS2*WFfXGi[IWdiDMHWKZLZ[$#nqW:Is7X$0?54U#VUg-6D4d5c"EroX\[B4S/2EPHq?#,$jI%k+RSa\dTlKgoH?Gl-,=-fVjmSHC!^,:f;VA$#u5J^,fm;Jc_ET>Go]_n_ug&;?e?G)]bgfN?NY=1D$RrIt>r*mChkJrWJ.Qc3T:V:`WrHlICnXg77*RlF5;5[,.:S7+JWPYGXO3`Y!XRn6r.D%'+Af[&H+XmY@1EMDAk'alr@CjoO/bWga$S.,[VqS'#hC^(5"LmtLM<]VPT+65\1#82-m\;qh%>/uQ1>\>K]df-bWXU1^O0Q08T0bTnXjn95=4-QcqC7ZuV]rfjE6$\,;I3/`jR_O,ns7,4>I@!]GNkui=[I:lc_26e0u!&:P`:ioPClRaXV=JV9MO!P18auLDAHPL2d=()inci))8$8jmgeV678fkHEJj&Na.J\,<76T8Kj.@;%)1I;gj-JD%/MRN!1"D6?#k`B"54u)EB;m14t3rop>s^-?8^g`cUZX5=nsSp[a*Vgm$KD/M5s7P3B(?P1mQ,%dP^0@AO%M18e@l*3M[QKC?)dpK#b74kNV,,6#)/N$neW9hpKSJd8V7"&(!ZCBGl*1%I+*Of$ATas^_5>P(uVqnE']M,l=?aA9dbFX23e8g8C,#-*2/rGK8YZF!dHs[%Sa\!eu)^+\298i.\-7*f[:9Aj-/Ree&6mg:WWlZTA1lYYqS0E=?6+LcMpA@'q$ucK3ZL?[%t(j!12&eo^;=,/O/;V]BJ15!mi;OX:YU4agfC9XDrZL+uj.dVfaHS(eb9!&QQ$I!;0;7nQ?'bfbb]%B))Ve1CojYptXBPDAQ;"N;r-q']uaJgn(-8^1XQ]f6Q&=R\EC6h2;Ot#X(h]iZg:Zs,(3dpZ98`eIlIp#3\@!_`_7CFZSLfPnnO\f0Tlf_XECCt1k'KO=jX+_#V4sstV7V-OA2'hjhWgjr>L*_1cFlPV-F.7AU/-f:0Ta&Cd.NUsrAQ@*7&;c34GdFMk(U6ZXX+S+mfS:>&d0I%ZZdSf&R(md>e*rUC0]P8k=Ec#N<(eU1LN=q:gPiHs/bjLaCOQO$ZL.('BB2$mu^es3EJmaCoBQOhW5'S,A?Ss][m,BN!0$2CsVmQ/tI"if(Z.ZBV/0pAj5D.3FKrAt-@heD=-Kh/1ELag%co<5^pPQs._(m_JYpo8Wo^b6AR8$?=Kbr,b^O9t>&beAZ*)dIFE9kiJ'/r`Pb9ZXO-/[[;76@jO_H@I78M$UeRCF0[p3`ugZ>kcV:PgT^+SCS!GO=lTC$'K`LnR+Dpsr\K,9eA.KE]mEk%rk818W%7/5TM\n)o-I[I%4dq75Xo+j,I8m.8BjMt0dWj6+]Lp:tlGg$[mA=O3"qS@Z,W>m2]X-B%;hH?d-Z(3Sr"Q'X6<"-LB:T_j5SqujH!l/1B8B4NaVT8o@Pj2Zjd2/M%1p+O&:X2\2.40[/#dUu6&s,&fmOae5Ab@aUdC7"$h>YTR`-!WES5YD!Pa)-NZ\qABR.rQE,N,aL]R,t.h,i(pCb%&&3d595^HZ_cf1@"FU]"-"r'1>j.Q\nl17&9?KS5,9Urj4pp(KIjJq&9PI.lGWr")ZNkn+8Khr.GFIW/mm34EtmDIIkp3S75<3*?o#SD&Y9^pdD2*;hu)Y]Or\nW/N4,`lFcTl030B>6As!/j52U@!!bPE"Q-crKk<13eg].liO,,3i;GC\(N)1*2-H&ElfB&aDr"_D.R&\6T^dH*8lIHPu9-,_#EP_gZa:n9f`>4p()QODu(q-me2_,k"a_*6J-%+^fU+a7b8N*,Im6YB)Xjpt;X)b.1dI]bWRle^b90DdO]rUV'l)'6*c+eDrn_Y-%h\d6NbRdA8<+$0!iDG2,qg$HUnVX$o:14fhE64SF@c1VY26=rPWp9p1/>Fs&K(#l$VGVoFPIqbDt!@&.uN;W>Ia>J#4$DjJ#I_WqK#p4.mR*WABl2H_4Qo]/40">o7d$Ri'T__7V:u$UG;$Zn=OU+OML#$2aW_VhqlNWn3b2IU)iPD9OE5TEZ3t/!Y4rldj^rMX_#])cL7#D+.NnK$3.#/c]nJNe;N[1UX3Fd^cd#WM^pKk#IfPp%2"ia'?2G=6s]E-Sb&eB21kVcS\m\KS8bb,8q[>nZo;<"WM_@g>-Pb%=_Z!cC_S(>cJ;cHb!MQ2N8\>4/J8R<&@#Q#(0q/D@eVK$B<6R"p+O@>If5pn:2O4<:LPZ^tKi+5iVtg4_P7sF,Qhs".,iO$?HIRonf)f83Z@j&_pbN9DYM3O8%+X-$"Mtl+[DJECO=prD8'a%21S$K!ckfgh0.\Us@b*"BtJrAo4'4KL:Z-[_Z985t/(*%+/C$D=R)\]iDCP:iX;[J$c&=9?\6hpE^+/Af3I'Z(djap]6E9IoCKitdj-(\QcVPp(#Ke^[!nu5f0Rnl`_7uQ3n'&n$Ep\4gmDG7*Nk-Pr46jHQW3H8:R?s]s-Y__X%>&X_JS0,Ue+.To.@]dje(o<&W(EPDEeq/TW^U`%I!cEgF[VL>%JUm88$?J;5K[hnqZgbrhmLP;_Y/FD>.g<<0hA0cE9P.RI.(+.SkY@B5DA^NaigU*+MpkEk'_k,fo'2BXaC1Pj:n<#s5',nJ%'cMe17F!G,/*V$gs>bB-:37G+=?!crFM_*$\2ZMt^V;PdkG)FG5UOq<8W0aSJXQ]EtWOS#Gh_hAWiL,@+ePsNGEp*Pqm9Sd&lgmI0mQX`k'e/BeT!8c02hdodR^HiFDg8bN\U@edb@`2rH6G2$5ZIg6WFFb()?A.ZTWG9R)KL5MSl#C'MuWPW:[)gJ0QP$3<]^+bDI=l."JoK-W6l=?8:ch`TaRWEAM*_!cu6!orD(DAFFd'`6?o%H?kgTM6bPXp4Bdj=X-0:@fg3`S2pV1ZpW%fMas,QTKp9;k=YdY`qIM!.l4MG3jU^g;YEAD=aQ:=oN!uSVaC;[uW6d.pPP!07L@d,^Gd#*+V61k:nTZ;kt\?aP#9h2ISR#84bIcjQ+dC1cQgBgiqp%S6XiFh5)M&8Etse;K8jE;6sbQ_=>=o['o_%Y0ubJXLQc+?JCU\q)`$,na#WcI1,1]PI;Y[DL>qC^F)(fe7s_SJD6J*Cn=B`\q&g%#sS5=gG/o3EQQO`r-5RphKttdW.t"NJ]b=\n>7>FY+,q+Ed9Y@ndp5XB]S%Y+-VuZ?UN7#^&9A:*aV*O!uTu6]45KF4>OfQ*5WAa$$)LIk25.AoSE/bC3UG%"&\Zk*rIId#aAhjZq5,U]3V8F7uLmDb;0+XSU&eRJU)'N#f4(/6nEu87Go@!J_>DEdQE?le?=DiAIF07S*b6:BO63GT5VN=([iV3Npc(:2/h-6R.jlc_gNFRI2T"%'sd0jW2m]e$Q,IZu./ZVBt^m&I:I&[hF2"[=]3Z#3Bf`nh[Qb$6.o_ptRmkE)lc`uaee8Kke*Q#-u@(Ir2s%lOHQ0+P5;3UgcnRHJ?"8Ar%>U=HD`Lpe1#+Im"\RU:Iu.B^,!A=/(]_6#X*6H0G5PSkRVcAh(_4`.WN7gOHkd.?,;M:.fO$9]H4OM;PnM5h,Ie6%Zh%n!B`TT4SQkO[t-#+8_8loJNG-:0@7`>2!hWlKG`8HNJ=bPZa61n$ZJ:#<;EIUo/k]Dak`QHn>>Vn*L`R'('hh3)n(LE1YDn"Ic%ZNkYXDZ.fH;M$#>!Z)VVWORL2gc#B)7.)Xa#"N/.=pra1g^!,;=5QI^!5@#?bH-Fo\.&MoT3\0-EH.=i,b$D9SI)0J3S6D`85"=[Z>sOdFYe7VUga$C@piYi0sW1?Blui5E=ONcE-3;_tW/X=MTHA8+V3LB9SuL3W"1;n+,jo#(78q%TjR,)B[_=MW(i7ING);\IH%Ij%^6HD,Q2(aI'+I%"XUb(XX!;lMIC^OEXJT">faS%5__1o0_EBr1nKK.]C5Z_/mS0O#g^]E3S-:D8_@nD8`hX5..YA1b+:fBG*Ro3El3hJbqO9%8/>+3QWPD4pW-@OX9;o2o@kMcXNF89lQ^)i)lJd.Ya_QjDk'toXorV8i1r9*MjBGB4P)d2])hHNA1N4MCr==02EW-B$g6!W;_uOF+/Zp"XqJHA_I;u8c3;+b(Q1I:F%pB_E^)ZD/hj<3rsLdrh&9-dZ_?]Bug#UiP>(`Su[Rk+`U.^$c+O6^m8k33daj.e\R#tLe.EG:luV,O9d/,P\:ti`Y]n-'At>.$FEJ5q=7;0rc\MNbX^\S2E)@KMZF6UXq+Li4=N.?-o-t!J0$^8EW1(/E5i`\LI2@lRZJR^5]nn&G_8U_nBs=W=eFY%q]UO`m]jPNKWhHWp.Kf%Ln]ePp!`KVj2OC&WaE:^;.VFrObHD!@6X-AD8=1+r$0bmH>76E\QSD0\84C_9C&ML+bsN7d%qHNHqtYST%El=doR,&dYarqWoGnq9bZ[3cJ'1]B1OaZ-n$I]YcJ==%qQS[LYS0(`^A.,mF9FbVcO_Ue#*"]cI>?]#Cud%9s@8UOUd'Za/dqkCElHI:T#3Ebcf"+WX+)_9g-2_*]Q.pR8,#A$NkeV-`;7=_0J(.5(R"['$)+W9sD)&!?4gJ[N:E?bEIg_P7GocG89jj['j9qAZ"GMXF>@8jd4C0L<3nP?nnK0HtH<&C6sm]&&d!hMn&0Pr'Y*h4CP/qcT;PuP%K$>ZONir`E*h;s`=Af<,4SDODJ:?i(/..SLAUtCh:@S%\1%g;PR_[>,6ocj_IKr's+2$&X[.R-O#%P[^b#b?UH^L08Zd2E]7>F`=&ctG;rAg3*8>3s9gcGJU;I?nadkO2"'huWO["7."=MBs)`!/Q%Y8Q&S2'Ht*1"Z(P8h6!dBrP9D;gkOU=c<_X=i]HPP-4Dm>g,/9h7"i>=akVL2=GLVF5Kh2:f,6UHV`@#-!Tqi!XF,,%'dhqGKGfOA2`i$fdo)RZsZBt!hWl*7"Ge'nhMnN*O0GbVB;<^gpG4+Lt#H*eLmqIAN\N$bT4P$uh7a,HI:eKKl,P1"(p47Ce1`b$?YGOQ%0^`dKD3/[!C/AOiIld.-Wfa:jP4(d]'F7cr/sb6iL4J06a'g3CNrl)E5Z,U)i8S])9L"mgMMcjC$:0af_Q!.LbYG"Y]:E"`Y@Q66.3a[A\"++]l?'rI#k4b6SEf9.j_FY]8``5h`Hf9?eYCYSPt@6c6#&-c8&u64:5C'ED)iCiedeJo)Acp^!b4ubg?!:-F&I"O#Si'mi5taMm$KOQ+=DiACnH?!=UH?2hO1RHc/!'FY)kr+Rd(^_rnISk3tP;rp7PMsSUSlhr0Z!Rc5?MN9@EGJRtm2RJsd(r`:9YZ!=aShfb5)5+K/8R*kHbo+CIpeYXa]WS]=6E+mXOqAlEK7"I\)nK>o![g3EQ258d&Q`J;&6bNK!E3)j!^_36,&Jug>Q3.esV1;Zg-<>cp:108?1h#W*/I()4];!LIM#r3ElQr"J`)MWa$d7n&#^7\S]MF@62d&2:qp-^il_C?U'*Z85@hT#tB_i=sq,]gDECkj&PV^c`#;*I?D3=#r3_aL03,`)NnA1!oU3#cVb_>*.q0dic$0K[>`gOr8r`a<^$E)G27R!KWZcI-1=0jMkt#bt3mX2"]`,TIi190NBDdT[FHn?&nrJgi`EUG@-A.6)7r?,GM.qq_RWjFIl:0-.S\nlQgC",^sgHV]-buW'1CCTd(UG)*@sLI`m.=&Xq7J7Z)s"^i^8tPI6qJS9k/&M-9+_RK8WjG:Bp5gOSV%'E"WsVOf\^hpn/d_.#>1[+5kBrNH`%JrF+O.%d0LZ*P.Ih?bVL*E8Y5<,6NVXn*5!&*+iEcMXRF_.ku)ZA/sW6(%$pH&j"&O(=s$hH\aRF"(Tb`)&__/[(AYeR$;jaG5f!WW9LVOC<7qI^T8%A(uFNsDfACp&AIn*7TYc!m5(_&$f=Y_jNd`C5,:&paD39/jH!.sBMSlRW@`Cbq"YuK:.0%X%cYK+noh*#\gDDH8/74a7=_2,YX5"34apP\Gt%X\8"CTe;##10c/\?8Hog6VeCMIi4:Z1D8:.L'I7$>F2\JOQ>75B^4#@peei]Y:(S'JPhTL1NQX\1IOX"%.Hf]V.i%cQ#4Hg9M=OD`pKFkDR8["+u;^6rWk4YI`mXetk`^ScQl"T;U&VJ#/h&KbdB\Kp@15$^[ncc^m#?2j'D)o]48^^e%/7'+>b@,*H4"?2M$*i0pf\:I'3&K]9_&;jm9>^I#<)aluL^#&-nD"\@H59"D(p@V5llo=3+f#8t5J&:AkYIK*lOHmFVB6j,$e)C'o(\'SD4ntK.>hl-rAP-0<$tC@*9l"/^L4o=lq8(?7bSu#9aM@=$!>m*E(soPu:Y*h;Qn#XZ0:YB:*NQ5CZ*Up^dOA$@GHX=\uE!Yn\SDMF_(<',Ui/m9Pe?h#Fk:35NF@^H0TdRjd9h7e1&K?P7jOrM5c+cK(DAI7.sA0Td_dN!N16$YY^8[_YU7"N=Ip$P4r[9c2)45kUV-C!dEkT-IGObJp+'Ho_RS/Tm^!*r6V8#:Q6_&XQ,Et8+IO`*O!Z1PS#"7&^F][njuN8l!eJ"IU(mmnK2OBG$3X_^q)i#brSnXl0@BWThS87)lYP;!GJEkAAf(7RiBQSeVBp"]hX3V`7E"Fq2%^m8fPf1FTCrNn&3URm%i:$5%/tid5Wlo0D`:&Ja77G\6j$7N2B=^+%5pB_^PNCU+9@.FWjkpI_rOHh;u)40-9k64`a1GZIe\8#q.c9#f.C(T-P4GSB'oBR7HkpNo6ih^j-jW_FcLHL\??sOBpdA,jPO3eVEUA5ZpZbr9MNIbh2XLnZi*DDoRE-LeN3L@^<,=u$2oU1Qi*"l;dmu\51h+ts/'t`CC\u*!TE!J^WXmDKgo(WTO8.d$iIs-"'cg#T:0JOf!f-'@L5Z.>h'4L.F#[XS6U1^PG(435s']!>8\B`nD*K\,e1kTr2U\TBc=V_moj(0&;)6a8EQs,^h@[/J%18XB;5;dVj+7"[$jFFK!)(^A"#t9b^6!D:j-r;=uc?_6eO/FnWapDTYHork^MYP2tZ\6*"HCpk]%p]e'HO;]8"o6Zk'Nf!$p&J$F+6a&'dde\.WN#J!9G'R!&@l>D>S6-N8QJ*V'X&2@@6J9r9U?3lbnJP^"aZsUp-CrZH6t8#t4He/%4G!3$u0pWnV0$MBJp.@d&O2b-rEPcq(LL!.Zt9XIjGF?3h?Y<8S6ZY=\\UdrD?I3ukJ*oubU#r[N*N8s,VRu[!V=YRa63THd^NNKYe9AXLPm>L\U\'#X!8^okYT@)/K`%PMG+PVJD+s6.3ph]'ToPHj`20\BLSD+U@3d0c=]Uj%',!5%MV*_j(FId@ITu27KruRna4CLb@fs]4c]h*\KYC#:\7QaMlpP<<_)Us#tfVfQ_[roCJ&5mhQ81'rda(8+Z6Go;pU?^:4K:!Gd7h=m@E!/GU*CnUJfASMrWI6kIt>r:"XhJD5K)jdjAe1&jg7//knPR?k[I?[Ci&^V,"$$2ZmlLii5+(]k@*Qb*lQ<2-%WP_]<+Cn2uO.eR(cf?e6lZ[@3PTo8pnSn5sAOm/Hk/R"`#eJHda3g\JH!X&P>6kQ>HG';LL%SW3c3FUs=YhlCs:2-L*X8KqP,lchHFESC#mc74s)M0ZOP'1GLHqf#HO6kb!a,K9dmE/ZdP<@=bU8,<_UomW?IiSI3N,JlnlEW)ERO3K>_66Cn2Mf?>FTPBAOg!DXfDD:\@KESGC+,rj(Q:N[7MgXq(e"33GFFg&F1J?ZG!%]aWeRd-2,k4fQoM(EDm.tT>K;s1L9jlT]WEu62agY3o:_P!1t3A%DD*kO:1<X_eOnpYXEpX'e3?/#[pSScYMT0BSt7I.&,4Pn?,7f#X0,mn2\](O?$)7q:E%<5A2mSZs"g7)iCfnuYU!/Uc4oPm0aXVK"2FDS@.L@]0I\@h8*FC``FT3+o\jJP=K1h`s@V68`%acA`'MqahT2bDg8`NDZUUdi*K&>:I=m/+g?n-TU4\GInZsB3e$Nl/P6L<(tKPHeYqNMSTKAoRN&JA;'ZnTD!auE*!.0LVeG3q8FZEfb(=D^NeU2M*0@CT8r)k+-,e02#NS2XrsH'4s,*r/("qBq;T+Gia&c7K`"KGI+dF8$7NKRG)c\fI&$.9Bq1tMNpA>+>E11I4mc?8Yf`d%oMq-968i:a%_=?`iiVrC:brKRmoE]$J6-/A>J9d@>TTYTQ9![!kPp+$&ko4Kjepj<>X+4IS:n0F8$WnpD^q>%9X_.Xk2d7Yr7CKb-Cp34]sseEoNlb[mpRVDlhJ-S"*#D:acpPsS*6+lesS]lW-$:8\QP)i3Q\6$<2n="F[KI-KbO#HnaSTl_t6"(:I(?^l?[RjW4A+?6Tk.ol`"I;eaPkOj$C3.2LVhdAuZk;dh<.UBE`.8fLSBaqV#s.I?B):JSakcZjA7D;^g&l6L9eJ8cKi7!bW/dbH>-S5Ltr'rUG@0lH%DHirdIW%GO$&Da'oV5QWW7>1a=e"Ve!;:&V)pOT=GCb!o!U05u)a?_$1ES_A7?mZGM[t3Q+oScHX?.(V+lB%dhl5%?]dAA?6-mIraa\k,nC;p,^FGd%(kV1Xp2Em5B`Id&\d]8n@pp*Y,M@Xi+?NGTXgeE2PDPS/hnUmGap$%JnmBhoj%Fthqj!F<)+j-/9iDnG`AF63C:S'U(_U4'dUdA4u\5cB$;>Es!(#*qg0^MouP2KgX2MhA410O1b`/NL`,^ClL4cP`I61E?K'[m8Lo3HRL[b>nsU#?pJ.s73M5*9QJN(FS>^!Wb"58pHsa*A`$;&'/@kEZ]E+No@oton3_0NF3-S63@rhc[![=)mF]6mdE]PE-N`!0BN.9tNs;RAL:>a/-"m/-SEQ9Ha?n0p=>SeMQN^pfu">VQ#'(5$WT3@Yr>],Unh?6,+HOq_3>lr15@PdS0&rXf.9lEj6Mi%H.iF5`'l,m:5[rkhBjuikLX@do<$paCA0HWJNCt2LIJlEp$3X*FDAc,Cojf6DU8"@S>SfIq\5ReM<0(j0e)_eKKk,P+*#F0)"$k=[PQg^5X7C'.4I"2PBB@rh#O/4q/pQ`BMK\SuBU2ockSE'A^:?6B(d?2/to;FJ;8'$1+D*!YJK9G,(SN8\aE/bNnPpodQ4d@n0IuF-*:MP::%7p@Z72>BCT1V,X:SU"JnO:qY.qu`Q+`>>K&XJqXS.hmu0AW20V")TiY'8fljSBQR*SV`9CD_FM%g31>j@'D)kWC:8S'Y>n`WaX/o1<;klfTN%uSKFsB7eaG(M!(dhkgRt/DR5FCRt#,LOa&QIY:;7;W\foqr6!k23rC3*%glFU"[C;1r,W]eaNd$%+Xe.gZT0gG=gKa16Dgu\LRaUk4*SE/(Dfdh%%G=p,_?:[MGR5`,hADn92&Y0?,68+Sb$IQkh,Ar";;u[mF.%p%Nf0u59'l.L%1&usY=u6).4VtZ=Y,2'k%>R2b?o/-d1UCJhl4V=X2[Qj3^,[]RW)6pC2$!YT/,o]1Ue78fqu5=N9;:K3BY^mf'XfIphTTlbI8?.K.Ojc&NgMSIXrd8rUAXLQt\joS+nGH;^P4r/>KL@FS]pMTT,gFd'_M@K.s9J#j"!:NGI"YXB.(8G?cu4bdNbR9S6b4N+i7OF%1gjjqV@=5/+^Q@ac<+`2s/S>:t3@AGfB1,^)8R"+gNXs(c\'rkG2]^+\i&bZ9,PV>fA=2/LKIAO=bM+rgS1/c6P:M^\6P>?lQM!gI.O$WqD(K9\qlZX4+4stN3ZYEq?Jf;^`DV`%U"ccCKfo$qHs?eC:'j&,WfO\$NU_]3MWZEC'@reI90,B'+Uj#84*AIjE&3hmkY>EjUblb178Y0nU4X)3bTi>n`qCIgc@'6?if@S`NU%+Wk>%2(HjVXMtuX9E'D_Q(-")_;EYX??`0l5eaO7+I8%.'jFmHjcg3t3C^A+M]>jR)/9U8l=1trW"WU3<5.q'rj1NkNF_5J2k3;0+5mA_4E3?\;b'X"r\Zl!;#QZ!g5e#e@G=I)W9Kf\F<_-,D.^ZIXluWR$W:V72,0oXD>5&%2M9n\4ac7U1j_K-Os9dha:dbh"ZbjhBU#_h-.O'>:lh]?`XG^7LuA*#rh]J?g2Kd\jiQW=NnpQ)-!MErf+UJF8;%*t3MsS>j%`cU7il9DcI)mI9V)g]jhCZgfrcoLkk`ToH1c#uPI_$%+-f_UlB*^]+\XVgW-&l<^m9fhf+oeUikEYM2:q9DSTS"'IqV4C9YT%gObu!-4U-P(_65]&6MW,dX(ZCMK6Dhp=1ShDGk,:.rsW[ZSl9,bUt8^^AsH?gW&F^q@a6UdDSG*3iha'1oj5]g"E+AQh9QVCs0TbBEGb"RVE/PbP`8I%sW=[G4s5+Z(p[&q5@SU9<*8h`sZ0HS22E+l[67Wt%k,At[Le$!1qI!LICR/5BqkXc_4J%Teu6>2?YTRS3Ja5&eaa3W2J.LmcFp#rG38I&$]72q*s/Y^W4,H_q<`YPK)jg#ZGU[]=\:uk&B#A@^9h%rY85cKGg8?5k^(HWk7J2qSIF[!+dAJRus1*n3m`=S;4<@a)VU8/b#8",dHY^4I6at59J5:hl""'!1`/p!jHQY&l#R,I5D'X.jb7Q)R)HoOdfVj30X.I"VRubF(!IMKAoK^M$6rS[kkMAj\=(%Y;Cd*..hZ3I_h?QSsq9?-sEr$s-CjQ^?'[B[a,K@.Y]m&a+Q)YM%;pq*g[dA2l8S>2Fn-SQ`gXqI^.M_B6&+50LAYamH^7'c`io@U82\jc^(iY6E:kcY>GX%lcLY0uUUribjYj]KAr@r-.a_GSEg>%+UQJ#QiV;igp3F;HZ^gkUc).:WZ.0BX`W!3.jgDdpU:$k:(qVU:Mj=&-I"+&Cnrt@)FIbTk%gcGR@\4*#'Hk=>,&!l)_n'D0&0[8]rV^Ed++F*'ZAgdL_]q!jUZE8FTh+.KD6&gu.X+EnpP\0'g3^T'p*ncQ-'*ClMbYVm3YE16t@1j-@aE]qK`K-b#S7duR,+Wi!/h^;QL+QfKf6^*`3,2N'?m0aku>fAtZ?ZG^c&pJPDFQ.Lkb)c&6Ld?Z^+J73NGk)'@c7Y6[-WC._+5Gkb`kRnNUuI3">Bd\XX)^`Zoh:_jo$>(@)H&>SlR@MWT"n)7`,MF-/BP_H*ELattG3K6JN:88=Z>ah6#Z>kK:SJn[s?L`s5s2r\>Gd=>b8G[#=5jD#jBiVPYW2RB'%u_#Y*B,Q)-'N%tTo$7I>$KTSP!,7,eqT8tSl2pRkRa#io0E1eeV7EBstG&6A4o+6jk_LS@8MD6S:f1m)=;\)*H`O5rY2U,,Zk@n`fC%P_ro11;MjH`lP]NHF2+g^T<#=FX1CK%/>R@lBb.VHMmsG1^g*!Y*\XXN2R27/YE8+<7#F@c!E_7Ths)!.60Mj-JdaiigWYtg+Mb\M7$9ouLVhOPn`2A3o)ACK'jn)WZ8^=6]`+L$#4ADX48.IP*5.Y%+r_npPf9o+5iQ=R&fboXgCbc*>]DG2l51$CU(7UCZPR,DZ#hHAK?rVj-)A*X/r>.#CcGs.DG0%gS/m0$dP*H`ill;$Cno]G,4d.`3YE>OFDZQB$9]M0/><$+C?oCSe#T>1JgD^n=lY-HQGj[6BWH?3JA0OLc'84mOXiUt-(O@Dq5R5r<#*_Y"QM)*pkPP?AAr2qSSBMS`0t?QA!'Pfgm-*m:Hl3`_HHbJDb]$+k#XX[#T=gr=jkhA26BkSdZSr'%MpU=*)',elZ.#>C'1^@Vb#p0Us*PeW1'%]a;,41l]-qAc4M=TO!i'ZZq-%QfRu:JQ$B*d!!!!@MdF_.j'R0#IaF[S`5iFY@!uPZ6hcf!^$mN\&%_M^:sag'V?A$jP"X@RI8GOg\g-COgE@uhRN4MMP@FZfK@ud_Ra=qfRB4SI1FJW2;!D^=&gI*">?@]fXSd>'?'L85p=EP_m-N$ckQL[jl2Z3LI(l-8iJC0>c[+]F5"Tm=[8g,_R=j9R$n]$),FcNXl$2.F/JZ^`P*7RbqTbE\d]i[*ES^J^Z^g:=*<\DCl<.!s,5L2-;6rDTOONPQ[KAA(MIC!YS\'RF<+9R4Q\j7!3,5pGn@O6[dr7>0pLm!>D[/,,`qY4(6HJYa[Xn?Q!5@`Hsc9W^"^/.B8,Ti.eneO'r#B+4RLX"P+,2fmc(3J%)+57Oi)As=LZ3U*5=@0qBdOL$5K-dskKBV:5SG(:V27P"EI0Agls7p'7l^noZV.puFoA:`ntF"HS-rM@LZ3_!7K$ORV64k#'buBX/gIq#U8>YKaimW8l^oIL"oY=Bdu,m0Uc'7M-n@[Wi%8crG7NI8OonA\RP1S1'u(bLg\Hga\l\ULf:6$N^^fe):iWGLh!WB\k:FHYo/]I[hdEgjnb.=fEso8kf?61b0s'c9]kG%N,ds0W0Qo/i]#?M'h:k(m?P<>YQtD5@L4X^lTm%4,JQ5d#pZa497Yl^'#L4e?Md/N]?Lracg8sE`A*O=\41nm6"nrLDhONLZ#k!?[D3Fj>@tGO^Qs2nNb%/$6oc`ZkdO@\D7mKoH6G^JWaHMBD>Prae?J9q.KbL"@E1W]2Fk9CHb6Q=2m.iHtQsM]MuTfOZ\D]*T=hj+,QfkM.!t>BhUj=M<%WplLD$O&HYgmr"WX*YjtKWAkI6_SZJa&L-?@GmlC/%Hju$jT]Qh8Z5`K;aJd__jiFuWKnhtF:nr\U!]j:OG\sSA0l8>&nL>(:$/eLHbj\9[io#q;?&^HP#sH`<[\T_*[s8OF\N.,keKr31g;-#H%i'5ii]mf'BMH]d.9BLW=b`mBY1lXVKHomei\9gZE?MRUef(YW)9H6a+Yq`E/K-kY!.+_8n-B`@A\0.D/#2M]HTh1>7nDY^1G0aGqbNQVYra8ubaC#iNZQ:"[9R:Njk0L2eW'+cu%[fMa)Q*SS\cgPa7/(PFHn6XEU/Q2p9C_Kf(7m8hgk=BfEbg3cD91j7o:2j[FG.\cl7NZe'_R_-0qnBhKX\!3$/uuQ`ma2"1qB\a);M&#M#GF?#8L^^q,r$rI-3A1jjYhA-s,o;!oCqi7Qm-d*4(]G9Nk+6_DF`h#E5fL8_5=IP(IY$-960IcVXOpLmPtA\X!OTkAC_S+*XFs_(%&642k0+fr\f[>o&<-B\E4ijl!;;YA#k?D#+55\9aX(d<^1$c'ea6<_U^lkB_%H;MAkD"bm9dp%aP-Du4T%sX@"ZK21DP_$H=ioODm5!n2&i9nPJHkoTk?Qr&8"s,d5!PN$pbY)BOo>51IJQT,R>D@;sOOdWa?WUqm^C(h@WT:G.*(+t[sFXt8GKac%r2JUPT(]fLgM9?nCIrQn1$"\\Jt_6Ck9P(H1[#]j0?CV_nZmLS9_o\JU_7O;oE(P9D-VcOWR@X$X89>(WVqEoc(SWXl<$D`(qH6bUb)\gnuA4Zt&o,9,nD3Wh%88WPV$bZO9ln&M=(=]%q,,O(WXb)FNOCoT&`V\03j%Y&;"*HekaIH%q94!5!g+W!U7C4YZ&"K&hqi%_36+rAON0s>j+bAI.7SrgMl$SJ6s3gTrb."S>gmgZ)])k.r'QiL7gFd\8W)uWXTXoSM6eW&5=dA`jT>#AV3Qb55*u,^tD7U('$'764Ou2"+(dB?Fig]?SMOFg!G)=)b6b^mmN95HY:VgI8kA.%NpiLkWWaG$2^oDg448IZ1@5Za7f!af3e,fdXXk[RL22jWam1mCS,E3f&?C;@(1,Mpc*cIhU&Z[=.er:'^*>"b26hiI=O?J&Q)TOgLoZ8"Wu&W&1Ikk5l+DFh?f.&qPM6uWMM4G6#RE`;M#D"p21kd_D*)jT\Xge'/B.^HRSY$*VMrZng'Bm@4^isLZ+!#n0t@1Z^No^;[oM\u2dRq]d2GIM'&JUe4bB0j1tUG;QZLKE7.W?>Tn"#>Z7,U+dk#G4;-LtmpTC$$sB_[e#NA-mJRHsk!R]^YHr;ALi=BR2qr(_[')j$AhBROr;&eB'QB=?!cRXMdftdUp3DJ-TLPF*FcUpB@k7,4<]X$=4N3uSlp^VRcotcn[DB(Pb)Kggc6.g^sTEc,u4Sl$RN!f[`9#$fF="-Gi$:LtNF5+/h2a%Xk_B@5Ba8Vi5J@A]CCTmDK+Ub0kGHTgNI!)/Hr6U"JC:&YA*c(buaO-Q1bWWP6/-I\Z\u(\u+b);8e.N2tUHde!/gkYp>PYM^kS?1Nj?nVg8C,Hf,5DIi%X<\*0l,QS8haZ6l)pbU?]j;."=I#F8gFKBIkOb@[N.^[(.?FhX9ooEZ+(Lu/m*m/Bn*SC\HH(o`AHr&f%MiLZRd^15kpa$t&p4PK=SpOtG:@?uf"X#E]->\SL79[HL;0tHgW5c$j7PV8#A8emrlL.TJ4.SJP@I#dH%NI2+PNg^b8n?NlacAbh*<(KA"km4)QDc&s(m8#Y6,>JAXIq<]"MAR@ZbEtsCVFY+3@*2t/DroD0O/:RVUVNbHY#l8K0ltNJd33@GQQraK68G[r[]c`MbmP1cej$/:?Z*@dS&UcXmE.5cSN8eF31Vjl^=Zeu-YoLCYL^jGO&Hp09SqGoacq"0*RKnN%:oV(WO7-ZlpU%T3(=@M.4#a'jmFO6G_:Za2)qChm7b;Rm(ZT*a,+!siPs"<9&YOc>Z33:^O36P(*+_nb+^+2Fh!W[X(SMldm=t53MWp=_r9og;Wk%-UlEnlT#&lWN"CEF<3*Lqt&U?6kN0=!Zl@U#l+-MKDH&/,%R@`9$6`9Qd!7Z=)$TZ_Yad2h!A[K3Ct2b&gelpnn"J1-4Qmp$%r40[8,T,fd^sT,fHrY"E7V8rn08[ed52l4T:1j2[rd_@)GOEXW,)Ll]:b^.i7h\jn!s.K)@^\O!2AIt[eY/BZmii5Y#ch0^"54R.^c";VHp"cR9.B:]a;en&Dkh2TPh::1iQS(B5%`\ogJ$D.pi8S(%idtS>PUdks")8XMM0]ad/]VO#''*$8XjQIRkIO!WaH_l#38;W6*I(pl8>`$lU`Z'4)A])ZERd(Ypc`i8;64>=^pCoc?BBHgVEh*/7:Pmup2]AWBs*q4\pM1U&2qs1jf]+sZd>XIFg]8'KSD4SK?GPm(*-UPt0DWNF;M\4B^EnF?"`oSM6J9aA'c7PO@@i*)He>kXB<5345cgVZBD.1O0>kSQ,!)Ze1fP>SUjL1kadB27uOZ&fdROHKB`O=6Qqi$=N&)lt/&'d&i"FLREi\?`/#r-iIN=[WN'Ib%TXTIIC6-mg__S4*8i=cT2O8KcIh/s5G+58]1J6k>Rl=L8N3NN?mDoI7^h[5FdlAB&1TA[,u#oWG-$Kni1lJl%^UJjC6*-4#%*JJ(?Phk^KE5Ad/[c0,A%PPgG+%FM%gD"m$#_[#Hk30:TLC`;9L<]3D2?8+WRdbV>e?je:tY)]JoBB:D#K-p6j%k)[SliVbk"jk&p1pP-q*lRUXJ1be#2!QG4%:bMG8:5=9hn,j@2m.1!+DVE9\hM9S`Wj6N&C$g<.J9GB6X>Idi.gIraQdZ/H&j,UisLq^g#23dmU0il+Ug_g"bk%W_Fe*-?=?.7"8NdjamS`ieE1U`$*g)!bbCOO3`-m&/TBFnE'1)thcfYGoO!9u"jj9,n'`sBd1.oW*rAW?j=F9_h)@Uu:Ml@m)?P7ZC;lf<4F%nHn"XHY8!UHk,>\[!cB;HoH.!>DP@2MRcPcU;3@FLK7_^o[b-H3VOW(O#-)r[%+t,:"Ie8BDM0[hWFD=;\ktQ#52o?k<\JZagbQ=es,A%mBnRgh;quJ[D>[rh`H_X:'?T`=8#SXXm+=*640?+$YN.(T??:=R\3Y]qO#f=iZ=f0X3DI^(hE^Tr99R`@Sn]"%b9=Q54ZaAFP@'iX=gi6^E1Cl+aLEK`);rM8F5sP[S&4aPl`[nQ-:D;KXW,.He+CkTX`*3`@GHhrcfI;RDEfM2@R)B]lGFINLdl2-7_%?Q%ma3RZkGP9RSO"7Bt6&Y(KUN@(C;I2U(SjC+B.-c4/U%*4,^_=390W*]iF>]3Hn$pdF2h[70H3og_W;;U*l]BO)s(9c`?I4C?0WM]>4_=,p7DNGBWOgbAn-H$-)\d0Ke%0Bhf[rbk!F((+s%\6P$L+AI]+.b(Dch*(3'9n?[bWCnaOPOs$,o,6AiA3e]=GaG`YO]!9Z(Hd#6@*.sEk"R2<[`6n,b%eSgk*1W4KY0Q:9RN^/6BI3jB\oA3LNduI$Pu0mX_K:t\eBDggm5!*/iE'IR"0Xh#c\[%].Ka[QmTcsUNKs9W#GL=d!SK'\C6;hV6gu<"9gB*0riQ@Qh2oC`5E,j402QF$9Eoq?*3qbBl5b\L1EmkoO1.>g""i7)M,0M9n-I/"a!^!kT%L+GSQ6$nZ+T_k!aUD/g1+N@S)D]u+R@))&,^;9d\>K318I.ln.#>f@7F*[^qtgO\QBSGnFT>kj@5)q=/9$d'Od!Iu5$&5S6O0DSb,$[?P^4-:THF%[Uh-AnV2'nnbFKiBP%"G>&ps0SDXnchAK\lQ;I?=joAr!o4)X^o0)$'6L1.I*,BXCrEPeE5O:G,r`9D<)EjTX'S+p$!%@0UH0!V=7m)MR4,ZE#_V]?U%D,%L>:"-guE!sUjVJH](G\V-&6o^uu&Nue_doS>CoNRYrKh&mY%^!Ng3VD&.V(U+9j45F/YpbTpIU0Kg=LiG4)b"D^uh2Na7bs$;L\aj;;>C^Ha.3MLP7A6FnMlYf/F`nfLm5-nV?!K*-70d5KW>)kDLb@br2^+KN!0;.A6^pL6CF-QI'/QfVp@;56M3ica$>m3/5IQ#IDE8bWB;7Os^n2]?=#ZOg2g+2u-*8k\fU2n[#mhrA\T?c#b?G3-aUFL%2qj>!rK)HKqUN[p,0-%;;(b1].!?"RM\-O5&oqMP/>p#,o00VqL;E@,f\cer5?^JZK`&M4Lom@PaF:NZ0Hh;.DNbAMco;8t8&=]4Q;7EY_o"TPbK?PC&_9lEp?oCZTZ1V[9t@c9ea2p9LL&2!#EO.OIfn.q;hpaI\R__)PnJqiRrFN?WiE)"j:2D*MGcuhi[&R#rnS4)4?GNXEB"9lO)D^LB9)(pV/M@ho\\'EkSSQ:'.mEs7U&Ms%%`.G=XM;(#`p0Kh5d=o7OrQ!/`8r.cCEoK8/A9e*/0n-QQaX2FK7#U!N@\,K$Cn%L7/`=";c2T_GhN]`Ylgb)Ao]I0[uT`qZ8P,b/s/4\(p?,>%-08)PQTN:@gR3%q8p5.Uk7*N0pA0*-7JSUrL<]Gjr0c-mH/A6pl839H"UsKQc>DO*nC?a!2-N*u$k\<^'BAkmo`C,Cg3,J5EX=5?>"])(;T$&SLLHH:(UZOe0.$r:7UpXU^_#/%+s%(3#6FmJ->B,_B'1Y7.`%n^)4?l!!@e,g07#8eg(_J#!`!a@dYtG1K50k@MG!lZBa!j/7e)8ta1d3&0.Y"$m8AjKbhF7-Yf.?(HrJ0_\a[b^B;>\+ODc^FUEUPqgpTTt5V%5N3'P%Cm&aqs)o,LF2A-jNg,a&_#&k.F^I^g`F^F"L)H+UNf^W-?J_hm7s#9UA-B].k:F[1)<_!Hoi3*!:76g9=b"'T@,;t5fu,RG`H+aAN80OQXYFj].JkNi6;Kns+Q0XoS=4C%5RU;`t^^m)$WqrOqrlk\JkB4@)jmf88"oFMC=BddKlp^bfhq#;UB"6L+(+DW>43.sfI=e?HX99[O@FV&lW7=fPO:Dq/JEcmXVCiV0Dn+7u'+m\%M*+0ff(5G?-W'rXV>Sg@Z&'3Z>#/*CDJc58Z![Yf$RYZ/S1gJ+^/Z8-%8g)QH0cZ"qKhM-*8BM?*=C7R*>I(5@"\E;$!_#55V"Al_'n5FM(W$].=kqE-pHW?CkuHRm![YQhUO`3WAKh$KE!jH@kjAh.Y#*h:dmNd`#Bn'.N+4TLH27g47!t)WMi4D#foFSD^efMTH"56#?CF]`(a'CP\M^_\!NE2pGI,t,m'>/:,iR;LhN_-j?r?c6?f'$%*V+]+*82H-c*+1D&#U[95?_AD5LjK$i"t\c;U@n7RPBf+UCN2a@ZQ`h`k9&=rTOGTOAOF+(^`2g\>/.M3oie8l2t>Co+MJgB03C'/3R"Zr4tL'No:)b$#S/b@N!,QI)uS;Hq>)7A4Pia%RZT2q[fLoX,RCDr&"osa@KOOqW6Z;O(n)k;JW_S%;/cJ*X^Ie,_2M1^b5:7Yl&l)p?i1_h+5Spj6Tqi5=':.\sa+.P81"?j#ChW1?B:+(XdT6PRTnZ]kMOUnXTgRneA6cagTC+']%\H8B?KH^mk&^!L5#!`j+LPrGMM$O4iaMKWepc[?P44Q.s!,:EhUPRQTh';F7/f.![a;4S75'lk)=FBS"o&?FIK1I7!(j1!rVp2qR(]mU>;l)UeE:Bl[bW/>%L?pej!6>^C=h^;oj0)\pf>fL,*J$RB25-U0\/]G,jH^*7=u1S2AR!1=>jGAQq5F481DE10usr"8.+-e-4n5-#caEr=5@Y-;.FH3)RcU!D&!b:OqLKP6?Un$TiO\+WAdH7:M.G9Q#h\f_P,8-'nI8;r^$6'I:*'e30G87m9%IY#mu"9K,Y7#D2,j:kmM04SDRYJ\0=n([biE(;J]JE,pd'P/E1.:UQ$*jlVH:kL!NK0Y&Cm;@@qc6N=Jq>!0;D`@=f(&p\21?t1eh'c#&kD$gQ#u]]$?utRH)Z@FC0CeHUY8K-4g^7`!g0S!=hY-<_f_R;2g0X-IHC(c?Xd]8_KWmYH$rag'(O6\R]MZ[ajLKob6do/B%DX=O[I#OFu(g]I-;A@fNN/\K]sW]):'FPp%-4/*YW.In;@\X#TugNmOrrd_1ECV\i];g>d;-m'h:PD?Z:N#kQr)g66RI:J<0t#5_=`\hGIbogu6,^Mg6%L'Q2afm-$_koSFsbEXnriRm(b.bZ(.ld#jOf@bZjhaR@5,GV^`V:s(.c4jXC!8([rYJ<9Cr,/0-.G5)s[lsXRDHROT!5?^Fs"*C-3JO;o_?O4#]b$-:a7,#M2UB#=eCC\6!%!fPCKj@LFL^3U/#E;^Vp4(4Ofg8q3r6*JmE2P@'+0YB>8)U8"DekeS]"F("43Kj4DEp36Pg5%hBD]GHn,\OK(cJ;/omWNHc:)MP;Vo'L2*I#h0?d6qRl[u3/GV$dfmi@(orok_'\V1feBhO+OkZsmm+d^Z+17ZB)H0kM38$*R'PChXiXS6TUMcHa@[5Xl7I6Bdjc]5GJELr'[YcpN$-kG3Raa2/K"d`9KI(VW/0E1U+RdlZ=rVd*.E``ctYTPX-oKD#,E(5BZGF2f/fLr60%pcM7@?:5eXITUD)q%2I]AAo/llg4-hSY)U&8V]QDi)r?"f*4oi[@J(coSCaq6jA<(oC>7@.+=lpD0tKmiAIiS"B:=U+CQE=R1RnGmD.',lZ:'059f8G4JGaa=m'<[-!rne'1bY?994kl$oG"V#Y6K[EFfkT,6KdMUI[l'E3,1,fS0dNCe30m]*VJO4"0($/iEY*];8jH/e-]8P9f[f-d@-on(7$SKM5;cSX%uG]iS3^?fX3&GqXeAWL@M<0kVWt%j,\U[$UkFj&QDb15h.-O+iM>D_XVc_5O[JSW#kiCtUN#M^]u)8aIHUh^$sr[[T23,paonHkfB85kt"&T`VG_CD7Zk6L:WJBRi/(,`pd(cG#;Eq`;j%?hA.kUc:`c#RTJH8B<$)(Biu^=f,X^O:#N6a(-QTiGR"P.IF\2r-eAF(H"4=3H">C#-12)T(V_jI+k[DMn[]cO9Ou=d=1mKCF,gEp@#\P+rTXo[_)['E0U!Q!qjAC.>,;rM3&j]fG5`nnL\<"/UKkH;n]=Ra#Ok%:;c@LOj(`8(V^fg5s>G/?5W!prpM_1hqJMJZAg=/U@B!7m+=bt'73]O0d(^\>(3#t5-$*UfRF+V"qY+(7"DUMni!=VX',jccjel3_'2>77O?,++H?JM7FHkEg%g4Yn67B-BEdK)-*TR4<5K7,*=7)$6s59#;k+VUCDt[8ie(^mBWTd)QsY:R'CjJRcnY>pIOi>DTI:=.cdP)..Kk<"A0b$NU\n.d<[-Qq,*`L`>+!H!LfB9U5IEij*)M6kV3o,q+]AZ5c6ms\Odj\=!`;+[S5)bD[MFR/koAp,&htXUjH2CInih#r?S9JZ7'W%6Ch+r7E*1chQ(hR4\/H`\lM[l3kJg*MMk[[-fMs6Dl"5NZJfb/U8jdfprW2IA_T?329Tp>q.6l:W,\T3QgOSA9pB#uHL2qPeaZ#0Ge2)CP.57sTl"n&Um?f2;UC$o]B0OnRNAsd&B-fq_JVX6k^6IH2\@LO+Vp?0!+V#/K=R0r6FobS`?5n!3m*`"/JK2^`sR#)%N$7@N?^EM=`U-c/<4>3o.f#9JVf4BaKY,a:44Def)?U;qH-o=.5A,%APNo9C\CtECfNr;nCuRBXFKSo7JP2YsOq:'IORR1!@dc"+;Tm1Cmced.U2rVFD8*BSoM,b*0@k?2ri&lC^(6!\SK`df0Hmq@1*nYZKnpQ]*/C`fg=Yj&2Qj*lB$$o:.Dhoj>QjCo$Fa<&^W8aDpgq)84Gok?l"LoGoV(3\Cou;YW<%b527i,b=NG6&mZZs!.g4eAAUk_&dig_q:8)Z4W>H/.IIXNW2%SSg!Ld6*F'iNk!2)G&/OH;;Y3j,nkc'*dV'b3'C?YCJJLZeU/;as/>Z&VNEk&BDJMt8r[q6S-j5FKTNhI7&SNSh@^/[\c3J3JccW/,LMl-31*o`51,T@W&5UCjTr^+(L#@3T)?l5p"Rut897%;85s7l!jis@9[QuPiX]o?[d_]thI-j6e4AOqVRto]c.Ol\dKRkG,N6&qFZ;i,d(2n]39T`4^RZ_35/M/fVW^bBP=^]%iR)Cd1A?fo+)6'KFc&ttU-r$$'3k?5<8gP-B6)\J=[>hZgR_'e&VCZ2rU0*7$'EguEUBL[)\l[ep]_MG$fr*3j)=Gm_1&t!'(^,nimT>:KC/,Zn[JpVNqifTXA1+Ief3/gh;B\/7=4k,/_A1_-ikTAoCJp[ZocceVCpO41cq-.kOAb=#f/=4o;G*8^UMeHhFDsH$a$h9&fTKhd+Gd$u=/PR@ERAu?1BZoGapS?C$?ZGDj&`>B-UZm$&4hqlc0n!Fa,1\J-u*W7\@Hn,d)5&)cQ]Y6$]?;Bmu\lK9L'1S"&eTH4fm;9$boMV1A^0+#`;`6?7)4!V;D2N$O2&]quBbH*KUCR>a1Q;F+JJrfSo"TB5"1i\._WIP5:o\YmEen00+ODF\1K*VI%,Sd[)/E"*j7IT(`!p,-R!&R"CtekTVS;K-hbb<3DRBS8@F'`aJH9HnRqFB"o-!pA+V;)/;0*-&nmpQ8Kn]`KAhsNGPPI7^VX1EW*\aO1N=.(H+Vc]%jMQT`p2>IWUV%Of^>LN>/fQK,Km9To^[&ac`[&5*;%55?XPo[jPbM`EdO6_`+U^*7C^Ggqrq1AP!Aq'Zd[5F*I7Q"Kg2*N]:.miA0W_.VB<31-K:?E(A:.l29g*gZXnUC"P>JX=^u;:mW%eh!=PX]PLcfrFd]^,@VrMd57i/gPOG@-=Sd/?n%+S^ZFoefo&OM_Z+B+?CCh?q_d6juQ1AC:;1_)(:.H*H^LjCFT\/[C3\eS+7lm/0MTTfQMXP13@0lO%,>&!'[Su:nqkC-YATrP_@.[IGrQAS+i(s3c(kf#@QPO(_d:c1KHUV:LL'ma2DB&3Hee9kQigi5?n,u.H6tocTHZQ&%6Jif$n>YO7C?7=I!MA=j58Eio_O`B-Cp7Yg^#tTfq%OFnK@@=Tu6-$?NAF/0qdY"g9I"`'\l%'M,bIOY`(7qRO2=pnUuZ8on5">nk4]TCbm_Cp2e&YTt:C8gENj>9Q^hTk-#Po#o78XaT-Fa]&j7eb'k:=:XMPHLaQ8MHS_oQ@BCD\l'W,sQ"H_%m=NpVR'HPQSs,g<7BC)&,quQ]LDFdnp^Cag)P]#YC$?,bn>:5ZZ%8E(<%49\:[jIE7]49TohOAG(T&Y$$a"oQjp.o.O]eO;Y$Q1%[n^_qjuQM-jpfhCV?mn,,bq.JaG!J$Si$En?p[8W9Lm0*,AEGRXD>S=fHqs#;e>l"fjmHP<*;lE;5ihcaGF?>u63-g/98$XUBnXAMho=fWHMi9kT.ERppOQV[(d.lp1,"U08L-#YR]I`J^TsXM[%F2qlmmMI10rbq0=@(rB7$:"+-1n"p=-NXdEL]egC9d24s=-/=#m&OI8AEMo_T*;MitAiX*Y"B;9bg#`4'C0Hqba?&l3pT!?N8+b9WJNm52MUk4$cTR6]ef.B<;4)so@$V)-I;kpmdf[DGP':i]Li)S<*sW5dU)*9Qe!uNu"\ococ.,;:n=R='0_]%nZdPpJQ1KilR&9S4en"\j=jHIjccn]#fsl/#Sn@N:dOGB^%9b>jd.1L[_ZC/EgJ>^4gO&f>5FT'0o7\3'SD="'.bJH,CHI;Ec[**)JrhK=Z4[,kgX1?Z?$YX3PmM+3?8C!&5.nNf:t<2n_P\<:6E?bk3ksB08<:7=/"kG90i>#0^MeRT,K1h`)C__%^/j:(//h!O(nI@Fji/,JbBc,^$Y16dJB`UOLkdREPsXP;4`&cU,/Tt@r&%(M8>gV$?&d;KUjA`'=A5;Los#XT:^`Bnr`lqYu3@pNSW?B@`*Z>9t08P]n.UM40#6=Wo9HkL:pD5'RoEf(?$`MB?:B!a:NjN_j^Q_r9L,]o,Q57.drCPh@q,:<:m#>%!BqA/p'(JSqr$?E!Ib$:iNaJ?/]3L+$m@%F1=$f:===\?b>4PFC2pYidS_l2M+5'+W^D4-p'.*`goE9,6O)*C#0^l5ld1I8j]emk77^AL.Kf97cWR+je1DKs%%\_PXs848i3+f5q,BLIY>YVa?R>fnB2h:)c?![OJZ.G6\QEJ:Z@a^eosnoeo?Si7[s/")g*@/EXGH6LL"/acMM<5EaI1Kn@TEP6KeHhBHLB5?8doYM<0eYh.QY<)VGclM3bkLh,0q<82p0$UN4GSRVV6*lET-;i,6:aeX`e[?WbN@?k!nsJeg7P'FJS`t'_3p0?'Rl\Dp]I$R<$n^DpO#\p@6dI1ic,7()@F[`N<9or?ktBSpU23/eL`5dJT"WU)O#@ai'XWn.0-:i:4$n[t3JD'AelT5O`<#(j6Q+iD))3]D.EfWQe>k(#Y](.!2Ah;ab84`ok_6C];A*,"jO"(Pl&g7:h[O1".B(\"%=m;;B0mG:.$#3_gLp(eF1!.uT`Ur,XqW154'WPW1CKEdX?4`1gSU?K)?c.0<^&3RF1h6(?qm#!,7*IO6UG=h=(N!Y_[2a'QN?!PD`Hc#Q6Em+"OfG#HKPlTfe,4A!_/uL9db(Fr4!WPbRp/A)j*(SKfL2BpTH$WP6O:>)FOSF7^FiBUgWWGu%IY`:r;J)KFlV$t[%0/9@**>M2#PR96V<\JYh+@*)Bn52lllkJlML(Lc[C5g_m&?eKiiqSXZ`Xr\<00!IC/]?b/e)['ADG7a4oMN)8guD[K0=.Ya,\+Ti=1C$(qn(Za^p$`(e=*1EfC?Ub)3H$ipjRYsr`Kj9B@,"n5"h*[";DY"OkE<1>!2,XXN!p%I,)["dFj+_R+`G!d7+/DqM62Jco/,@L2"4-OjPM^hIR5a"h98PPC6L@.FJMQ)Om&@093Z3]A=U/kK,Jup67"c4,*Op$Gk>Ib]7.GQTcQH?JKb`L)g\Uo%8V8C$.3ljl@49K'u20LsdRhu6sR>@"sNgQWHfd:s".B!J_Pt]k'630n3W^STS+\:Ob]V:KcML$VDL%(L!!Z-uk0LQ?Sa?NaAVk2*\$!es#gf.aa[8cS[VKo@U?*X:tF_46*\S]V8lu.OgRCbKK[tNpWI!TVR@EVO^%12:dKK;QPcni--N]=>@hOKCB]S[td7u(Msh)8!7Wj]%a9";m79PC\T]*)1fA0aQSN&6VS_L[_/ZfpEB/JR8Bl%C3/2\Y5c3[Y2F]h![C#8>%6`kXN-SK`Po'#<[0"Fo37KNO%p6*^bH5VAl[BVo>`)2rMp_86BPF9b+q@EcbXBhC1[7#Xku8kI0_=;VHBQch(o5WG`1"[rTffPW)2aU'Q&^t$p*I.4f1RA4Rl/JQ&.(mYJB@R;I+6pJFO3Wlnr>spnW1>NC1!pg<9+h7Gp!CQ<$>9^RGO9eBB#ukm6<-A^6$6Ok(U0-c(5*^J>Ji8F6);Fi_'l0T!l+VUF^8Gg*_=VpK=FQt-?Ab%>/4ft,=9+XfM*rbG.mfpK7YS-K,aF't>*)2W+r2J/;@(BR8m)0S;P:<4E82RY4V4j_-86a_$,(!]=f+b1Q>W$,\LE@VIWLRh`m);.5ZFQVA:]P\-j9]rLoTb@N(Y(pC=o8?>8A`5]=5@N%0K^b&g2hS`^e.5_RdPWKnJt6%*rVEaU)5X`%7-#e:V-jqgf2u$.p'.H9d<9&tbi&Im-Zlk2YNrdOPtW@]G:GUre<0-'1q,35EP>)e_o2NJN`CUo8rKO5F6Q4TY_tV(OV]Kad%jJ!W)(!gMNXT%+9XIc/"AH=9;O"]L"7&;dJiZ@3!8JWg4MI-ZkF=)(RS#"?YVcK8U*K7A6Rl37*u\IW4?Q-8GA)SE.MaGVh4'^l1g>G3[qkq,3sR1:*TXU`_An>U+V>$;J$fd>-'A%c>%L:?9[!edY\f:S7Lp\m6PSL7:Yj8LdbfZ#GfK^VFm?m4_:IM)!c'Huko$R6C5>8$OM&-iUdeG*[ap`\8`>W3c4F`sk.BD%DiD(4f;!WZd_5HR'HA37`:.m@MW=XBRl1pO\5%:GQ9=C+Y:[t_E@0QcG#QT&sqK4RD]s#NO+$+8NA&!Gt732B`sVqeF$n\93)NAm+JG2jdEN?S]rC!g2oX(U..HoQeN#HS*Zj=+&#jtj=+r8`8Q<(a>)_6+-,fC'Sf!3>TRent2'SWRG$8'T&q(VFGim_;`=`b-Z@Uj+&^.M^;l8XegVt9da4^if5nN4o[ek/dSSi%M`jIT1.7XS&10I@:$m&gKPV[VZb'\9q>^_=UGDMl57#GrT86.pK=Ku>P*t]./7S3e[KRj:a&K$Km^jU]AL'4Ht^H`W,HTPD.;?i+kQ%2sPd&`t,H.oiFgGN!XC2%L?`b5QAjq\N@kg0En==t^9A$=%4ZD872m3e-`R%RQRF:H,2Yd?2M]=h2eDKIi-$-pa[0`.h1,,-MSC>FA]tH*ub'C,/CcB%DecXHdL#CGsm])3P9F&;!9Y\)?c]RH;dQ7R7>(%2D`P8P,X`8(.5$q#)jp]l!<:TGTPQYflkVpj\Su?e7n8oj*,CdTn_;[USHT*o9M>'#96G_Lf5i+cmk^_H>"nfeIXV7J@7HsEk--@OLLr@:Q+.-Yp.XXP&3ltbZM[B?3O#)pr3X)tiUmqe4_<2E;6D+qsaKc]"!gu@laJL(\"diF'mA;S%[K;&C@$s`%SseJfjDZs%LSQ:6r)b&Pbt!drKDKF=:WYh/0[lnH?6RV>-to"&e(/Fo3t/]R2:j'lP"$#c&W_`1+2l3L:.(EUTuaXLe5+Xd5264S%PtuCVmW&:(eX#0a4fT?LthGJb6u]Nofe1/2dG3uD@o\dq&BA4[X5#]!0\do+FKd7n4S>2$6R;PcUmQRs:ugdot!hf=JuEV%[Vn[>Mn&8#rALC',FFosMBsN`-SpBCr,*E76Z!CnKU=?WJRZbAM[af9'9[O'fC2$M/ZF7s(grF,FLO6WsF4nHYtLRgJL'f^l[Pr>(7g5TpU__Gb*ela>0,1jDDP,u=Ef%[Rd@p<#oCSe<_>/"!`<_SQ>M38FR.c]nJ2@3?&2*PPRX'su^o1ffTq.U+g/`E-hi\j4NKZWO<[W4'0nk$,o0.B&-J[4Q,Oe?hpsK4Mr\"XZ"LUt[5!W,3h"/J?XtFRr:dI]N2H#)d8q<[Bp:(#Y557Yf6Tm135JqMn:Q%NSLDe3r8K?,`9MSaJpS2N3bl9HDX9'7;RofO'r,pAgV9rAjP'>5!#hr?CQ-:V6K1p,rJlBujffK(?MGNYLE#8+fZ,9Y'rBc0DB@mY>=K@EP[h-pO#"Q40.PSsF=)i^g>1*Ff?r8"c2]jZGYH8bY'6pD;gpWA]6R:-0.WH1$j+*h>;#p%C>4UVSbpm/LV<-uefkDg1s"GkDD10pH79G@H"!?,%/]?)ou]GjQ>GQ]oi7JeAdf-*DCSPA(V9PkJ$%YSY:u(AH]6uMBNSf*E\sYbSi!"6b-`C5eiYoHE/JEAIA!`H&"3MHJMHh;=rE_khJ)f$\ZgLNk$s8db5f@DHU\d?l]mc;R"sWS9GjH-jK?q"I,hX(<"8\c4)\lg,"G"0KjHf<0(""B'>,$$]9J=G%f>M?NgoZAT(,HI%65J)!_?YGCJ?>1chT:WVTU20fXYW_Q#"1*l>l#nVe.()3TrJZ]s@;l:>/T`FhBgB*/Hi1KLpW;.h`"rXDA52?\j6^SZr7UK`tdeVMV*b[DuM1o&Ofs$:3C:3PLg)I:"Jkq%7l$A431E2*I@:A,M4DX^b!eRESdU>Td#\!Bi+>6Q3C/0M%-WT'FEWM1jZP-36/3))`0CLd[@!Pe1+\LR(7mkY1?pOQ;s5/#Fl6qF)`,l)k7kqJ)Jg$(a_p^)(l3t2bj7`D)%-J6'#hdr66XNo'X[#_Q#Y4:6V=LfKAo/Ffi%>o+X:3VAk6)?p%PVb;eu5UGDU5O&#W,U0;af=.7Ur0hc3ZV$iGnPp++#Qm)r(p2CIcU$(Jr/\itA-6*l9\uJ'-W5_<%*\o"pbLiZNS(;LuJDu$8*%CKIN][^a0(n*e&$(GdhW4(VmA.jo*s'32d,p:BCDkg#9,,WiE)!WiE)Ml'`V-2On<8@2$AR]2UXnp+/j'T%+0%<*7'4grb:L9cbDCAY4!7TRSSdZO,Dp#!ep2`)NR;6nBTpEn[C%A>scXC5Q:;d\V#--*>IhACPKu2=RPF&RZ?;1<9^b:*>!:i[>4D4CemKWY@i,5no,?'p'bXf*/mPY>=n&IW+#ch7.:iU[G@dcOA<"U.$*!b;WQuK*Yhm@@^X7!?!R_nd>FG6k.+?P-\8:YU[X[KEsTl2MN1Y?78kUcuSMuecHO(8dL^_U<_t=B)ASq8PI[Q.B/L55sW'eBF-sk@"AbX".3MniQFrNj5(>%,bC8I.k;GY*kjT4@,'g\;lE8?A;6V?1gBTh@AX4iJF&_sYom6PGWN.Ml6Q+b*0ePhH"AqG-taRE)"TYc@X?,PqTSc%;%K!k2fNYo#H9(sZeWJSn=*OV<05j;W42k0oXgM%N$S&*RgN+1&(X/`'JtuLatU'/;JgYOcps1-88Oi,7!XfnffK4CG5EV_\;R`0i70aU=k5O>X+i6oB9S$<%GfE"P-V-Zuoa_JdMMD"&bP,l^dkLK$7TPH>fO'K/W]0t>X\WATF(hUe&g>6U>@-S,Zl@>Grdo0YMa/X3"l&1]`@S!$-:TP>*K:6H?J0T-)YP?7urUk0mce',EhXFeE^+]+%]2$+\X0M&D`$PlbUUr+TPNj-TVJfu,-]Jgu#Nn&s=P[Y*G-#,Lt.SAeP`>30$#_4?,5\k\6.^!BGZu&7J29iPWj_34(3C`)q[cP-5D;s/7?/@*(sFC/FIK_6P\1hOpd8gn\BcMu9<5+P?u3\r<.K&YXBg!6bfoPL$*a0>LN,S631mVeG.?/^^8I,6@6"s8aMb-7X=I-k!Kg?1!9ILkfrkn1PO"AS_@JS:BD`c8FZmYK\pug7pjqn"'e1Je+]oG6lt?l27YO/C5`OTAqAci_W[hW/Y+k5gb1V7nC$ii(m(^7fN[7Y9%2n6uDRmQNf,m=BGGabb+8\i2njAGu[@>$W&L,Y]b(WO[aG>8=+@qV#L5>i4YF`u(a&c1%D?S.7;'b6o<0/dg-QKmWFq?L,as>q==;4:;"V#cbDqe\B.[aW5mmp5_BbpU;XC$hUq5X#`_0(Vm@ngR?8sr)FnJfohOVOX"I@%1($@KOD_Sr@>PEGk$*,i_YiGUAof,D4(:Z>Hd7Neu!q5@6'r\Z;u!pbF0MMN&`Zgq2='e(1e>KW(=3Pal`f*LYWY@fSCBKLGga.^h=NZXlS//Ji5>%[U-DFYB5:7G>9Ie[NkleIhXHTl16X&1cSDZ%$:gubKq7W:N>)1Ha6>3htVJlo0+e;WQJ]=&kARt_i!3#4a#F0DbK?)FNX-lU(m-4"U0=@;2BO/YXpO5MBXb[`k:L33gV:3,A'?H:&j%(c;SM_a:9kZ.W.=2up7e41V/&2Z?-kbX6_$W3BN!f0iY[Y4_.6lirb*LFmnefVO:JLGDqZo%$K%T9!dk9'IN^-hXq8WqfIhogVa2h[^[@+4_RT,Z^D`:7O&X8$r#@(nifC%DK=:rMND'u]h3l7X,7i1A@]FJtet0A]f-<^]L_!#H7OP'4XKH#R0>RUMt-Oda:WPp6]sZBEI`[^:_B8bdDmR7dRcWM*6;PqAuBXA`[W93,NU/5m=#CGdCeXHo`h))\4q1e?279XNN>VOGbmbpdF2/Q-.'#bbW_5G3M+dNFY#nUI1Y,7rnL!*0Rr*!@r+k!Y;#&JZH#<00h;X[_$/g6l!hC2_bZjf]Cn"B_[pTR>fm(ZdRVooN$#.MWjG152G8#nAYoo6S(gkAW][&;<#E#lQKhTEts]aXml5m9l%t=r*J9d-))j=h8P#P-,ZV#OofNLi?%dK1q2MQ7Q&&XX\Z\.:oseS-YgAYb7WpLj'(bQ?n.u;lg]]@tWca-]LZEoE#8')%P`+B80oT0:ViK2`O?5[af2#>f7=K=HS[GF^>L]pto#kj`+_$l:U[&d2Z46oN@RmECNXB0[Yb\Z='!:+mT^_?bErn0U/2(0&+"l@Z1DeW'IKkKeH49UjYtm)9_.naVJ'C*E2Ql$YV_S"`)"V)=W5C(oj?EZh]Y6fFD!,7%noA2e'R%LH`ABe*)K$4UbRPd6Q%oi!N4*2QP6);+XBV[Z=2MZ`rn,!)8V/p"3V,+C]feK8!5(q.&('ZV4;R.-Eoqc#Re0L*M=(=)2Lin)(%$L%XGt*q/#1UX5do\WG!9;A0"@Ti_8rb9^qSjdk"Ug86$O$Y#'bA`fYf`KAM;tb%+#s\M`?%GV1(r-2'ZOo97kPVB-R_=8m1ncOHq`To/'*3:\dER0Tmf^`7Yi&9u!.c+(dj4I3I4<-!K^8j+"mId[W'ZNL3X4OcaF)-]irBpjG&o+X%]::[KnsK5MP\@O,E,D<$O@Q,6+2V80UgSfd,*G.b(g@(Ub:0?&:0?mX)`I=8`1!Kpte^RFRY^(4r#%k(uN9^/ETm?"4UhDuSg*5ll2B[`ab?Q"U<(C5'(b=6,/M8;'ZVJ&Y;$D9JggF@smq(piu4m_/QjL]BLlIH<2=n)pJ2>?^hE6e5?7udn5/7WD\Ccp[`lmZC;OGR1:&8<,]`ss,8_%!(E$gGu3L:G45!\SYs8,b0@R)$B+fW-4:&+cq6YKor?FX9I:U\a[hd$+\!61i2%$]\Okjt&BE\!:N>mj"j,R/iE1.0gXI3F\kW?dV)B?9SjfDK5oJYCuV7MPtq4bni4i=27rX^;V'S;X\a3iMg:iTU33N@-QlgL#d5Cp__5hC@2O]%i`IQ#fWTXXQrNUD^>;-&!&VG8r*u2X8H@]#7cc+@`.n"XhQ+OCF"9;C^p5+TrQK_F@WsM0jgJkqe4CLp>F*9p0JAfNB="7T;gd)8:CDIepKl+%r$;*epRt4]NfOb2C-F2TQ`+Nn?,(pd3"P#t0JEno[]!_4g!hbj&0cP%H2f!/r6)P6O&o-*S>=a="T]_"Wq$&+jjh6\=?9:e_Rr,"N;gPu+F$6s<@G1U@4+AGW@`Eq&=aNVgtL_Q`Yfnuejl72HO^^1hhKT;LkccZOu)7NdS',>B'PF@2QkeGG8j`kmL9a5CA*rk!Xo_>iBtNCi^h6P:V%<)61E]kDe.l^_oFNcO2OsHPaGNei6IB/9^Rs]LTJQH\IH(o#n>M0LG8H'OoN%nnQAk^"V]N#O)theflmg'9F]Y`>1eWNd7^H&Q/3N0#4p!^q;;JVQTi13iA[bTq"4>UgK0\$"Cl3`q>KBdb$F(bnZkf#qjG`RdX`?\;BMdUYVEPFA0=Bh59NZ?ZB%aPnHq;O*A7Vm@Dm4n\ZP_QTM;"6tZ(p:%@lH#lT":YTX#=[/?!R_O$lVqcR]3`-R0VqF%IlnlUb;ujh]lH:5dWcr0Ufuubp2fY'pM++&=0)IPBNjDmAUGEiY;8)*Z*m?bHTuA>(CptBXb=p.%)*LV!3"X[[pS%1-KHQ0ss=5UD5bWt)>0"YpqR6"_hJA'"5%'6#eGGB<,>cu4TFV`U9.\i6'.LQ6H&>kK4@o_ub#BikQ*VD3Hb49rFMPEKU7.:^SY5hDW^U]7H/,,V;WfT;jF9r(Q'#Y@24s(;dJA\)$%OUaK$:-u;(mM-2_U'SK.@CJsOqNk.Mrcf(Y"D7m,)ZFD#UCrE?V`;GaHCZnV5]b0#KbBu1XM:/U7%R9)ih9e*'>MB&M6E):)?"`GtQ\WRriJV^[bT"Ml,kO3ac9(O3$+kjPF!45lK/b@XVm:'"UY5,C2kh`USa5A+4Vq!\j;ASV`R&T&/VSHrE3FZ_7`Qa-EsOUPqn,RRkFf6RjPQGM:X.*!,^74`TX?qpHb.G21$;p_6Qs<]),G!c'E.$3e=*'sSD%F%Q1&n0/Z(F#',I$+N8,HI+QdPQ3UlQ=-n'Xu67^![-\\:DaB>$a^MmM1eaQ3<7VW14`RA&jdQ1qNSnc9N")!-N6.$WLqKQ'&oN6#"@tHH&f71Lgrnljq=;83AHQ09mD"[p@"U?Ojk`+LR.ANWdP!Sj$pB#&Kp=gU!D;/NgX)ERW/8^ET%lVA,CUpi*Hj]oZ,E:6SFJ+X!4l(F5$ZgM+$(!![hpM=Mmuls+8S4(($4g,SEXjP67!^o`i.2M=VHo-O/2^McIs;kuA[uWamFt#FCg0hpht!-%LVO$$huIoMpe.mW_@b;H4=,23lX2DDi[4qe-YA=t7Z*0;Z;&_46roNR)uRBNf=*JQ#:(j^d1mbZkZA$n$o"FoD(iV*@O*Pne*b7]W5$-mjn4%TqbkinL`?arbt>0#;Xn5s%P[6r?U$VUp)@6F"9K2VZGo29SV+A%V+g_[2TZ#^"eoat!,0d_GT%,)p&P-u3@Au@&D1Cp(>H&1=pN4W@@8h5La7R#T(n!T[2'opK!NfH5Hgorp%,?N@o+i%,]R9]W5tNU*Z(Xnj2)'8;BZ.Bg8s!CMZHWC1I`$=A:S!fd8cDE%!p`c/'KUM;+!#3qEpfF!9geo3$FpFl&:b3KPD.<5\5Y75oQGuYj?:M:/M=7$n1)VZUk*h$Ckkf\V@1[8kR5-;SYq6d+`TrJj=h'c'f@SkWBFiAL:kU$O'Ws]n&JdNOIJQo1BdHO(=Rh%I!Pd5,G4JJOO\TQM*D'iDaP,-hO8[R/[a\+BgUf"ErA8.m?mFP7QF0,Ufk-SR1A_'M'SaEp`!f!^E=Ucd$oVZH-5-]%L$ljbKaP=(\]Kpmb)q@'7k-%5]a6N%N(e6r?-0(FgH+0,4$2(m[r?f'%0T%[HtAgZ"tgPphrQ:i$m?WB.RFh7b%Eh1&E)l<*-Ko0`1*#K5Y=&(<3d7p\]3#h5\/;1!,`9;,7J%5M(Y)Z1/`iD"VCq_)[fcZ16WPSJr&-S.(aF2>\ONR7>Wl'_$:^M2]6/N&_Tm'?3WY^822R2.)QAqPADYA$AcSK_-li&^q=jG&f>?",i#F'iQUH,9.?b0-R?311Ps1`Q"SdrDS+Z&?gGg@4n-^u!<"H$"U!6:l=@U;1VhN-Z3mnc=HP\NT7#CJUN7b.(`8@#1;arID;Q9R>dP2P_Lnl_,(Bhnn[)bjLNlJ%)V&i3J%'a/j$:69V%U`9][W%n\i?\m:-inSa5@6V&[eY.-L)=@%A#)saF3A%U!0i`EGb-g6d7h[j+S*L+#MCPX_>3T1cBs%HH"7C=X9+q,Yp(=ucFTs1j#+9Mm^+Pe>A8q<"Vi`="AYk3>D@;QQo?i=!SRFjmQRNp#(j3rm_jT+G(`%>U,W5`I3GBBj9r4ljVM@\i9s,[C$?A19Y;H:s3<22#"`8sI4,Bh>-mknVkV.fJ?lFEdJOI+m0Ji-)bRQI4!jgNXc:[5!BLXPq,`JKfsH`gZW5]g*QTF:G[pGaKkDY#P<(eMk%8`pc^XL>l1[IV_&Q6/ioGgLFGcoT:_6>P?N9GkT\XkTja.j":7ok9=-toY=]nGZ_Tp?IX[!eds:6Th8)iTMRqfRHe28=ZFVE`#Kb`nRa--Ce+)'NC1i`nV.8'LX'\#.>khNF22[:1ZIH71]V$G?@Q"kW(I4Wm2A2C9#R/3ZL]KhUU,X!tYb_NH$BW3EQjEsa$R?E0@S&.HgU:IVO63ql#ds;jk2q_1/*XM1iIoX6GGQDGA5e?KknS:8IAW3@e.E4FWZSGA,r+#hpa;YF/OK?C?fe1WkGnu,n%NtiL&o6<=;*AO!mYSRG_cnXNq*"Rq(4hUjtC.+d3JA?)G-)t[&:gmI)Np)aEuZgVgD3-..S,%i5N`kH^?;452,0D1VX@]_oNoU$U,?B4::u[jr8/B.)b6Bi-qf\m0qR5cgKhX^e.,@3_jtVIEAmJTh"4*.J4:\j=7r('eq$I`p/rsbe1gcBHGaD0&O9Pn*#.YqKiX9_#.SJhr1B4f<*;_7Sc:$-P>CKG%)ng0T%*nkkZH983i+Vh1\74_sR.";r4,>]jJVd!+>$tbFG*/TfSd=O[c43O*57V^m"Kd8]G`3iRUi('a"Mt=2;>7=:i:Ma9_)C(m50A#@rZ)8`>=^l6B1EJODVj^qg,3(s50-AHd&\#a.J/At)JYY_n\-&K80U,=O%;-k2'@.Rf/V?=aOW7a*;QG:PCE^ss%PJ[S^kjN%]8N$Vs!6q#$2"(fAi&Al"QU/%`jnq;^N[S&gLLs3q$._5J=oMeo/F\>_KREsrigBK%mLoP+Y?,J.\N2@g@r"AhhdV-=?61"nTV$2D2!LW+j_JAm&Dt"9Zo2MF8:pd#;m>XdBPN'.K2%IO\j^/o^dL)&d/t>7P[S1@k"cR8p/m;7,E&\>I#t>9(TTlaX)ikNJJ@lBYYBp9-@7>%2)XAK'QKAe#RV+\Q5JGg1;178PMia0smEkR5\qn16%c:VOY8F-SH58Y?A%JfoXX6U\LW#!`]*.:b7ZJH)a'qT]Fi:"-1>;tE0AMtTN[l_)b]&V$CJW7'*NYp-+cET^,Tp]-036dD6L+&4DVB"COW[#XMFPc%,4]+.Q,GJ0@`)++km`'I[Nq3'(oO"A)#+bqt6tU`?a;D9RSWM[d',:!7R1OMsYM&V(t&#dQ__L9UjfYn]['!>liL!e>6MPd57j";&lM!0N4nec:FOB!MHk&6U,^2*d8aOT7jR!)nC`&>ca##VZGk2l!/G?3'l@!7Zr(<@#Pe=3.$s,,tKr!&Xp_&.+Sa^*iRPF&ICsJX?Z,pQ,qYCti\)VP^CPQ;lEHMM+kNg]UeK32)!mm.`3JEQV*C42a7f!RV@=+VY,M7R_J#YIb0=K4,%J;*<0prt!oQ&0s;1KB7WnMPKhGO])+,Rs8js2VGJ`&cNQfQhaq0AbE'bC&m^h6UHW#^?a#]$bX$HNfNNtVYL7R4E(iImUJI&,E?0]ia7'cAk[kYld>?m,#l*=_2?*!-iXOV0spP)K*2Fn$!So?u6_-4+oHa`Tu\[#*I,;UkB!7n]3b*`,).!q;CTBHKC9^i7ZOQB]BLiP?06-BnoN"JS5WR,mqhFRYJ1VTG6WVM,bBUpAVZb"Q2NKgVEXiY%s!`d.2+FZ]Ye(rI:Q]+FP=k!_-1)@CthFSWdHCJ&rcaL"/bj7q7;5KO7h"qh70JgY8I;?RU7%aaG$%t$2klV1Ru9A&X*1ciEl4.??;_0H`KMh&j'R^JGmH51*R>3C7uQjn9rQON_.Lf15'6+sVV+3d`bUX=?N+TG,ePa&B"V"8r*SIV;M,UZLjtT'RM[mlb!,)/#cZ,@f!PEa/0\#!8Sts2db6nbC*1C5qaW:G""NB?6]'0`7p1LpE6kSq+b`4IQsOZ0j.t.*TVs-3b\f.YcAlmb8#lR[WferidmG!WQY0J`5MFg\Kgk-=7:+ra&7hZA&oPj^h+0mehrulGn=OA*tMC-&hPF=asjQ+hk[=4E$qMS1i\G"nCg8$;<@@pu,5:^!SeoVVE*>^AT)`o=d$V]oRi6PuS]LXW0r4D(B"oTI?Oc=C0;slCP,+,N,3erF1r\\$[Hd<'"B^7WjbS5$gq#Te/?mp\;Jh#acYL*Ha^=#MbH?nftr(64g53[&fuF7?iX_R)LV/=d^W9U7&K\YoM@uD-F'Z7Uio:QlXMnnP>$kc^&"gno]s-AY<\LR15o`5BQ-7/7IKmUPE:5Iileg;RC:VFmSQF'-l#d&]GSIXBR@ee0^&mM12tZ(o7?*q6r&6@hORd]jW67*P89'-c.71n5[+(6O?=`BH0WP7>U5P@2\m3)m_\rADU,hpB+jm!tanEi,Bu#BRJ&EDFF6hb:WY't=H-STP0Y#49%2RtO%:%#fj`jOtCS@0$NW`E"mc:,fE(^MJ$5e^0auj+n@<.QKL9R[8*Z5_+prfYIUN?;d)IU^E#%JRRbDZ.4C.(j6bn2EJ6F?2:8-i,""+S>5E9FA@T'p"-s:4gGT*%bNX@fS@9,@1QJ6+=()3Lhi"6Y6YCb3(0H^@'hX0--djrk&EUKa-X[U-:PVr8IR8WDZo]=jbrYqa#E)2S<$*RjrY!$IiGf[!aRhlneb(p1_iE2eh6DHj]+X3$l*bf#V%G1^qAt*&U4?8UQCG,4Uh%%?pV-lmNi=o@EQg6-J3uZ]b'3>A$-I$j2q)Hf$Ia6=.CS&0C7NQ%e?ZJZ]t[Uu@XG#SDm/'?I)Dd*InUs$:QP4n]bc5Zg<_"D/+!,o@m/S<6sH.@VNIH;oq\a[nOtS#$^f0hmS8^8&jIRe]$$9RW#hbg%<5S71BQBefPk[5d^a,mI@<1IXb@E*g3CdQ4)!L^J#VUhR:R%m>g@GNicO^J)X5gMFS.XW[e69bTS:gWM.2oL9*!$j;I/#O3QHOGjo!&L7sN?G&/n!)%o]rFeP-_p=h8YIf?ik2!SP[Z\@idYq[$&ct?<1m"nJ7p[kU!_NZ$9j'h^(i5ET:i&`*6==>TV4.fi.*7Z@P\On=@"anqrT3M*BC41eL^*DQA3fX;J8dU]d8nAP]8Q.LoU!oJ&;E7l#\R0o-r<+$AG=`pIeqI8P'$RBe'QT4&J5*De3K_GQE*/8hUF:1]2hok3BH/hS2j^Aotr@nP6"bkY[:hQXC0YAEk.91$S7349Z4s;CZbGR-4s(?R>9PlL]R=!:ZfC2#oQduF#P_pNZaa$0PU(uiHLI-gMPCb^Wdbkdt2'rPn^+Vc9k"EHD`G0`2mgg%*W:er`gU7@Lu!U96YDM[S!3C6qC8a+KWtr8JJDcm&KjLXZ""A!>B4P5r?YJc*``jaF<9U"&KAOaXkU@;3IirP'PKkej-<7$R?<]@NY^*9XjnF=QeZ9UZ7Q,te[_(BesL1^k#3SF6kH=D"u&lNbP]8%C!;-Y4WTle72O8CI"Vus:RfsU\k*qL=:I]lP1s/mLmo![7_7kd9hTC?\lMuD-,3%JU%>cfl(aHJh>-jNP<1Le%M8:JLrXTcSC#JO<@hC\dI->eicM&L#0XIaILo<_IP1(!,=@"BfDUX&:e.%SfZi8#9[0;AkoCC3&\2]7oAZGhY/6b(u:hAe0:Nk(mRQ+m<5LBQS,]jq1[2/(6eC1RWs)S/FF43uq)-/]5:=`-`W_1Vr'l>3VlJBBn;O6+iR^KOWGI.qY6#&3@sQCUqs&8KNlqRNRD)h]:Z'F6p!!'@?"E;KR_X`IY%XPbV^DktN<&YSN0WUm)K`4H6LUSJ.oMSCVV55TggF4>C`nE*O-=dlX"=.L[/Zb3V7'*4Wg,@?W[Ym#.6kG#"1MTfP#tf+I,&HD)XX._ne:O&n)QAKU/b6&X=j[g282B5_7gJ7^V1UMgL6I?79)QCLK\;M>B``9:sC/:51/0HQEE-RBW@rM'8[$n&S34"We.=t=YVNrVRnOR>>?2g"u$0GB9A?rmHc;"%*)]cOSW<_d8XH>uY/a%,\DOTgKBe,LsDAnN$C?s0S-[+)iMSVd$KHss1Gfh-XJcN75]7rZdr3Qe=MUZ$cY_>EL]M)ku>XVnh\@cU#@%%^7ja6[j/bPT::2*L_iuAhg+CktC!sLekjmRC+P\P1pJ/mNe1P22Ob1td/&7QW=&W._;A8NHfj@BQD,)BGTV)l?^^@mPKp6E<'e1B_be:4h%3UDQO;T8CA4qRVks7ti6kpKAXGFt9k*h\FKdh3u2C;6iAZB6]0Nf&<j,%CYn+NV>+BZRu=NrPO,JL6>,']Tc/U0Y.\G.4TNY#K*m'm[J@FooL)q?IuO]\t.:T9_(P^4HJS5_,FSjj`qsF=^buFW&0sBA4oYOWbSg6r@@We1)Y1"#:Gh@Gc5F/KoGHj]qsVigqQ?&A"r'aKQotf2kVuV(q#3?:AF`*([[eS$cEX9Np10C0fESdM.W]p@Mg`eEh`T)=NEaE-_5&P_R:.qr.<'u^;>n!H:?<[l'7"AMBsSmc.<.`)g-=6L0%/7M>=WFWeQqEqk$$h_U!rW2Tpbd`Fm2?C5HSX2hkt,FW6FbN).DOjX9!kH3/?tpP#nEDN?Xq!]Sl0lVZA;#kXahq'PN;H?.k150as6kaJ)siNafET]MD,\P(aN@j:JMeRajrO\Xgi;+Xn2Ypg&TtZnW*-3HKi1"&@1(@T(lmE:'LhkZ):?)D8Yq>Ce_6'IG$G_-.['-9e]YH0YcU%)beQ:F:&P5Yiu9W>&P\Ye-V(9pm^(P!L8_V3l]5o(#j&rNd(mUCf)L]j-l.Gq-T+)R!)e!3MG1Z/%B`cC:aOm$_/_s:`"U8)@>#8`nXo7NaM@)HKd/U\q&--"d6c7W%,a)noPido5o>WLpo?A4j[PI)I>+GXbC'YX3Q6''Hj.id)52ct`\3:.@hrB4Y5g)g,Y4E0D['VfecQ#_$6)(_R;QAB$=['?G^cnIa4%LpGDLe]*TANK(jT%)[s<[?\\a:K5nP7iOpFEs7tQEE![$7*-/Wp*XIlAP!SI$3_S*8Q0(-=kjT^=Y^%PV:\!K"S``e9!jB?kc0B3_7OXlsRrk\onsa7oTM`"f$W\jFa]Xm/sBp+C]*pS$K?@J\:."AR),2Wmq7780JQh$ZIMM]WF4$L7G`T[)$r?c;po@geL:sbr"A4"IaZeS8X6A:,5>c#@*;YJ;ZSrY_k2BJOu0TNjeKg/Gh#dT)\)s\[;g-,X.&G>lqh90.^2ZDTeW,8=/':KM[mB&@?rIk8?NpspsLb44chQHiprU!EQ%`t[Ro<:\Db-tmf;_<"YHca4aLjN:\ZVZYB$mr5`\[U#OmAE_u^,gB77V859-e)'L5paj9DE@c8BS4C/X*+#1JI%erOR3nN[7;[BJ>'Ae2c?K?28!Xqri#'%pZk*24P8"K*DTG!`4`C(4Flgk,A`kcS]A%i`H._7o'hF35+mX%jRSPEu]>g9WR\j@I98,/RO&GrFhXmdr5:[SiC%G>t\e+4,6-)MB^b:cr:;1k+^$?o.idD=Le99QhuAd-@"jN=!+7PdVHTSeb/V.SJJd*TDbH*X0/9,OBR&@JY/q_tl3X/NA$oWoG6Y$$f\Fh-c"]@kJ%d1s#NM;ppX@g#2r$p^[XbH@$]k8]lt!o,P1e?536X5,_G?F$nN]kQ#QhBsG,H:U^sQ;'MRP(b@IAXo)H)M]Zk=iGp<'W$pL82l,7RlXbbC!8Fd\'>j@B:ZTi;IR:bQ+``/6=Hi*:E?4MY,p92DdR8.f&r>^4C9(u@FG\BT(6c>h03"\Fuul@a!L;#.?J@=$8E7&;1#h3`:OtmXn+M]ZPml041)FpP).MRE46;H;:[mD)!Je;n:F8=G:HK%5SA@B"I?_^Rh!;LF*LT$T5`fq!=]_pQqjmCOL"PUYr[+@EZ.c7*-et!/=_$F2hfr;V%=UN@EsOosf,^@lA%u"Z2kuVD*9h6VG-LcKi`r;[ZAMTZ$G:5.'S6*=.^75QfYGEXa2^qMk)iBLi?mD'q#;S6>KYn3cM3;$(;o-qA38qHn94r/gkfP0*84$/`Pe32"^#tOufaZLQ`ahdqR*(/E.S$$;L_hgl5gs2aU"&?p^J:B%RVr7u+G:oY"KQ_LDBOa10C4'B/7l^)MfteP]J/EnnTl25@@;\:`@I^6Ff7":<=Fg$#`9`GBjhp!i!i7jD0O#hYmU78PTh9\2Ib<8-C'P$qEh5CL$fn!gC0J)NK86U'%b-#]Bf$$6^`7U*GX0R`KQM,Jf/ETUdNF)!-8i0@@'r?PBn^d6q;,$^n^/L!^;FU(BdgP>s2/'Ul)@%L-D]/0e0`R@8Y['SVUB9+Kp*hhb%43S.?r?lNFX_C1>%diRo2gn+L8:MXB;:#-H7p=ZV=q=aJ:"*+@8C;,@2L`UpWJIJ]MdhLpT&l=/&f=GR>L>i1ecnZ"#1h!NPUg,2N!SaS64V6`*\ej_OcfYi6b[a-@0r%+!@)`Zeb-7%"7,ZS[V_U(p\:'crUB/au%J&8#($sf'T2g4ceMtO-h9iao2+XQVl+^Nr<4e_0J[g\hc=1)(berpIB)KOQ^\E/6obY@VVGjk*.hVq%UM#KU5'&q*YN'+V)_4$ZJ]>a<#7RdKktPV/0rS/G$lDOt[F974KGdY%3\!8'=r6E>!C[97X7)$_B#a%=qAac(CJh(s>8C1bjnrEH8b30,cl;jKTX(1)G]'`e'$V6lJDY$4%f3Tl@hrJUdbo@%c]l`l!UCXl?NHTbBeDCP!t)d9&ZKa7.Fb,kiDdbJ(e).\M^K0a8]V0_6/G5@M@P1'03.kMp2R"0NA\tCB)mksZ:lMg[@76je^jRW2eV%Sb],"%!:2cYKR>R3+fB>I@INt!5[IZ:RL.RoZ0_95<7Ak7q_,^i6G-_QbJLj#+9c+b#^dOAeQA(80$5J0"Y-AVe+ght!,Tki5@_esHKs@tKKY$K#7L3;K>tZ],@0D1(pOo2sCh82=TQSU[A;inl6CXlD!0Cu>HQAVe(-!6m&\9S7B!'g#!/uG9+P]l'9L;ma6k>;:SJiK\S3\ZjULVJ&:+K:J**=&%"GE3\Ok##S9/;q^'Kj3CH:bc^g0@*u/t``1X:$AJB.V%'i.uJ7lpIQ%9Q9FX9?8QF)@NW6&2#\K)d.5=1ap?4_B$SZL<^JY$SNh3K%8EX6!.?&BMN5Lj(s\E5cTo,'!C2a>NRXM@GD_@.dIsb$RJ!-^dfT]Adn\sRsjOR+[+&HF0dSsD_>GVK>]tkF.%so)\4o_*pj]2n#('6F,l:*Z'G!!mWqiQh.Ynk.K2Juig+l-$Ml+*>S"`Y`h_ipT*T_9cP9&-"!A![PMjT7B[CsCTQ4RRaemSQg.J<$f,$&N23"-U1pm*8NptYj'%r"n;2%CoX;J"RW$s1*#2umt#]D!TlUB8G!i23$@!3'0K!9t4^lo4^VAbA5F[J=C!Zp>S9rDH2*tL3f+K[\GMM@@R+)1mkB14WrjRK^)13r>@Wd#2-aJ#^)0V-?%g&dYCC:/cu_J3RTbuu@oUEc@R=:R5p54'oKpU?[U:TAATUC?TrZqM9R."VuCijkLBT/Ea`$T@CZd86+@p.i^gcO50B7r)/lNtDsd\qj4e$76NjNY$ha9e9P2UZ&$q8q>2mmqZ%mn%tVnFYO51qRQcA;P8KB-dTm0)`8V"`p0pRTTq.QuOlT7r8qWm;L$3dQ:*2.5@kL\X\c'pbE0&?ofl82419&:0DPo:lu)U25j>Xcc^le,BU_,FTf%&go(o(Un%atnlf?U"dmMCKZNeG?Gd);+k[F<=bG3u%@e*l]?mC1CusE)0H8UnBJINV88p)cdQj0:[Q6qFfeL_SaP/pUKC"IeB^"rgHT,juL*\VifaPaQNb:-Z;cJIj5VNKhAKuVP>jZmXRKU."_GEFrUCJVK!XM@E+G$RJM`H.6W0+eP@Tdmd`7-BbQ:g>XO?//jd=TG!pQ].ZgMR0AK-Ik_:1h-pGsnNE[8Y^[eA=3hgFEf%ZZbi,:N]G8nERpPLRb[>.!fF1(#>u1##tG\64$j/367mE)S!TC-?pg1p(!uc4$""111@9c$nRE`LVH=d#=G_8JjAUY)W\=^nmtTB]2XWX'#MplmcZd8FV&BO%9=i%_l.>=2D"uA&4:#si"raZ67r@RD3u`;pD8$F_K-Jd*E@5bK;?@FR>!4hV-R)/_`]#bd1YjruTN8dO'#+DhlGb#L1u0ac.OE)),oOK[We57;_6@%h)1p7nNSl=M_Q"6++W*R#UPPTd14#Q74_mi%#qO/#QXjN'$"b7"%H6#LGqaAinTRS1J-UjM]Uu8RK5Q9NW$j-qIPW\Km1/Xf;%Bu&HY4R`^(_0eOAF.%kOuiJ56uq6G7WqFp%?@;q*7D+Lf@o%^OIX@V]HR*8hF7amUS1;pamAaNZ5WiloI+5g2oTpck#*(7?M2L:j[oCf0KX78Rh?ND<+p4'A[Z`&a'1'cU?>&l>)a7OM3Gu%rq&54+i!2Yeg?-XTf!`kXJ)&]^DWrJ*5+SAK:ZE&clBRNl]5rR.hk>3s%j!M9<9tJPI(ZFo3:71@mG*+1IRfG>'JMrbnA.V#RC7A%_snYLl$jpE$dc(_QJY++=_FF!!_tc=qRVV#V6o]U8UUYkP:^cm1Fpl;O.g@o=F=:$XR\=ABBXj8ZF9mRpcVu=c.rP4/Q?3\PX\1$=q7pYp'Ii#`(8>8.-9^?rDuH6II?j=P:bt^fU\)p1%FQ`ga$HK?Nd%[&MmsarM373FoA;CQYt\/Idk/Je;+(p\4H-++9c6E..3dH0:dB&$Q/Ipq[H2d%='d>P5ChAr0#c.B*k9QR$.^S5TTC@urLQ')M\5DH%D(?JCI"3JoL0&[[p]f:nsl)$m<'eaZcVW3#M!Ub$CQ$NUZHc_cQsLEZC1+.8]fpM=!kXB%e\7GtH*+J:N(-u0*Q!Vk\0`l5#/nAu/iEMlYp(oa*M\db8KIUITn59K.eL]Ke6T8&\PMCU7__".g:fBr5G?m??;qB',Z:QFlbrW=DV/2+]ICe;!Kr$/=L8uB$S(6FXYoSB<"#`'sC'#_a/6I^7!1Fn]$58(mnVEfUG6$!G)8srZdj=Vc^VC6k!)u(0*a]b2'[pB;4c[4\EeK[\KAkCXM2NZoQIsjEDg0%PX4B6[Nsc16<+HC76m+`/KLGYrRf$J8NWom7U3%iuVV^`j1.]7p"D5!.JCF8Zq;K8@K'ieQ4G8:=a7nk7P+W-9[%02:F&FC6hD"I,3U7K&Wo^eJmV:qRXZB"!'*EADjDFpTMW"pKII`IREC6s!cq[R*ZPl'-='!j5,f*Gc$2WgE@sRqefIfHl&R?&b&br*Y'Ar(pCqmm&EELQ#R68,#@O4g.'9HgJI)SjQ"D>38i/DAA>iBAb%#0\NK%fM(6*-I\3[Bgiup%(X@0-emF(Q;NZIW`7hJ'`;B-ZtcNhW:-aL8;#:TY]c(f*K`u*>`dq)3ZUi2;rC(f'S;DX1S5jNJYWfpO,uadhL[1!LRLA078>?7V4^q@*N4PmR=QMM3$Nk6YEd+&XklHS"[e\P!BQ0,QmnpNVbC:!!ANcO9ILn<6VeS.b,cj(7T.]U>V)6S9E70_"sRdo5F,R2O/*X/8H]VCIc&G!jo!\)LP9"_VC&TZe+#t<_U![[J1L=]@#=8/qEk=6*?3qEQu[>`aDddZVOPUR6L3<Ol%Z?t:mTX$r^LjF09+$[BXYjLDGaJoHW(7OPm6*=)#]+3n[rJ)*gpf5po]Z:C)6i\<'fMl3)[&O:m4>GE8,eCM=B\3?;#0[s)pgP?b[a"qcAN%#Pk.7)0ut9gCbm6hI/VJ?&V(GgAJWd7:.[q`bR@]5Fbpi%qcD&`E%f`gq7Wj8^iScKuX".\"Bnrstf4qt1S-P2'CT!V%:W'Ct^8eP:gM?qLjUaVhF@Zo7S=GWG'UoKF9\uEWDA/(hRjX^uHZ4I94^_/A'6KY]=,79NA*)<%!HFF`W:@Gl!L3WLOq>8mR"qI4o$5`<1E#;!%K)>fk&^ggpN"jW0648>`RWr)OP.jFiKT-X',)_tZ[Rj:1"q4oW%-/f,n#kEF.4GNYai&3l3",hb[UR+hB#_TH>FKE>2/H;'a6eG_VV/+06mV4@I>qbrMWX,0"!YMA1'\7aL$d_(.ja]]S0MjRbZG\i_!N:I8A@#12RV\9iQ<9:qWO/,BRn9u$D`t=$&;&\*^)(]Iii.LAHIY#8)n"Xdrn@pB;>eF::Or7s(&642V(bJN#N!S=J;<^T%%fIGfO^)r<[g.q*K6Q_-+I`75/4!SX$-J[2ksXtpd>sh-tuA&L8V62N"pb;bR*aoIRTtdH5&%UG'oG#N\j=Z'mPnQ.646!LDB#g2JRE9@b!fF\J>TJ.tWj-"7Le^SK9AZAULc3X/8M/o?'rR&=E`T\YU9=6];R,B[SFH$D@.NFIlTZ3pmpQbT(0AJTc==7\ar>-@H\qD/CTkEKuR3&Hm+t`]A+2CO5'_hHFj^M_2KDhjKZ;d)(IgCFD`C6[Tbfe'\K5-a`,h5$*Og:lKuE3k3WDG:aja'brhVm%WDA71HUerd0@Km1!H90SJ)LmX@:m`1?K5Z\UFrZug>ubW\cKD\";c8CV>jdLAr$h@H1W;[9??["9mj[O0PWk7DaO/sP*<-[%'.VX!N)'`A_5'O*t(dLCZ,g]tBF<12W0LL]G/+gg9_-:0d=n^up.I\jngYiW`aV0GoIB!5ePa[>jSQ(D\.Il/X$q4UW7L-$4([VN%5C+ReP`Sl&sBhfBA^;miuqL5dnTdR4Kb]C?h1d7=KmP-_:npR\M,e,LN`J*Httr4>c#IfK=qqu=/)^[ci'<$Y>CT(gD;35l"SBUn]Il(,Bs-./R;O'NZlG2._%V8KS&gJ#!TmRZqHMe-F^Q;!B6NfPpkO8(k2@DjloVM/5PjY\QQd9sTo\]G8D8UlJ+jtkJ[_&[prD5.V_r26o+p\&Se09u,mF7sKmqD.)%5Z<^X$FPQOcpd,D,jQ8@7(AJ>1U"g2:omsrVZ=?`+3!Eo]'^)UiXGOp%6/p#+s>d.dk1BqV7AYY,ZfofKsU&[(sLb"CW6UcpCuemf!i]cs"UL@]R(^Ukekr6H!9+kt;X28XpKC\8f&Hhb$a.5J-FBbN(rt3pO#-HeQBoR@\NBYeeSXoM_2#?F4.Zf(;kfBP(/ikbWSJ5^p*I@lnc6-@sTMp!dC;8lJoE^V,>O_J;%\%PshS?)CnY`]=eT.b].3D,gDN"%F`/@,SuSuCgQlPKHnDm=(+;kaQB(e.4E&*UWm;&8p$8$_?Z*D(uU6O^A=9#ca)lCp[bj.1$P[gj5k(eVO5pF=B9cCi:Bh_+>F`#^<3he:6O,$+>nNdQ%"KE#u+XdPJW?dHRkFRYpI:<5L[/?%3-.g!;5k(C6#Z(?E3Gs=iMRbC`VIdC_pHfF]G'?a5pCsoB\Mfh!,cM"N^?XpTo+^S^hj2Lpm\RBMY!#++1*1iZ?(;`?3Q;FaUCW*CIdH4AeG]E1C#U1X!4J+U"2jeCF%(WZ3C&+mMs];@!;/QdBCC#\OtL?g#pd3J0(eBYg7F$KGHgL$q)QPF$NZq$=+A$!\j(g\#"pnDF#$Ul>i7)&E,)lq@r!p#c@-hOB>FP#B1:O^_5Qj;cP%"5[3=.E:8JRkDR@\p?P:ooC)!e*J6b#.ms3B(4[`gX6Vg!r=MJ\A4@i#_C.iB!t\!g5g@7QQn/r55[b@hJ4+PEV*AY3B_)9H!=a,^%g!;n('$ZN1dhj=!5Qal62;XpW<0a0N3EEd^#rSpAS3G7gchD3s3g`SXA;NO9DPXe8-6kdh#d4a(BmAR?+L+Z_uhsWPPruqW=ST&,Q1p*l*2RBr*LS;HXdoR0D^,VDcEpB[_5':&M0r#9[Yeul'*<8q/Z!ci=GnD5*M:-5[RW*L+0D<";&t-$JUrH!OC'nTLeSfs34E&'f=W;b,$$)4/;DSY]V`u9V^I\Oq\t^@@Yg?.0s+ui*+hMNpM0c_I6Sf,ms2EcU:)"rS*8Sbf #<== From c33568c079db5ef3ddb98fd8631e6f4622ed2cec Mon Sep 17 00:00:00 2001 From: "Gustavo J. A. M. Carneiro" Date: Wed, 16 Jul 2008 16:06:50 +0100 Subject: [PATCH 175/495] New API considering comments from Craig: NetDevice->Node uses two callbacks; Node->ProtocolHandlers uses a single API with a promiscuous flag. --- bindings/python/callbacks_list.py | 1 + bindings/python/ns3_module_bridge.py | 8 ++- bindings/python/ns3_module_core.py | 56 ++++++++++++++++ bindings/python/ns3_module_csma.py | 8 ++- bindings/python/ns3_module_node.py | 60 ++++++++--------- bindings/python/ns3_module_point_to_point.py | 4 +- bindings/python/ns3_module_wifi.py | 4 +- src/devices/bridge/bridge-net-device.cc | 26 +++++-- src/devices/bridge/bridge-net-device.h | 3 + src/devices/csma/csma-net-device.cc | 28 +++++++- src/devices/csma/csma-net-device.h | 8 +++ .../point-to-point-net-device.cc | 2 +- src/devices/wifi/wifi-net-device.cc | 4 +- src/node/net-device.cc | 15 +++++ src/node/net-device.h | 36 +++++++++- src/node/node.cc | 67 +++++++++++++++++-- src/node/node.h | 55 +++++++-------- src/node/simple-net-device.cc | 2 +- 18 files changed, 299 insertions(+), 88 deletions(-) diff --git a/bindings/python/callbacks_list.py b/bindings/python/callbacks_list.py index 2ea5db414..5dbffdc0b 100644 --- a/bindings/python/callbacks_list.py +++ b/bindings/python/callbacks_list.py @@ -6,6 +6,7 @@ callback_classes = [ ['bool', 'ns3::Ptr', 'ns3::Address const&', 'ns3::empty', 'ns3::empty', 'ns3::empty', 'ns3::empty'], ['void', 'ns3::Ptr', 'ns3::Mac48Address const&', 'ns3::empty', 'ns3::empty', 'ns3::empty', 'ns3::empty'], ['bool', 'ns3::Ptr', 'ns3::Ptr', 'unsigned short', 'ns3::Address const&', 'ns3::Address const&', 'ns3::NetDevice::PacketType'], + ['bool', 'ns3::Ptr', 'ns3::Ptr', 'unsigned short', 'ns3::Address const&', 'ns3::empty', 'ns3::empty'], ['void', 'ns3::Ptr', 'ns3::Ptr', 'unsigned short', 'ns3::Address const&', 'ns3::Address const&', 'ns3::NetDevice::PacketType'], ['void', 'ns3::Ptr', 'double', 'ns3::empty', 'ns3::empty', 'ns3::empty', 'ns3::empty'], ['void', 'ns3::Ptr', 'double', 'ns3::WifiMode', 'ns3::WifiPreamble', 'ns3::empty', 'ns3::empty'], diff --git a/bindings/python/ns3_module_bridge.py b/bindings/python/ns3_module_bridge.py index b15f97df0..72822a316 100644 --- a/bindings/python/ns3_module_bridge.py +++ b/bindings/python/ns3_module_bridge.py @@ -102,8 +102,12 @@ def register_Ns3BridgeNetDevice_methods(root_module, cls): cls.add_method('SetNode', 'void', [param('ns3::Ptr< ns3::Node >', 'node')], is_virtual=True) ## bridge-net-device.h: bool ns3::BridgeNetDevice::NeedsArp() const [member function] cls.add_method('NeedsArp', 'bool', [], is_const=True, is_virtual=True) - ## bridge-net-device.h: void ns3::BridgeNetDevice::SetReceiveCallback(ns3::Callback, ns3::Ptr, unsigned short, ns3::Address const&, ns3::Address const&, ns3::NetDevice::PacketType> cb) [member function] - cls.add_method('SetReceiveCallback', 'void', [param('ns3::Callback< bool, ns3::Ptr< ns3::NetDevice >, ns3::Ptr< ns3::Packet >, unsigned short, ns3::Address const&, ns3::Address const&, ns3::NetDevice::PacketType >', 'cb')], is_virtual=True) + ## bridge-net-device.h: void ns3::BridgeNetDevice::SetReceiveCallback(ns3::Callback, ns3::Ptr, unsigned short, ns3::Address const&, ns3::empty, ns3::empty> cb) [member function] + cls.add_method('SetReceiveCallback', 'void', [param('ns3::Callback< bool, ns3::Ptr< ns3::NetDevice >, ns3::Ptr< ns3::Packet >, unsigned short, ns3::Address const&, ns3::empty, ns3::empty >', 'cb')], is_virtual=True) + ## bridge-net-device.h: void ns3::BridgeNetDevice::SetPromiscReceiveCallback(ns3::Callback, ns3::Ptr, unsigned short, ns3::Address const&, ns3::Address const&, ns3::NetDevice::PacketType> cb) [member function] + cls.add_method('SetPromiscReceiveCallback', 'void', [param('ns3::Callback< bool, ns3::Ptr< ns3::NetDevice >, ns3::Ptr< ns3::Packet >, unsigned short, ns3::Address const&, ns3::Address const&, ns3::NetDevice::PacketType >', 'cb')], is_virtual=True) + ## bridge-net-device.h: bool ns3::BridgeNetDevice::SupportsPromiscuous() const [member function] + cls.add_method('SupportsPromiscuous', 'bool', [], is_const=True, is_virtual=True) ## bridge-net-device.h: void ns3::BridgeNetDevice::DoDispose() [member function] cls.add_method('DoDispose', 'void', [], visibility='protected', is_virtual=True) ## bridge-net-device.h: void ns3::BridgeNetDevice::ReceiveFromDevice(ns3::Ptr device, ns3::Ptr packet, uint16_t protocol, ns3::Address const & source, ns3::Address const & destination, ns3::NetDevice::PacketType packetType) [member function] diff --git a/bindings/python/ns3_module_core.py b/bindings/python/ns3_module_core.py index 0ad9704e9..a9a3b35d9 100644 --- a/bindings/python/ns3_module_core.py +++ b/bindings/python/ns3_module_core.py @@ -21,12 +21,16 @@ def register_types(module): module.add_class('SystemWallClockMs') ## callback.h: ns3::CallbackImplBase [class] module.add_class('CallbackImplBase', incref_method='Ref', allow_subclassing=True, decref_method='Unref', peekref_method='GetReferenceCount') + ## system-mutex.h: ns3::CriticalSection [class] + module.add_class('CriticalSection') ## trace-source-accessor.h: ns3::TraceSourceAccessor [class] module.add_class('TraceSourceAccessor', allow_subclassing=True) ## attribute.h: ns3::AttributeChecker [class] module.add_class('AttributeChecker', incref_method='Ref', allow_subclassing=False, automatic_type_narrowing=True, decref_method='Unref', parent=root_module['ns3::RefCountBase']) ## random-variable.h: ns3::RandomVariableChecker [class] module.add_class('RandomVariableChecker', parent=root_module['ns3::AttributeChecker']) + ## system-mutex.h: ns3::SystemMutex [class] + module.add_class('SystemMutex') ## random-variable.h: ns3::NormalVariable [class] module.add_class('NormalVariable', parent=root_module['ns3::RandomVariable']) ## object-factory.h: ns3::ObjectFactory [class] @@ -37,6 +41,8 @@ def register_types(module): module.add_class('ParetoVariable', parent=root_module['ns3::RandomVariable']) ## random-variable.h: ns3::ConstantVariable [class] module.add_class('ConstantVariable', parent=root_module['ns3::RandomVariable']) + ## system-thread.h: ns3::SystemThread [class] + module.add_class('SystemThread') ## random-variable.h: ns3::EmpiricalVariable [class] module.add_class('EmpiricalVariable', parent=root_module['ns3::RandomVariable']) ## enum.h: ns3::EnumChecker [class] @@ -121,6 +127,8 @@ def register_types(module): module.add_class('Object', incref_method='Ref', automatic_type_narrowing=True, decref_method='Unref', parent=root_module['ns3::ObjectBase'], peekref_method='GetReferenceCount') ## object.h: ns3::Object::AggregateIterator [class] module.add_class('AggregateIterator', outer_class=root_module['ns3::Object']) + ## system-condition.h: ns3::SystemCondition [class] + module.add_class('SystemCondition') ## random-variable.h: ns3::SequentialVariable [class] module.add_class('SequentialVariable', parent=root_module['ns3::RandomVariable']) ## object-vector.h: ns3::ObjectVectorChecker [class] @@ -219,14 +227,17 @@ def register_methods(root_module): register_Ns3TypeIdAttributeInfo_methods(root_module, root_module['ns3::TypeId::AttributeInfo']) register_Ns3SystemWallClockMs_methods(root_module, root_module['ns3::SystemWallClockMs']) register_Ns3CallbackImplBase_methods(root_module, root_module['ns3::CallbackImplBase']) + register_Ns3CriticalSection_methods(root_module, root_module['ns3::CriticalSection']) register_Ns3TraceSourceAccessor_methods(root_module, root_module['ns3::TraceSourceAccessor']) register_Ns3AttributeChecker_methods(root_module, root_module['ns3::AttributeChecker']) register_Ns3RandomVariableChecker_methods(root_module, root_module['ns3::RandomVariableChecker']) + register_Ns3SystemMutex_methods(root_module, root_module['ns3::SystemMutex']) register_Ns3NormalVariable_methods(root_module, root_module['ns3::NormalVariable']) register_Ns3ObjectFactory_methods(root_module, root_module['ns3::ObjectFactory']) register_Ns3AttributeAccessor_methods(root_module, root_module['ns3::AttributeAccessor']) register_Ns3ParetoVariable_methods(root_module, root_module['ns3::ParetoVariable']) register_Ns3ConstantVariable_methods(root_module, root_module['ns3::ConstantVariable']) + register_Ns3SystemThread_methods(root_module, root_module['ns3::SystemThread']) register_Ns3EmpiricalVariable_methods(root_module, root_module['ns3::EmpiricalVariable']) register_Ns3EnumChecker_methods(root_module, root_module['ns3::EnumChecker']) register_Ns3Empty_methods(root_module, root_module['ns3::empty']) @@ -262,6 +273,7 @@ def register_methods(root_module): register_Ns3UniformVariable_methods(root_module, root_module['ns3::UniformVariable']) register_Ns3Object_methods(root_module, root_module['ns3::Object']) register_Ns3ObjectAggregateIterator_methods(root_module, root_module['ns3::Object::AggregateIterator']) + register_Ns3SystemCondition_methods(root_module, root_module['ns3::SystemCondition']) register_Ns3SequentialVariable_methods(root_module, root_module['ns3::SequentialVariable']) register_Ns3ObjectVectorChecker_methods(root_module, root_module['ns3::ObjectVectorChecker']) register_Ns3StringChecker_methods(root_module, root_module['ns3::StringChecker']) @@ -449,6 +461,11 @@ def register_Ns3CallbackImplBase_methods(root_module, cls): cls.add_method('IsEqual', 'bool', [param('ns3::Ptr< ns3::CallbackImplBase const >', 'other')], is_pure_virtual=True, is_const=True, is_virtual=True) return +def register_Ns3CriticalSection_methods(root_module, cls): + ## system-mutex.h: ns3::CriticalSection::CriticalSection(ns3::SystemMutex & mutex) [constructor] + cls.add_constructor([param('ns3::SystemMutex&', 'mutex')], visibility='public') + return + def register_Ns3TraceSourceAccessor_methods(root_module, cls): ## trace-source-accessor.h: ns3::TraceSourceAccessor::TraceSourceAccessor() [constructor] cls.add_constructor([], visibility='public') @@ -487,6 +504,15 @@ def register_Ns3RandomVariableChecker_methods(root_module, cls): cls.add_constructor([]) return +def register_Ns3SystemMutex_methods(root_module, cls): + ## system-mutex.h: ns3::SystemMutex::SystemMutex() [constructor] + cls.add_constructor([], visibility='public') + ## system-mutex.h: void ns3::SystemMutex::Lock() [member function] + cls.add_method('Lock', 'void', []) + ## system-mutex.h: void ns3::SystemMutex::Unlock() [member function] + cls.add_method('Unlock', 'void', []) + return + def register_Ns3NormalVariable_methods(root_module, cls): ## random-variable.h: ns3::NormalVariable::NormalVariable() [constructor] cls.add_constructor([], visibility='public') @@ -555,6 +581,19 @@ def register_Ns3ConstantVariable_methods(root_module, cls): cls.add_method('SetConstant', 'void', [param('double', 'c')]) return +def register_Ns3SystemThread_methods(root_module, cls): + ## system-thread.h: ns3::SystemThread::SystemThread(ns3::Callback callback) [constructor] + cls.add_constructor([param('ns3::Callback< void, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty >', 'callback')], visibility='public') + ## system-thread.h: void ns3::SystemThread::Ref() const [member function] + cls.add_method('Ref', 'void', [], is_const=True) + ## system-thread.h: void ns3::SystemThread::Unref() const [member function] + cls.add_method('Unref', 'void', [], is_const=True) + ## system-thread.h: void ns3::SystemThread::Start() [member function] + cls.add_method('Start', 'void', []) + ## system-thread.h: void ns3::SystemThread::Join() [member function] + cls.add_method('Join', 'void', []) + return + def register_Ns3EmpiricalVariable_methods(root_module, cls): ## random-variable.h: ns3::EmpiricalVariable::EmpiricalVariable() [constructor] cls.add_constructor([], visibility='public') @@ -944,6 +983,23 @@ def register_Ns3ObjectAggregateIterator_methods(root_module, cls): cls.add_method('Next', 'ns3::Ptr< ns3::Object const >', []) return +def register_Ns3SystemCondition_methods(root_module, cls): + ## system-condition.h: ns3::SystemCondition::SystemCondition() [constructor] + cls.add_constructor([], visibility='public') + ## system-condition.h: void ns3::SystemCondition::SetCondition(bool condition) [member function] + cls.add_method('SetCondition', 'void', [param('bool', 'condition')]) + ## system-condition.h: bool ns3::SystemCondition::GetCondition() [member function] + cls.add_method('GetCondition', 'bool', []) + ## system-condition.h: void ns3::SystemCondition::Signal() [member function] + cls.add_method('Signal', 'void', []) + ## system-condition.h: void ns3::SystemCondition::Broadcast() [member function] + cls.add_method('Broadcast', 'void', []) + ## system-condition.h: void ns3::SystemCondition::Wait() [member function] + cls.add_method('Wait', 'void', []) + ## system-condition.h: bool ns3::SystemCondition::TimedWait(uint64_t ns) [member function] + cls.add_method('TimedWait', 'bool', [param('uint64_t', 'ns')]) + return + def register_Ns3SequentialVariable_methods(root_module, cls): ## random-variable.h: ns3::SequentialVariable::SequentialVariable(double f, double l, double i=1, uint32_t c=1) [constructor] cls.add_constructor([param('double', 'f'), param('double', 'l'), param('double', 'i', default_value='1'), param('uint32_t', 'c', default_value='1')], visibility='public') diff --git a/bindings/python/ns3_module_csma.py b/bindings/python/ns3_module_csma.py index aa310a6b4..a8a00d525 100644 --- a/bindings/python/ns3_module_csma.py +++ b/bindings/python/ns3_module_csma.py @@ -213,8 +213,12 @@ def register_Ns3CsmaNetDevice_methods(root_module, cls): cls.add_method('SetNode', 'void', [param('ns3::Ptr< ns3::Node >', 'node')], is_virtual=True) ## csma-net-device.h: bool ns3::CsmaNetDevice::NeedsArp() const [member function] cls.add_method('NeedsArp', 'bool', [], is_const=True, is_virtual=True) - ## csma-net-device.h: void ns3::CsmaNetDevice::SetReceiveCallback(ns3::Callback, ns3::Ptr, unsigned short, ns3::Address const&, ns3::Address const&, ns3::NetDevice::PacketType> cb) [member function] - cls.add_method('SetReceiveCallback', 'void', [param('ns3::Callback< bool, ns3::Ptr< ns3::NetDevice >, ns3::Ptr< ns3::Packet >, unsigned short, ns3::Address const&, ns3::Address const&, ns3::NetDevice::PacketType >', 'cb')], is_virtual=True) + ## csma-net-device.h: void ns3::CsmaNetDevice::SetReceiveCallback(ns3::Callback, ns3::Ptr, unsigned short, ns3::Address const&, ns3::empty, ns3::empty> cb) [member function] + cls.add_method('SetReceiveCallback', 'void', [param('ns3::Callback< bool, ns3::Ptr< ns3::NetDevice >, ns3::Ptr< ns3::Packet >, unsigned short, ns3::Address const&, ns3::empty, ns3::empty >', 'cb')], is_virtual=True) + ## csma-net-device.h: void ns3::CsmaNetDevice::SetPromiscReceiveCallback(ns3::Callback, ns3::Ptr, unsigned short, ns3::Address const&, ns3::Address const&, ns3::NetDevice::PacketType> cb) [member function] + cls.add_method('SetPromiscReceiveCallback', 'void', [param('ns3::Callback< bool, ns3::Ptr< ns3::NetDevice >, ns3::Ptr< ns3::Packet >, unsigned short, ns3::Address const&, ns3::Address const&, ns3::NetDevice::PacketType >', 'cb')], is_virtual=True) + ## csma-net-device.h: bool ns3::CsmaNetDevice::SupportsPromiscuous() const [member function] + cls.add_method('SupportsPromiscuous', 'bool', [], is_const=True, is_virtual=True) ## csma-net-device.h: void ns3::CsmaNetDevice::DoDispose() [member function] cls.add_method('DoDispose', 'void', [], visibility='protected', is_virtual=True) ## csma-net-device.h: ns3::Ptr ns3::CsmaNetDevice::GetQueue() const [member function] diff --git a/bindings/python/ns3_module_node.py b/bindings/python/ns3_module_node.py index c3d161e8f..67f3e6055 100644 --- a/bindings/python/ns3_module_node.py +++ b/bindings/python/ns3_module_node.py @@ -77,10 +77,10 @@ def register_types(module): module.add_class('AddressValue', parent=root_module['ns3::AttributeValue']) ## node.h: ns3::Node [class] module.add_class('Node', parent=root_module['ns3::Object']) - ## tcp-socket.h: ns3::TcpSocket [class] - module.add_class('TcpSocket', parent=root_module['ns3::Socket']) ## channel.h: ns3::Channel [class] module.add_class('Channel', parent=root_module['ns3::Object']) + ## tcp-socket.h: ns3::TcpSocket [class] + module.add_class('TcpSocket', parent=root_module['ns3::Socket']) ## ethernet-header.h: ns3::EthernetHeader [class] module.add_class('EthernetHeader', parent=root_module['ns3::Header']) ## socket.h: ns3::SocketIpTtlTag [class] @@ -175,8 +175,8 @@ def register_methods(root_module): register_Ns3NetDevice_methods(root_module, root_module['ns3::NetDevice']) register_Ns3AddressValue_methods(root_module, root_module['ns3::AddressValue']) register_Ns3Node_methods(root_module, root_module['ns3::Node']) - register_Ns3TcpSocket_methods(root_module, root_module['ns3::TcpSocket']) register_Ns3Channel_methods(root_module, root_module['ns3::Channel']) + register_Ns3TcpSocket_methods(root_module, root_module['ns3::TcpSocket']) register_Ns3EthernetHeader_methods(root_module, root_module['ns3::EthernetHeader']) register_Ns3SocketIpTtlTag_methods(root_module, root_module['ns3::SocketIpTtlTag']) register_Ns3Ipv4_methods(root_module, root_module['ns3::Ipv4']) @@ -861,8 +861,12 @@ def register_Ns3NetDevice_methods(root_module, cls): cls.add_method('SetNode', 'void', [param('ns3::Ptr< ns3::Node >', 'node')], is_pure_virtual=True, is_virtual=True) ## net-device.h: bool ns3::NetDevice::NeedsArp() const [member function] cls.add_method('NeedsArp', 'bool', [], is_pure_virtual=True, is_const=True, is_virtual=True) - ## net-device.h: void ns3::NetDevice::SetReceiveCallback(ns3::Callback, ns3::Ptr, unsigned short, ns3::Address const&, ns3::Address const&, ns3::NetDevice::PacketType> cb) [member function] - cls.add_method('SetReceiveCallback', 'void', [param('ns3::Callback< bool, ns3::Ptr< ns3::NetDevice >, ns3::Ptr< ns3::Packet >, unsigned short, ns3::Address const&, ns3::Address const&, ns3::NetDevice::PacketType >', 'cb')], is_pure_virtual=True, is_virtual=True) + ## net-device.h: void ns3::NetDevice::SetReceiveCallback(ns3::Callback, ns3::Ptr, unsigned short, ns3::Address const&, ns3::empty, ns3::empty> cb) [member function] + cls.add_method('SetReceiveCallback', 'void', [param('ns3::Callback< bool, ns3::Ptr< ns3::NetDevice >, ns3::Ptr< ns3::Packet >, unsigned short, ns3::Address const&, ns3::empty, ns3::empty >', 'cb')], is_pure_virtual=True, is_virtual=True) + ## net-device.h: void ns3::NetDevice::SetPromiscReceiveCallback(ns3::Callback, ns3::Ptr, unsigned short, ns3::Address const&, ns3::Address const&, ns3::NetDevice::PacketType> cb) [member function] + cls.add_method('SetPromiscReceiveCallback', 'void', [param('ns3::Callback< bool, ns3::Ptr< ns3::NetDevice >, ns3::Ptr< ns3::Packet >, unsigned short, ns3::Address const&, ns3::Address const&, ns3::NetDevice::PacketType >', 'cb')], is_virtual=True) + ## net-device.h: bool ns3::NetDevice::SupportsPromiscuous() const [member function] + cls.add_method('SupportsPromiscuous', 'bool', [], is_const=True, is_virtual=True) cls.add_constructor([]) return @@ -908,20 +912,33 @@ def register_Ns3Node_methods(root_module, cls): cls.add_method('GetFirstApplication', 'ns3::Ptr< ns3::Application >', [param('ns3::TypeId', 'tid')]) ## node.h: uint32_t ns3::Node::GetNApplications() const [member function] cls.add_method('GetNApplications', 'uint32_t', [], is_const=True) - ## node.h: void ns3::Node::RegisterProtocolHandler(ns3::Callback, ns3::Ptr, unsigned short, ns3::Address const&, ns3::Address const&, ns3::NetDevice::PacketType> handler, uint16_t protocolType, ns3::Ptr device) [member function] - cls.add_method('RegisterProtocolHandler', 'void', [param('ns3::Callback< void, ns3::Ptr< ns3::NetDevice >, ns3::Ptr< ns3::Packet >, unsigned short, ns3::Address const&, ns3::Address const&, ns3::NetDevice::PacketType >', 'handler'), param('uint16_t', 'protocolType'), param('ns3::Ptr< ns3::NetDevice >', 'device')]) + ## node.h: void ns3::Node::RegisterProtocolHandler(ns3::Callback, ns3::Ptr, unsigned short, ns3::Address const&, ns3::Address const&, ns3::NetDevice::PacketType> handler, uint16_t protocolType, ns3::Ptr device, bool promiscuous=false) [member function] + cls.add_method('RegisterProtocolHandler', 'void', [param('ns3::Callback< void, ns3::Ptr< ns3::NetDevice >, ns3::Ptr< ns3::Packet >, unsigned short, ns3::Address const&, ns3::Address const&, ns3::NetDevice::PacketType >', 'handler'), param('uint16_t', 'protocolType'), param('ns3::Ptr< ns3::NetDevice >', 'device'), param('bool', 'promiscuous', default_value='false')]) ## node.h: void ns3::Node::UnregisterProtocolHandler(ns3::Callback, ns3::Ptr, unsigned short, ns3::Address const&, ns3::Address const&, ns3::NetDevice::PacketType> handler) [member function] cls.add_method('UnregisterProtocolHandler', 'void', [param('ns3::Callback< void, ns3::Ptr< ns3::NetDevice >, ns3::Ptr< ns3::Packet >, unsigned short, ns3::Address const&, ns3::Address const&, ns3::NetDevice::PacketType >', 'handler')]) - ## node.h: void ns3::Node::RegisterPromiscuousProtocolHandler(ns3::Callback,ns3::Ptr,short unsigned int,const ns3::Address&,const ns3::Address&,bool> handler, uint16_t protocolType, ns3::Ptr device) [member function] - cls.add_method('RegisterPromiscuousProtocolHandler', 'void', [param('ns3::Callback< void, ns3::Ptr< ns3::NetDevice >, ns3::Ptr< ns3::Packet >, short unsigned int, const ns3::Address&, const ns3::Address&, bool >', 'handler'), param('uint16_t', 'protocolType'), param('ns3::Ptr< ns3::NetDevice >', 'device')]) - ## node.h: void ns3::Node::UnregisterPromiscuousProtocolHandler(ns3::Callback,ns3::Ptr,short unsigned int,const ns3::Address&,const ns3::Address&,bool> handler) [member function] - cls.add_method('UnregisterPromiscuousProtocolHandler', 'void', [param('ns3::Callback< void, ns3::Ptr< ns3::NetDevice >, ns3::Ptr< ns3::Packet >, short unsigned int, const ns3::Address&, const ns3::Address&, bool >', 'handler')]) ## node.h: void ns3::Node::DoDispose() [member function] cls.add_method('DoDispose', 'void', [], visibility='protected', is_virtual=True) ## node.h: void ns3::Node::NotifyDeviceAdded(ns3::Ptr device) [member function] cls.add_method('NotifyDeviceAdded', 'void', [param('ns3::Ptr< ns3::NetDevice >', 'device')], visibility='private', is_virtual=True) return +def register_Ns3Channel_methods(root_module, cls): + ## channel.h: static ns3::TypeId ns3::Channel::GetTypeId() [member function] + cls.add_method('GetTypeId', 'ns3::TypeId', [], is_static=True) + ## channel.h: ns3::Channel::Channel() [constructor] + cls.add_constructor([], visibility='public') + ## channel.h: ns3::Channel::Channel(std::string name) [constructor] + cls.add_constructor([param('std::string', 'name')], visibility='public') + ## channel.h: void ns3::Channel::SetName(std::string arg0) [member function] + cls.add_method('SetName', 'void', [param('std::string', 'arg0')]) + ## channel.h: std::string ns3::Channel::GetName() [member function] + cls.add_method('GetName', 'std::string', []) + ## channel.h: uint32_t ns3::Channel::GetNDevices() const [member function] + cls.add_method('GetNDevices', 'uint32_t', [], is_pure_virtual=True, is_const=True, is_virtual=True) + ## channel.h: ns3::Ptr ns3::Channel::GetDevice(uint32_t i) const [member function] + cls.add_method('GetDevice', 'ns3::Ptr< ns3::NetDevice >', [param('uint32_t', 'i')], is_pure_virtual=True, is_const=True, is_virtual=True) + return + def register_Ns3TcpSocket_methods(root_module, cls): ## tcp-socket.h: static ns3::TypeId ns3::TcpSocket::GetTypeId() [member function] cls.add_method('GetTypeId', 'ns3::TypeId', [], is_static=True) @@ -969,23 +986,6 @@ def register_Ns3TcpSocket_methods(root_module, cls): cls.add_method('GetDelAckMaxCount', 'uint32_t', [], is_pure_virtual=True, is_const=True, visibility='private', is_virtual=True) return -def register_Ns3Channel_methods(root_module, cls): - ## channel.h: static ns3::TypeId ns3::Channel::GetTypeId() [member function] - cls.add_method('GetTypeId', 'ns3::TypeId', [], is_static=True) - ## channel.h: ns3::Channel::Channel() [constructor] - cls.add_constructor([], visibility='public') - ## channel.h: ns3::Channel::Channel(std::string name) [constructor] - cls.add_constructor([param('std::string', 'name')], visibility='public') - ## channel.h: void ns3::Channel::SetName(std::string arg0) [member function] - cls.add_method('SetName', 'void', [param('std::string', 'arg0')]) - ## channel.h: std::string ns3::Channel::GetName() [member function] - cls.add_method('GetName', 'std::string', []) - ## channel.h: uint32_t ns3::Channel::GetNDevices() const [member function] - cls.add_method('GetNDevices', 'uint32_t', [], is_pure_virtual=True, is_const=True, is_virtual=True) - ## channel.h: ns3::Ptr ns3::Channel::GetDevice(uint32_t i) const [member function] - cls.add_method('GetDevice', 'ns3::Ptr< ns3::NetDevice >', [param('uint32_t', 'i')], is_pure_virtual=True, is_const=True, is_virtual=True) - return - def register_Ns3EthernetHeader_methods(root_module, cls): ## ethernet-header.h: ns3::EthernetHeader::EthernetHeader(bool hasPreamble) [constructor] cls.add_constructor([param('bool', 'hasPreamble')], visibility='public') @@ -1256,8 +1256,8 @@ def register_Ns3SimpleNetDevice_methods(root_module, cls): cls.add_method('SetNode', 'void', [param('ns3::Ptr< ns3::Node >', 'node')], is_virtual=True) ## simple-net-device.h: bool ns3::SimpleNetDevice::NeedsArp() const [member function] cls.add_method('NeedsArp', 'bool', [], is_const=True, is_virtual=True) - ## simple-net-device.h: void ns3::SimpleNetDevice::SetReceiveCallback(ns3::Callback, ns3::Ptr, unsigned short, ns3::Address const&, ns3::Address const&, ns3::NetDevice::PacketType> cb) [member function] - cls.add_method('SetReceiveCallback', 'void', [param('ns3::Callback< bool, ns3::Ptr< ns3::NetDevice >, ns3::Ptr< ns3::Packet >, unsigned short, ns3::Address const&, ns3::Address const&, ns3::NetDevice::PacketType >', 'cb')], is_virtual=True) + ## simple-net-device.h: void ns3::SimpleNetDevice::SetReceiveCallback(ns3::Callback, ns3::Ptr, unsigned short, ns3::Address const&, ns3::empty, ns3::empty> cb) [member function] + cls.add_method('SetReceiveCallback', 'void', [param('ns3::Callback< bool, ns3::Ptr< ns3::NetDevice >, ns3::Ptr< ns3::Packet >, unsigned short, ns3::Address const&, ns3::empty, ns3::empty >', 'cb')], is_virtual=True) ## simple-net-device.h: void ns3::SimpleNetDevice::DoDispose() [member function] cls.add_method('DoDispose', 'void', [], visibility='protected', is_virtual=True) return diff --git a/bindings/python/ns3_module_point_to_point.py b/bindings/python/ns3_module_point_to_point.py index ac6e8520c..790f75862 100644 --- a/bindings/python/ns3_module_point_to_point.py +++ b/bindings/python/ns3_module_point_to_point.py @@ -131,8 +131,8 @@ def register_Ns3PointToPointNetDevice_methods(root_module, cls): cls.add_method('SetNode', 'void', [param('ns3::Ptr< ns3::Node >', 'node')], is_virtual=True) ## point-to-point-net-device.h: bool ns3::PointToPointNetDevice::NeedsArp() const [member function] cls.add_method('NeedsArp', 'bool', [], is_const=True, is_virtual=True) - ## point-to-point-net-device.h: void ns3::PointToPointNetDevice::SetReceiveCallback(ns3::Callback, ns3::Ptr, unsigned short, ns3::Address const&, ns3::Address const&, ns3::NetDevice::PacketType> cb) [member function] - cls.add_method('SetReceiveCallback', 'void', [param('ns3::Callback< bool, ns3::Ptr< ns3::NetDevice >, ns3::Ptr< ns3::Packet >, unsigned short, ns3::Address const&, ns3::Address const&, ns3::NetDevice::PacketType >', 'cb')], is_virtual=True) + ## point-to-point-net-device.h: void ns3::PointToPointNetDevice::SetReceiveCallback(ns3::Callback, ns3::Ptr, unsigned short, ns3::Address const&, ns3::empty, ns3::empty> cb) [member function] + cls.add_method('SetReceiveCallback', 'void', [param('ns3::Callback< bool, ns3::Ptr< ns3::NetDevice >, ns3::Ptr< ns3::Packet >, unsigned short, ns3::Address const&, ns3::empty, ns3::empty >', 'cb')], is_virtual=True) ## point-to-point-net-device.h: void ns3::PointToPointNetDevice::DoDispose() [member function] cls.add_method('DoDispose', 'void', [], visibility='private', is_virtual=True) return diff --git a/bindings/python/ns3_module_wifi.py b/bindings/python/ns3_module_wifi.py index ff93b16c9..e33d20093 100644 --- a/bindings/python/ns3_module_wifi.py +++ b/bindings/python/ns3_module_wifi.py @@ -1075,8 +1075,8 @@ def register_Ns3WifiNetDevice_methods(root_module, cls): cls.add_method('SetNode', 'void', [param('ns3::Ptr< ns3::Node >', 'node')], is_virtual=True) ## wifi-net-device.h: bool ns3::WifiNetDevice::NeedsArp() const [member function] cls.add_method('NeedsArp', 'bool', [], is_const=True, is_virtual=True) - ## wifi-net-device.h: void ns3::WifiNetDevice::SetReceiveCallback(ns3::Callback, ns3::Ptr, unsigned short, ns3::Address const&, ns3::Address const&, ns3::NetDevice::PacketType> cb) [member function] - cls.add_method('SetReceiveCallback', 'void', [param('ns3::Callback< bool, ns3::Ptr< ns3::NetDevice >, ns3::Ptr< ns3::Packet >, unsigned short, ns3::Address const&, ns3::Address const&, ns3::NetDevice::PacketType >', 'cb')], is_virtual=True) + ## wifi-net-device.h: void ns3::WifiNetDevice::SetReceiveCallback(ns3::Callback, ns3::Ptr, unsigned short, ns3::Address const&, ns3::empty, ns3::empty> cb) [member function] + cls.add_method('SetReceiveCallback', 'void', [param('ns3::Callback< bool, ns3::Ptr< ns3::NetDevice >, ns3::Ptr< ns3::Packet >, unsigned short, ns3::Address const&, ns3::empty, ns3::empty >', 'cb')], is_virtual=True) ## wifi-net-device.h: void ns3::WifiNetDevice::DoDispose() [member function] cls.add_method('DoDispose', 'void', [], visibility='private', is_virtual=True) return diff --git a/src/devices/bridge/bridge-net-device.cc b/src/devices/bridge/bridge-net-device.cc index 6529d4da2..a88b16933 100644 --- a/src/devices/bridge/bridge-net-device.cc +++ b/src/devices/bridge/bridge-net-device.cc @@ -68,19 +68,23 @@ BridgeNetDevice::ReceiveFromDevice (Ptr incomingPort, Ptr pac Mac48Address src48 = Mac48Address::ConvertFrom (src); Mac48Address dst48 = Mac48Address::ConvertFrom (dst); + if (!m_promiscRxCallback.IsNull ()) + { + m_promiscRxCallback (this, packet, protocol, src, dst, packetType); + } switch (packetType) { case PACKET_HOST: if (dst48 == m_address) { - m_rxCallback (this, packet, protocol, src, dst, packetType); + m_rxCallback (this, packet, protocol, src); } break; case PACKET_BROADCAST: case PACKET_MULTICAST: - m_rxCallback (this, packet, protocol, src, dst, packetType); + m_rxCallback (this, packet, protocol, src); ForwardBroadcast (incomingPort, packet, protocol, src48, dst48); break; @@ -160,12 +164,13 @@ Ptr BridgeNetDevice::GetLearnedState (Mac48Address source) { if (m_enableLearning) { + Time now = Simulator::Now (); std::map::iterator iter = m_learnState.find (source); if (iter != m_learnState.end ()) { LearnedState &state = iter->second; - if (state.expirationTime > Simulator::Now ()) + if (state.expirationTime > now) { return state.associatedPort; } @@ -187,8 +192,9 @@ BridgeNetDevice::AddBridgePort (Ptr bridgePort) m_address = Mac48Address::ConvertFrom (bridgePort->GetAddress ()); } + NS_LOG_DEBUG ("RegisterProtocolHandler for " << bridgePort->GetName ()); m_node->RegisterProtocolHandler (MakeCallback (&BridgeNetDevice::ReceiveFromDevice, this), - 0, bridgePort); + 0, bridgePort, true); m_ports.push_back (bridgePort); m_channel->AddChannel (bridgePort->GetChannel ()); } @@ -396,6 +402,18 @@ BridgeNetDevice::SetReceiveCallback (NetDevice::ReceiveCallback cb) m_rxCallback = cb; } +void +BridgeNetDevice::SetPromiscReceiveCallback (NetDevice::PromiscReceiveCallback cb) +{ + m_promiscRxCallback = cb; +} + +bool +BridgeNetDevice::SupportsPromiscuous () const +{ + return true; +} + void BridgeNetDevice::DoDispose (void) diff --git a/src/devices/bridge/bridge-net-device.h b/src/devices/bridge/bridge-net-device.h index 7a4475b1d..be44792d6 100644 --- a/src/devices/bridge/bridge-net-device.h +++ b/src/devices/bridge/bridge-net-device.h @@ -66,6 +66,8 @@ public: virtual void SetNode (Ptr node); virtual bool NeedsArp (void) const; virtual void SetReceiveCallback (NetDevice::ReceiveCallback cb); + virtual void SetPromiscReceiveCallback (NetDevice::PromiscReceiveCallback cb); + virtual bool SupportsPromiscuous () const; protected: virtual void DoDispose (void); @@ -81,6 +83,7 @@ protected: private: NetDevice::ReceiveCallback m_rxCallback; + NetDevice::PromiscReceiveCallback m_promiscRxCallback; Mac48Address m_address; Time m_expirationTime; // time it takes for learned MAC state to expire diff --git a/src/devices/csma/csma-net-device.cc b/src/devices/csma/csma-net-device.cc index b1e8fd317..15c353f94 100644 --- a/src/devices/csma/csma-net-device.cc +++ b/src/devices/csma/csma-net-device.cc @@ -481,7 +481,11 @@ CsmaNetDevice::Receive (Ptr packet, Ptr senderDevice) if (m_encapMode == RAW) { m_rxTrace (packet); - m_rxCallback (this, packet, 0, GetBroadcast (), GetAddress (), PACKET_HOST); + if (!m_promiscRxCallback.IsNull ()) + { + m_promiscRxCallback (this, packet, 0, GetBroadcast (), GetAddress (), PACKET_HOST); + } + m_rxCallback (this, packet, 0, GetBroadcast ()); return; } @@ -575,7 +579,15 @@ CsmaNetDevice::Receive (Ptr packet, Ptr senderDevice) packetType = PACKET_OTHERHOST; } - m_rxCallback (this, packet, protocol, header.GetSource (), header.GetDestination (), packetType); + if (!m_promiscRxCallback.IsNull ()) + { + m_promiscRxCallback (this, packet, protocol, header.GetSource (), header.GetDestination (), packetType); + } + + if (packetType != PACKET_OTHERHOST) + { + m_rxCallback (this, packet, protocol, header.GetSource ()); + } } } @@ -847,4 +859,16 @@ CsmaNetDevice::SetReceiveCallback (NetDevice::ReceiveCallback cb) m_rxCallback = cb; } +void +CsmaNetDevice::SetPromiscReceiveCallback (NetDevice::PromiscReceiveCallback cb) +{ + m_promiscRxCallback = cb; +} + +bool +CsmaNetDevice::SupportsPromiscuous () const +{ + return true; +} + } // namespace ns3 diff --git a/src/devices/csma/csma-net-device.h b/src/devices/csma/csma-net-device.h index 91e66517c..db22d7065 100644 --- a/src/devices/csma/csma-net-device.h +++ b/src/devices/csma/csma-net-device.h @@ -287,6 +287,10 @@ public: */ virtual void SetReceiveCallback (NetDevice::ReceiveCallback cb); + + virtual void SetPromiscReceiveCallback (PromiscReceiveCallback cb); + virtual bool SupportsPromiscuous (void) const; + protected: /** * Perform any object release functionality required to break reference @@ -533,6 +537,10 @@ private: * The callback used to notify higher layers that a packet has been received. */ NetDevice::ReceiveCallback m_rxCallback; + /** + * The callback used to notify higher layers that a packet has been received in promiscuous mode. + */ + NetDevice::PromiscReceiveCallback m_promiscRxCallback; /** * The interface index (really net evice index) that has been assigned to diff --git a/src/devices/point-to-point/point-to-point-net-device.cc b/src/devices/point-to-point/point-to-point-net-device.cc index 0ee8376de..b2953d070 100644 --- a/src/devices/point-to-point/point-to-point-net-device.cc +++ b/src/devices/point-to-point/point-to-point-net-device.cc @@ -241,7 +241,7 @@ PointToPointNetDevice::Receive (Ptr packet) // m_rxTrace (packet); ProcessHeader(packet, protocol); - m_rxCallback (this, packet, protocol, GetBroadcast (), m_address, PACKET_HOST); + m_rxCallback (this, packet, protocol, GetBroadcast ()); } } diff --git a/src/devices/wifi/wifi-net-device.cc b/src/devices/wifi/wifi-net-device.cc index 79672729e..862dd8e9a 100644 --- a/src/devices/wifi/wifi-net-device.cc +++ b/src/devices/wifi/wifi-net-device.cc @@ -316,9 +316,7 @@ WifiNetDevice::ForwardUp (Ptr packet, const Mac48Address &from) m_rxLogger (packet, from); LlcSnapHeader llc; packet->RemoveHeader (llc); - Mac48Address to = from; // FIXME - PacketType packetType = PACKET_HOST; // FIXME - m_forwardUp (this, packet, llc.GetType (), from, to, packetType); + m_forwardUp (this, packet, llc.GetType (), from); } void diff --git a/src/node/net-device.cc b/src/node/net-device.cc index 410cc3f49..92ea085ac 100644 --- a/src/node/net-device.cc +++ b/src/node/net-device.cc @@ -38,4 +38,19 @@ TypeId NetDevice::GetTypeId (void) NetDevice::~NetDevice () {} +bool +NetDevice::SupportsPromiscuous () const +{ + return false; +} + +void +NetDevice::SetPromiscReceiveCallback (PromiscReceiveCallback cb) +{ + // assert that the virtual method was overridden in a subclass if it + // claims to support promiscuous mode. + NS_ASSERT (!SupportsPromiscuous ()); +} + + } // namespace ns3 diff --git a/src/node/net-device.h b/src/node/net-device.h index b90dd9ab4..2110dbb04 100644 --- a/src/node/net-device.h +++ b/src/node/net-device.h @@ -271,11 +271,10 @@ public: * This protocol number is expected to be the same protocol number * given to the Send method by the user on the sender side. * \param sender the address of the sender - * \param receiver the address of the receiver * \returns true if the callback could handle the packet successfully, false * otherwise. */ - typedef Callback,Ptr,uint16_t,const Address &,const Address &, PacketType> ReceiveCallback; + typedef Callback,Ptr,uint16_t,const Address &> ReceiveCallback; /** * \param cb callback to invoke whenever a packet has been received and must @@ -284,6 +283,39 @@ public: */ virtual void SetReceiveCallback (ReceiveCallback cb) = 0; + + /** + * \param device a pointer to the net device which is calling this callback + * \param packet the packet received + * \param protocol the 16 bit protocol number associated with this packet. + * This protocol number is expected to be the same protocol number + * given to the Send method by the user on the sender side. + * \param sender the address of the sender + * \param receiver the address of the receiver + * \param packetType type of packet received (broadcast/multicast/unicast/otherhost) + * \returns true if the callback could handle the packet successfully, false + * otherwise. + */ + typedef Callback< bool, Ptr, Ptr, uint16_t, + const Address &, const Address &, PacketType > PromiscReceiveCallback; + + /** + * \param cb callback to invoke whenever a packet has been received in promiscuous mode and must + * be forwarded to the higher layers. + * + * Enables netdevice promiscuous mode and sets the callback that + * will handle promiscuous mode packets. Note, promiscuous mode + * packets means _all_ packets, including those packets that can be + * sensed by the netdevice but which are intended to be received by + * other hosts. + */ + virtual void SetPromiscReceiveCallback (PromiscReceiveCallback cb); + + /** + * \return true if this interface supports a promiscuous mode, false otherwise. + */ + virtual bool SupportsPromiscuous (void) const; + }; } // namespace ns3 diff --git a/src/node/node.cc b/src/node/node.cc index e1c650e00..5469f1a44 100644 --- a/src/node/node.cc +++ b/src/node/node.cc @@ -26,6 +26,9 @@ #include "ns3/simulator.h" #include "ns3/object-vector.h" #include "ns3/uinteger.h" +#include "ns3/log.h" + +NS_LOG_COMPONENT_DEFINE ("Node"); namespace ns3{ @@ -95,7 +98,7 @@ Node::AddDevice (Ptr device) m_devices.push_back (device); device->SetNode (this); device->SetIfIndex(index); - device->SetReceiveCallback (MakeCallback (&Node::ReceiveFromDevice, this)); + device->SetReceiveCallback (MakeCallback (&Node::NonPromiscReceiveFromDevice, this)); NotifyDeviceAdded (device); return index; } @@ -170,12 +173,44 @@ Node::NotifyDeviceAdded (Ptr device) void Node::RegisterProtocolHandler (ProtocolHandler handler, uint16_t protocolType, - Ptr device) + Ptr device, + bool promiscuous) { struct Node::ProtocolHandlerEntry entry; entry.handler = handler; entry.protocol = protocolType; entry.device = device; + entry.promiscuous = promiscuous; + + // On demand enable promiscuous mode in netdevices + if (promiscuous) + { + if (device == 0) + { + for (std::vector >::iterator i = m_devices.begin (); + i != m_devices.end (); i++) + { + Ptr dev = *i; + if (dev->SupportsPromiscuous ()) + { + dev->SetPromiscReceiveCallback (MakeCallback (&Node::PromiscReceiveFromDevice, this)); + } + } + } + else + { + if (device->SupportsPromiscuous ()) + { + device->SetPromiscReceiveCallback (MakeCallback (&Node::PromiscReceiveFromDevice, this)); + } + else + { + NS_LOG_WARN ("Protocol handler request promiscuous mode for a specific netdevice," + " but netdevice does not support promiscuous mode."); + } + } + } + m_handlers.push_back (entry); } @@ -194,9 +229,26 @@ Node::UnregisterProtocolHandler (ProtocolHandler handler) } bool -Node::ReceiveFromDevice (Ptr device, Ptr packet, uint16_t protocol, - const Address &from, const Address &to, NetDevice::PacketType packetType) +Node::PromiscReceiveFromDevice (Ptr device, Ptr packet, uint16_t protocol, + const Address &from, const Address &to, NetDevice::PacketType packetType) { + NS_LOG_FUNCTION(device->GetName ()); + return ReceiveFromDevice (device, packet, protocol, from, to, packetType, true); +} + +bool +Node::NonPromiscReceiveFromDevice (Ptr device, Ptr packet, uint16_t protocol, + const Address &from) +{ + NS_LOG_FUNCTION(device->GetName ()); + return ReceiveFromDevice (device, packet, protocol, from, from, NetDevice::PacketType (0), false); +} + +bool +Node::ReceiveFromDevice (Ptr device, Ptr packet, uint16_t protocol, + const Address &from, const Address &to, NetDevice::PacketType packetType, bool promiscuous) +{ + NS_LOG_FUNCTION(device->GetName ()); bool found = false; // if there are (potentially) multiple handlers, we need to copy the // packet before passing it to each handler, because handlers may @@ -212,8 +264,11 @@ Node::ReceiveFromDevice (Ptr device, Ptr packet, uint16_t pro if (i->protocol == 0 || i->protocol == protocol) { - i->handler (device, (copyNeeded ? packet->Copy () : packet), protocol, from, to, packetType); - found = true; + if (promiscuous == i->promiscuous) + { + i->handler (device, (copyNeeded ? packet->Copy () : packet), protocol, from, to, packetType); + found = true; + } } } } diff --git a/src/node/node.h b/src/node/node.h index 1608fd314..1f9d814a5 100644 --- a/src/node/node.h +++ b/src/node/node.h @@ -136,6 +136,20 @@ public: /** * A protocol handler + * + * \param device a pointer to the net device which received the packet + * \param packet the packet received + * \param protocol the 16 bit protocol number associated with this packet. + * This protocol number is expected to be the same protocol number + * given to the Send method by the user on the sender side. + * \param sender the address of the sender + * \param receiver the address of the receiver; Note: this value is + * only valid for promiscuous mode protocol + * handlers. + * \param packetType type of packet received + * (broadcast/multicast/unicast/otherhost); Note: + * this value is only valid for promiscuous mode + * protocol handlers. */ typedef Callback, Ptr,uint16_t,const Address &, const Address &, NetDevice::PacketType> ProtocolHandler; @@ -150,10 +164,12 @@ public: * \param device the device attached to this handler. If the * value is zero, the handler is attached to all * devices on this node. + * \param promiscuous whether to register a promiscuous mode handler */ void RegisterProtocolHandler (ProtocolHandler handler, uint16_t protocolType, - Ptr device); + Ptr device, + bool promiscuous=false); /** * \param handler the handler to unregister * @@ -162,34 +178,6 @@ public: */ void UnregisterProtocolHandler (ProtocolHandler handler); - /** - * A promiscuous protocol handler - */ - typedef Callback, Ptr,uint16_t, - const Address &, const Address &, bool> PromiscuousProtocolHandler; - /** - * \param handler the handler to register - * \param protocolType the type of protocol this handler is - * interested in. This protocol type is a so-called - * EtherType, as registered here: - * http://standards.ieee.org/regauth/ethertype/eth.txt - * the value zero is interpreted as matching all - * protocols. - * \param device the device attached to this handler. If the - * value is zero, the handler is attached to all - * devices on this node. - */ - void RegisterPromiscuousProtocolHandler (PromiscuousProtocolHandler handler, - uint16_t protocolType, - Ptr device); - /** - * \param handler the handler to unregister - * - * After this call returns, the input handler will never - * be invoked anymore. - */ - void UnregisterPromiscuousProtocolHandler (PromiscuousProtocolHandler handler); - protected: /** @@ -207,14 +195,19 @@ private: */ virtual void NotifyDeviceAdded (Ptr device); + bool NonPromiscReceiveFromDevice (Ptr device, Ptr, uint16_t protocol, const Address &from); + bool PromiscReceiveFromDevice (Ptr device, Ptr, uint16_t protocol, + const Address &from, const Address &to, NetDevice::PacketType packetType); bool ReceiveFromDevice (Ptr device, Ptr, uint16_t protocol, - const Address &from, const Address &to, NetDevice::PacketType packetType); + const Address &from, const Address &to, NetDevice::PacketType packetType, bool promisc); + void Construct (void); struct ProtocolHandlerEntry { ProtocolHandler handler; - uint16_t protocol; Ptr device; + uint16_t protocol; + bool promiscuous; }; typedef std::vector ProtocolHandlerList; uint32_t m_id; // Node id for this node diff --git a/src/node/simple-net-device.cc b/src/node/simple-net-device.cc index ba58688bb..8f1b0d718 100644 --- a/src/node/simple-net-device.cc +++ b/src/node/simple-net-device.cc @@ -59,7 +59,7 @@ SimpleNetDevice::Receive (Ptr packet, uint16_t protocol, { NS_FATAL_ERROR ("Weird packet destination " << to); } - m_rxCallback (this, packet, protocol, from, to, packetType); + m_rxCallback (this, packet, protocol, from); } void From a8d461f29e59ee6f9e26bd7a9ae2ec0261c8340c Mon Sep 17 00:00:00 2001 From: "Gustavo J. A. M. Carneiro" Date: Wed, 16 Jul 2008 16:17:21 +0100 Subject: [PATCH 176/495] Remove some useless code --- src/internet-stack/arp-l3-protocol.cc | 5 ----- src/internet-stack/ipv4-l3-protocol.cc | 5 ----- 2 files changed, 10 deletions(-) diff --git a/src/internet-stack/arp-l3-protocol.cc b/src/internet-stack/arp-l3-protocol.cc index fa418deac..70aeab62a 100644 --- a/src/internet-stack/arp-l3-protocol.cc +++ b/src/internet-stack/arp-l3-protocol.cc @@ -119,11 +119,6 @@ ArpL3Protocol::Receive(Ptr device, Ptr packet, uint16_t proto { NS_LOG_FUNCTION_NOARGS (); - if (packetType == NetDevice::PACKET_OTHERHOST) - { - return; - } - Ptr cache = FindCache (device); ArpHeader arp; packet->RemoveHeader (arp); diff --git a/src/internet-stack/ipv4-l3-protocol.cc b/src/internet-stack/ipv4-l3-protocol.cc index 81b023b6e..975071419 100644 --- a/src/internet-stack/ipv4-l3-protocol.cc +++ b/src/internet-stack/ipv4-l3-protocol.cc @@ -454,11 +454,6 @@ Ipv4L3Protocol::Receive( Ptr device, Ptr packet, uint16_t pro { NS_LOG_FUNCTION (this << &device << packet << protocol << from); - if (packetType == NetDevice::PACKET_OTHERHOST) - { - return; - } - NS_LOG_LOGIC ("Packet from " << from << " received on node " << m_node->GetId ()); uint32_t index = 0; From 8cc54510bad20470b66a18b60d6820566b12adf8 Mon Sep 17 00:00:00 2001 From: "Gustavo J. A. M. Carneiro" Date: Wed, 16 Jul 2008 17:44:42 +0100 Subject: [PATCH 177/495] Don't run python unit tests if python bindings not enabled. Closes #254. --- wscript | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/wscript b/wscript index bea93c482..68e942b18 100644 --- a/wscript +++ b/wscript @@ -456,8 +456,11 @@ def _run_waf_check(): print "-- Running NS-3 C++ core unit tests..." run_program('run-tests', get_command_template()) - print "-- Running NS-3 Python bindings unit tests..." - _run_argv([env['PYTHON'], os.path.join("utils", "python-unit-tests.py")], proc_env) + if env['ENABLE_PYTHON_BINDINGS']: + print "-- Running NS-3 Python bindings unit tests..." + _run_argv([env['PYTHON'], os.path.join("utils", "python-unit-tests.py")], proc_env) + else: + print "-- Skipping NS-3 Python bindings unit tests: Python bindings not enabled." def _find_program(program_name, env): From 4914c4afcb473a3784d5b594936c3a453fca3029 Mon Sep 17 00:00:00 2001 From: Tom Henderson Date: Wed, 16 Jul 2008 22:33:51 -0700 Subject: [PATCH 178/495] Add NS_LOG_FUNCTION calls in arp implementation --- src/internet-stack/arp-cache.cc | 27 ++++++++++++++++++++++++++- src/internet-stack/arp-l3-protocol.cc | 2 ++ 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/src/internet-stack/arp-cache.cc b/src/internet-stack/arp-cache.cc index bfceaea2f..cee855236 100644 --- a/src/internet-stack/arp-cache.cc +++ b/src/internet-stack/arp-cache.cc @@ -85,6 +85,7 @@ ArpCache::DoDispose (void) void ArpCache::SetDevice (Ptr device, Ptr interface) { + NS_LOG_FUNCTION_NOARGS (); m_device = device; m_interface = interface; } @@ -92,50 +93,59 @@ ArpCache::SetDevice (Ptr device, Ptr interface) Ptr ArpCache::GetDevice (void) const { + NS_LOG_FUNCTION_NOARGS (); return m_device; } Ptr ArpCache::GetInterface (void) const { + NS_LOG_FUNCTION_NOARGS (); return m_interface; } void ArpCache::SetAliveTimeout (Time aliveTimeout) { + NS_LOG_FUNCTION_NOARGS (); m_aliveTimeout = aliveTimeout; } void ArpCache::SetDeadTimeout (Time deadTimeout) { + NS_LOG_FUNCTION_NOARGS (); m_deadTimeout = deadTimeout; } void ArpCache::SetWaitReplyTimeout (Time waitReplyTimeout) { + NS_LOG_FUNCTION_NOARGS (); m_waitReplyTimeout = waitReplyTimeout; } Time ArpCache::GetAliveTimeout (void) const { + NS_LOG_FUNCTION_NOARGS (); return m_aliveTimeout; } Time ArpCache::GetDeadTimeout (void) const { + NS_LOG_FUNCTION_NOARGS (); return m_deadTimeout; } Time ArpCache::GetWaitReplyTimeout (void) const { + NS_LOG_FUNCTION_NOARGS (); return m_waitReplyTimeout; } void ArpCache::Flush (void) { + NS_LOG_FUNCTION_NOARGS (); for (CacheI i = m_arpCache.begin (); i != m_arpCache.end (); i++) { delete (*i).second; @@ -146,6 +156,7 @@ ArpCache::Flush (void) ArpCache::Entry * ArpCache::Lookup (Ipv4Address to) { + NS_LOG_FUNCTION_NOARGS (); if (m_arpCache.find (to) != m_arpCache.end ()) { ArpCache::Entry *entry = m_arpCache[to]; @@ -157,6 +168,7 @@ ArpCache::Lookup (Ipv4Address to) ArpCache::Entry * ArpCache::Add (Ipv4Address to) { + NS_LOG_FUNCTION_NOARGS (); NS_ASSERT (m_arpCache.find (to) == m_arpCache.end ()); ArpCache::Entry *entry = new ArpCache::Entry (this); @@ -167,22 +179,27 @@ ArpCache::Add (Ipv4Address to) ArpCache::Entry::Entry (ArpCache *arp) : m_arp (arp), m_state (ALIVE) -{} +{ + NS_LOG_FUNCTION_NOARGS (); +} bool ArpCache::Entry::IsDead (void) { + NS_LOG_FUNCTION_NOARGS (); return (m_state == DEAD)?true:false; } bool ArpCache::Entry::IsAlive (void) { + NS_LOG_FUNCTION_NOARGS (); return (m_state == ALIVE)?true:false; } bool ArpCache::Entry::IsWaitReply (void) { + NS_LOG_FUNCTION_NOARGS (); return (m_state == WAIT_REPLY)?true:false; } @@ -190,12 +207,14 @@ ArpCache::Entry::IsWaitReply (void) void ArpCache::Entry::MarkDead (void) { + NS_LOG_FUNCTION_NOARGS (); m_state = DEAD; UpdateSeen (); } void ArpCache::Entry::MarkAlive (Address macAddress) { + NS_LOG_FUNCTION_NOARGS (); NS_ASSERT (m_state == WAIT_REPLY); m_macAddress = macAddress; m_state = ALIVE; @@ -205,6 +224,7 @@ ArpCache::Entry::MarkAlive (Address macAddress) bool ArpCache::Entry::UpdateWaitReply (Ptr waiting) { + NS_LOG_FUNCTION_NOARGS (); NS_ASSERT (m_state == WAIT_REPLY); /* We are already waiting for an answer so * we dump the previously waiting packet and @@ -220,6 +240,7 @@ ArpCache::Entry::UpdateWaitReply (Ptr waiting) void ArpCache::Entry::MarkWaitReply (Ptr waiting) { + NS_LOG_FUNCTION_NOARGS (); NS_ASSERT (m_state == ALIVE || m_state == DEAD); NS_ASSERT (m_pending.empty ()); m_state = WAIT_REPLY; @@ -230,12 +251,14 @@ ArpCache::Entry::MarkWaitReply (Ptr waiting) Address ArpCache::Entry::GetMacAddress (void) { + NS_LOG_FUNCTION_NOARGS (); NS_ASSERT (m_state == ALIVE); return m_macAddress; } bool ArpCache::Entry::IsExpired (void) { + NS_LOG_FUNCTION_NOARGS (); Time timeout; switch (m_state) { case ArpCache::Entry::WAIT_REPLY: @@ -266,6 +289,7 @@ ArpCache::Entry::IsExpired (void) Ptr ArpCache::Entry::DequeuePending (void) { + NS_LOG_FUNCTION_NOARGS (); if (m_pending.empty ()) { return 0; @@ -280,6 +304,7 @@ ArpCache::Entry::DequeuePending (void) void ArpCache::Entry::UpdateSeen (void) { + NS_LOG_FUNCTION_NOARGS (); m_lastSeen = Simulator::Now (); } diff --git a/src/internet-stack/arp-l3-protocol.cc b/src/internet-stack/arp-l3-protocol.cc index bd27ce7c6..9ba059b43 100644 --- a/src/internet-stack/arp-l3-protocol.cc +++ b/src/internet-stack/arp-l3-protocol.cc @@ -68,6 +68,7 @@ ArpL3Protocol::~ArpL3Protocol () void ArpL3Protocol::SetNode (Ptr node) { + NS_LOG_FUNCTION (this); m_node = node; } @@ -88,6 +89,7 @@ ArpL3Protocol::DoDispose (void) Ptr ArpL3Protocol::CreateCache (Ptr device, Ptr interface) { + NS_LOG_FUNCTION_NOARGS (); Ptr ipv4 = m_node->GetObject (); Ptr cache = CreateObject (); cache->SetDevice (device, interface); From f7fc5982400d1ada86003ef468599089572c1c94 Mon Sep 17 00:00:00 2001 From: "Gustavo J. A. M. Carneiro" Date: Thu, 17 Jul 2008 17:57:18 +0100 Subject: [PATCH 179/495] A couple of attribute python unit tests --- utils/python-unit-tests.py | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/utils/python-unit-tests.py b/utils/python-unit-tests.py index a513f9a7f..18d6b5d96 100644 --- a/utils/python-unit-tests.py +++ b/utils/python-unit-tests.py @@ -78,7 +78,35 @@ class TestSimulator(unittest.TestCase): ns3.Simulator.Run() self.assert_(self._received_packet is not None) self.assertEqual(self._received_packet.GetSize(), 19) + + + def testAttributes(self): + ## + ## Yes, I know, the GetAttribute interface for Python is + ## horrible, we should fix this soon, I hope. + ## + queue = ns3.DropTailQueue() + + queue.SetAttribute("MaxPackets", ns3.UintegerValue(123456)) + + limit = ns3.UintegerValue() + queue.GetAttribute("MaxPackets", limit) + self.assertEqual(limit.Get(), 123456) + + ## -- object pointer values + mobility = ns3.RandomWaypointMobilityModel() + ptr = ns3.PointerValue() + mobility.GetAttribute("Position", ptr) + self.assertEqual(ptr.GetObject(), None) + pos = ns3.ListPositionAllocator() + mobility.SetAttribute("Position", ns3.PointerValue(pos)) + + ptr = ns3.PointerValue() + mobility.GetAttribute("Position", ptr) + self.assert_(ptr.GetObject() is not None) + + if __name__ == '__main__': unittest.main() From e567e5fec5c1507985fe332bdeaeddb2ccd32129 Mon Sep 17 00:00:00 2001 From: Craig Dowell Date: Thu, 17 Jul 2008 18:45:58 -0700 Subject: [PATCH 180/495] fix darwin build break --- src/core/unix-system-mutex.cc | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/core/unix-system-mutex.cc b/src/core/unix-system-mutex.cc index 359ffa74d..afbaf518c 100644 --- a/src/core/unix-system-mutex.cc +++ b/src/core/unix-system-mutex.cc @@ -51,7 +51,14 @@ SystemMutexPrivate::SystemMutexPrivate () // deadlocking it returns an error. It will also check to make sure a thread // has previously called pthread_mutex_lock when it calls pthread_mutex_unlock. // +// Linux and OS X (at least) have, of course chosen different names for the +// error checking flags just to make life difficult. +// +#if defined (PTHREAD_MUTEX_ERRORCHECK_NP) pthread_mutexattr_settype (&attr, PTHREAD_MUTEX_ERRORCHECK_NP); +#else + pthread_mutexattr_settype (&attr, PTHREAD_MUTEX_ERRORCHECK); +#endif pthread_mutex_init (&m_mutex, &attr); } From d369fc0c616115641696c41524429e7e459b000b Mon Sep 17 00:00:00 2001 From: Unknown Date: Thu, 17 Jul 2008 18:57:08 -0700 Subject: [PATCH 181/495] fix darwin build break --- src/core/unix-system-condition.cc | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/core/unix-system-condition.cc b/src/core/unix-system-condition.cc index b2bfa11d7..133dc18ed 100644 --- a/src/core/unix-system-condition.cc +++ b/src/core/unix-system-condition.cc @@ -55,7 +55,15 @@ SystemConditionPrivate::SystemConditionPrivate () pthread_mutexattr_t mAttr; pthread_mutexattr_init (&mAttr); +// +// Linux and OS X (at least) have, of course chosen different names for the +// error checking flags just to make life difficult. +// +#if defined (PTHREAD_MUTEX_ERRORCHECK_NP) pthread_mutexattr_settype (&mAttr, PTHREAD_MUTEX_ERRORCHECK_NP); +#else + pthread_mutexattr_settype (&mAttr, PTHREAD_MUTEX_ERRORCHECK); +#endif pthread_mutex_init (&m_mutex, &mAttr); pthread_condattr_t cAttr; From b1af5815b07368407fa5969a0d5a4755949212c1 Mon Sep 17 00:00:00 2001 From: Craig Dowell Date: Thu, 17 Jul 2008 23:52:59 -0700 Subject: [PATCH 182/495] factor simulator into interface and (multiple) implementation pieces --- src/simulator/simulator-impl.cc | 331 +++++++++++++++++++ src/simulator/simulator-impl.h | 88 +++++ src/simulator/simulator.cc | 547 ++++++++------------------------ src/simulator/simulator.h | 6 +- src/simulator/wscript | 2 + 5 files changed, 552 insertions(+), 422 deletions(-) create mode 100644 src/simulator/simulator-impl.cc create mode 100644 src/simulator/simulator-impl.h diff --git a/src/simulator/simulator-impl.cc b/src/simulator/simulator-impl.cc new file mode 100644 index 000000000..0bfdc9995 --- /dev/null +++ b/src/simulator/simulator-impl.cc @@ -0,0 +1,331 @@ +/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ +/* + * Copyright (c) 2005,2006 INRIA + * + * 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 + * + * Author: Mathieu Lacage + */ + +#include "simulator.h" +#include "simulator-impl.h" +#include "scheduler.h" +#include "event-impl.h" + +#include "ns3/ptr.h" +#include "ns3/pointer.h" +#include "ns3/assert.h" +#include "ns3/log.h" + +#include + +NS_LOG_COMPONENT_DEFINE ("SimulatorImpl"); + +namespace ns3 { + +NS_OBJECT_ENSURE_REGISTERED (SimulatorImpl); + +TypeId +SimulatorImpl::GetTypeId (void) +{ + static TypeId tid = TypeId ("ns3::SimulatorImpl") + .SetParent () + .AddConstructor () + ; + return tid; +} + +SimulatorImpl::SimulatorImpl () +{ + m_stop = false; + m_stopAt = 0; + // uids are allocated from 4. + // uid 0 is "invalid" events + // uid 1 is "now" events + // uid 2 is "destroy" events + m_uid = 4; + // before ::Run is entered, the m_currentUid will be zero + m_currentUid = 0; + m_logEnable = false; + m_currentTs = 0; + m_unscheduledEvents = 0; +} + +SimulatorImpl::~SimulatorImpl () +{ + while (!m_events->IsEmpty ()) + { + EventId next = m_events->RemoveNext (); + } + m_events = 0; +} + +void +SimulatorImpl::Destroy () +{ + while (!m_destroyEvents.empty ()) + { + Ptr ev = m_destroyEvents.front ().PeekEventImpl (); + m_destroyEvents.pop_front (); + NS_LOG_LOGIC ("handle destroy " << ev); + if (!ev->IsCancelled ()) + { + ev->Invoke (); + } + } +} + +void +SimulatorImpl::SetScheduler (Ptr scheduler) +{ + if (m_events != 0) + { + while (!m_events->IsEmpty ()) + { + EventId next = m_events->RemoveNext (); + scheduler->Insert (next); + } + } + m_events = scheduler; +} + +Ptr +SimulatorImpl::GetScheduler (void) const +{ + return m_events; +} + +void +SimulatorImpl::EnableLogTo (char const *filename) +{ + m_log.open (filename); + m_logEnable = true; +} + +void +SimulatorImpl::ProcessOneEvent (void) +{ + EventId next = m_events->RemoveNext (); + + NS_ASSERT (next.GetTs () >= m_currentTs); + --m_unscheduledEvents; + + NS_LOG_LOGIC ("handle " << next.GetTs ()); + m_currentTs = next.GetTs (); + m_currentUid = next.GetUid (); + if (m_logEnable) + { + m_log << "e "<Invoke (); +} + +bool +SimulatorImpl::IsFinished (void) const +{ + return m_events->IsEmpty (); +} + +uint64_t +SimulatorImpl::NextTs (void) const +{ + NS_ASSERT (!m_events->IsEmpty ()); + EventId id = m_events->PeekNext (); + return id.GetTs (); +} + +Time +SimulatorImpl::Next (void) const +{ + return TimeStep (NextTs ()); +} + +void +SimulatorImpl::Run (void) +{ + + while (!m_events->IsEmpty () && !m_stop && + (m_stopAt == 0 || m_stopAt > NextTs ())) + { + ProcessOneEvent (); + } + + // If the simulator stopped naturally by lack of events, make a + // consistency test to check that we didn't lose any events along the way. + NS_ASSERT(!m_events->IsEmpty () || m_unscheduledEvents == 0); + + m_log.close (); +} + +void +SimulatorImpl::Stop (void) +{ + m_stop = true; +} + +void +SimulatorImpl::Stop (Time const &time) +{ + NS_ASSERT (time.IsPositive ()); + Time absolute = Simulator::Now () + time; + m_stopAt = absolute.GetTimeStep (); +} + +EventId +SimulatorImpl::Schedule (Time const &time, const Ptr &event) +{ + NS_ASSERT (time.IsPositive ()); + NS_ASSERT (time >= TimeStep (m_currentTs)); + uint64_t ts = (uint64_t) time.GetTimeStep (); + EventId id (event, ts, m_uid); + if (m_logEnable) + { + m_log << "i "<Insert (id); + return id; +} + +EventId +SimulatorImpl::ScheduleNow (const Ptr &event) +{ + EventId id (event, m_currentTs, m_uid); + if (m_logEnable) + { + m_log << "i "<Insert (id); + return id; +} + +EventId +SimulatorImpl::ScheduleDestroy (const Ptr &event) +{ + EventId id (event, m_currentTs, 2); + m_destroyEvents.push_back (id); + if (m_logEnable) + { + m_log << "id " << m_currentUid << " " << Now ().GetTimeStep () << " " + << m_uid << std::endl; + } + m_uid++; + return id; +} + +Time +SimulatorImpl::Now (void) const +{ + return TimeStep (m_currentTs); +} + +Time +SimulatorImpl::GetDelayLeft (const EventId &id) const +{ + if (IsExpired (id)) + { + return TimeStep (0); + } + else + { + return TimeStep (id.GetTs () - m_currentTs); + } +} + +void +SimulatorImpl::Remove (const EventId &ev) +{ + if (ev.GetUid () == 2) + { + // destroy events. + for (DestroyEvents::iterator i = m_destroyEvents.begin (); i != m_destroyEvents.end (); i++) + { + if (*i == ev) + { + m_destroyEvents.erase (i); + break; + } + } + return; + } + if (IsExpired (ev)) + { + return; + } + m_events->Remove (ev); + Cancel (ev); + + if (m_logEnable) + { + m_log << "r " << m_currentUid << " " << m_currentTs << " " + << ev.GetUid () << " " << ev.GetTs () << std::endl; + } + --m_unscheduledEvents; +} + +void +SimulatorImpl::Cancel (const EventId &id) +{ + if (!IsExpired (id)) + { + id.PeekEventImpl ()->Cancel (); + } +} + +bool +SimulatorImpl::IsExpired (const EventId &ev) const +{ + if (ev.GetUid () == 2) + { + // destroy events. + for (DestroyEvents::const_iterator i = m_destroyEvents.begin (); i != m_destroyEvents.end (); i++) + { + if (*i == ev) + { + return false; + } + } + return true; + } + if (ev.PeekEventImpl () == 0 || + ev.GetTs () < m_currentTs || + (ev.GetTs () == m_currentTs && + ev.GetUid () <= m_currentUid) || + ev.PeekEventImpl ()->IsCancelled ()) + { + return true; + } + else + { + return false; + } +} + +Time +SimulatorImpl::GetMaximumSimulationTime (void) const +{ + // XXX: I am fairly certain other compilers use other non-standard + // post-fixes to indicate 64 bit constants. + return TimeStep (0x7fffffffffffffffLL); +} + +}; // namespace ns3 + + diff --git a/src/simulator/simulator-impl.h b/src/simulator/simulator-impl.h new file mode 100644 index 000000000..f72a71952 --- /dev/null +++ b/src/simulator/simulator-impl.h @@ -0,0 +1,88 @@ +/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ +/* + * Copyright (c) 2005,2006 INRIA + * + * 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 + * + * Author: Mathieu Lacage + */ + +#ifndef SIMULATOR_IMPL_H +#define SIMULATOR_IMPL_H + +#include "scheduler.h" +#include "event-impl.h" + +#include "ns3/ptr.h" +#include "ns3/assert.h" +#include "ns3/log.h" + +#include +#include + +namespace ns3 { + +class SimulatorImpl : public Object +{ +public: + static TypeId GetTypeId (void); + + SimulatorImpl (); + ~SimulatorImpl (); + + void Destroy (); + + void EnableLogTo (char const *filename); + + bool IsFinished (void) const; + Time Next (void) const; + void Stop (void); + void Stop (Time const &time); + EventId Schedule (Time const &time, const Ptr &event); + EventId ScheduleNow (const Ptr &event); + EventId ScheduleDestroy (const Ptr &event); + void Remove (const EventId &ev); + void Cancel (const EventId &ev); + bool IsExpired (const EventId &ev) const; + void Run (void); + Time Now (void) const; + Time GetDelayLeft (const EventId &id) const; + Time GetMaximumSimulationTime (void) const; + + void SetScheduler (Ptr scheduler); + Ptr GetScheduler (void) const; + +private: + void ProcessOneEvent (void); + uint64_t NextTs (void) const; + + typedef std::list DestroyEvents; + DestroyEvents m_destroyEvents; + uint64_t m_stopAt; + bool m_stop; + Ptr m_events; + uint32_t m_uid; + uint32_t m_currentUid; + uint64_t m_currentTs; + std::ofstream m_log; + std::ifstream m_inputLog; + bool m_logEnable; + // number of events that have been inserted but not yet scheduled, + // not counting the "destroy" events; this is used for validation + int m_unscheduledEvents; +}; + +} // namespace ns3 + +#endif /* SIMULATOR_IMPL_H */ diff --git a/src/simulator/simulator.cc b/src/simulator/simulator.cc index 00af60a65..7d20ec4d9 100644 --- a/src/simulator/simulator.cc +++ b/src/simulator/simulator.cc @@ -19,7 +19,9 @@ */ #include "simulator.h" +#include "simulator-impl.h" #include "scheduler.h" +#include "map-scheduler.h" #include "event-impl.h" #include "ns3/ptr.h" @@ -27,395 +29,16 @@ #include "ns3/assert.h" #include "ns3/log.h" - #include #include #include #include #include -#define noTRACE_SIMU 1 - -#ifdef TRACE_SIMU -#include -# define TRACE(x) \ -std::cout << "SIMU TRACE " << Simulator::Now () << " " << x << std::endl; -# define TRACE_S(x) \ -std::cout << "SIMU TRACE " << x << std::endl; -#else /* TRACE_SIMU */ -# define TRACE(format,...) -# define TRACE_S(format,...) -#endif /* TRACE_SIMU */ - +NS_LOG_COMPONENT_DEFINE ("Simulator"); namespace ns3 { -/** - * \brief private implementation detail of the Simulator API. - */ -class SimulatorPrivate : public Object -{ -public: - static TypeId GetTypeId (void); - - SimulatorPrivate (); - ~SimulatorPrivate (); - - void Destroy (); - - void EnableLogTo (char const *filename); - - bool IsFinished (void) const; - Time Next (void) const; - void Stop (void); - void Stop (Time const &time); - EventId Schedule (Time const &time, const Ptr &event); - EventId ScheduleNow (const Ptr &event); - EventId ScheduleDestroy (const Ptr &event); - void Remove (const EventId &ev); - void Cancel (const EventId &ev); - bool IsExpired (const EventId &ev) const; - void Run (void); - Time Now (void) const; - Time GetDelayLeft (const EventId &id) const; - Time GetMaximumSimulationTime (void) const; - - void SetScheduler (Ptr scheduler); - Ptr GetScheduler (void) const; - -private: - void ProcessOneEvent (void); - uint64_t NextTs (void) const; - - typedef std::list DestroyEvents; - DestroyEvents m_destroyEvents; - uint64_t m_stopAt; - bool m_stop; - Ptr m_events; - uint32_t m_uid; - uint32_t m_currentUid; - uint64_t m_currentTs; - std::ofstream m_log; - std::ifstream m_inputLog; - bool m_logEnable; - // number of events that have been inserted but not yet scheduled, - // not counting the "destroy" events; this is used for validation - int m_unscheduledEvents; -}; - -NS_OBJECT_ENSURE_REGISTERED (SimulatorPrivate); - - -TypeId -SimulatorPrivate::GetTypeId (void) -{ - static TypeId tid = TypeId ("ns3::SimulatorPrivate") - .SetParent () - .AddConstructor () - .AddAttribute ("Scheduler", - "The Scheduler used to handle all simulation events.", - PointerValue (), - MakePointerAccessor (&SimulatorPrivate::SetScheduler, - &SimulatorPrivate::GetScheduler), - MakePointerChecker ()) - ; - return tid; -} - -SimulatorPrivate::SimulatorPrivate () -{ - m_stop = false; - m_stopAt = 0; - // uids are allocated from 4. - // uid 0 is "invalid" events - // uid 1 is "now" events - // uid 2 is "destroy" events - m_uid = 4; - // before ::Run is entered, the m_currentUid will be zero - m_currentUid = 0; - m_logEnable = false; - m_currentTs = 0; - m_unscheduledEvents = 0; -} - -SimulatorPrivate::~SimulatorPrivate () -{ - while (!m_events->IsEmpty ()) - { - EventId next = m_events->RemoveNext (); - } - m_events = 0; -} -void -SimulatorPrivate::Destroy () -{ - while (!m_destroyEvents.empty ()) - { - Ptr ev = m_destroyEvents.front ().PeekEventImpl (); - m_destroyEvents.pop_front (); - TRACE ("handle destroy " << ev); - if (!ev->IsCancelled ()) - { - ev->Invoke (); - } - } -} - -void -SimulatorPrivate::SetScheduler (Ptr scheduler) -{ - if (m_events != 0) - { - while (!m_events->IsEmpty ()) - { - EventId next = m_events->RemoveNext (); - scheduler->Insert (next); - } - } - m_events = scheduler; -} - -Ptr -SimulatorPrivate::GetScheduler (void) const -{ - return m_events; -} - -void -SimulatorPrivate::EnableLogTo (char const *filename) -{ - m_log.open (filename); - m_logEnable = true; -} - -void -SimulatorPrivate::ProcessOneEvent (void) -{ - EventId next = m_events->RemoveNext (); - - NS_ASSERT (next.GetTs () >= m_currentTs); - --m_unscheduledEvents; - - TRACE ("handle " << nextEv); - m_currentTs = next.GetTs (); - m_currentUid = next.GetUid (); - if (m_logEnable) - { - m_log << "e "<Invoke (); -} - -bool -SimulatorPrivate::IsFinished (void) const -{ - return m_events->IsEmpty (); -} -uint64_t -SimulatorPrivate::NextTs (void) const -{ - NS_ASSERT (!m_events->IsEmpty ()); - EventId id = m_events->PeekNext (); - return id.GetTs (); -} -Time -SimulatorPrivate::Next (void) const -{ - return TimeStep (NextTs ()); -} - -void -SimulatorPrivate::Run (void) -{ - - while (!m_events->IsEmpty () && !m_stop && - (m_stopAt == 0 || m_stopAt > NextTs ())) - { - ProcessOneEvent (); - } - - // If the simulator stopped naturally by lack of events, make a - // consistency test to check that we didn't lose any events along the way. - NS_ASSERT(!m_events->IsEmpty () || m_unscheduledEvents == 0); - - m_log.close (); -} - - -void -SimulatorPrivate::Stop (void) -{ - m_stop = true; -} -void -SimulatorPrivate::Stop (Time const &time) -{ - NS_ASSERT (time.IsPositive ()); - Time absolute = Simulator::Now () + time; - m_stopAt = absolute.GetTimeStep (); -} -EventId -SimulatorPrivate::Schedule (Time const &time, const Ptr &event) -{ - NS_ASSERT (time.IsPositive ()); - NS_ASSERT (time >= TimeStep (m_currentTs)); - uint64_t ts = (uint64_t) time.GetTimeStep (); - EventId id (event, ts, m_uid); - if (m_logEnable) - { - m_log << "i "<Insert (id); - return id; -} -EventId -SimulatorPrivate::ScheduleNow (const Ptr &event) -{ - EventId id (event, m_currentTs, m_uid); - if (m_logEnable) - { - m_log << "i "<Insert (id); - return id; -} -EventId -SimulatorPrivate::ScheduleDestroy (const Ptr &event) -{ - EventId id (event, m_currentTs, 2); - m_destroyEvents.push_back (id); - if (m_logEnable) - { - m_log << "id " << m_currentUid << " " << Now ().GetTimeStep () << " " - << m_uid << std::endl; - } - m_uid++; - return id; -} - -Time -SimulatorPrivate::Now (void) const -{ - return TimeStep (m_currentTs); -} -Time -SimulatorPrivate::GetDelayLeft (const EventId &id) const -{ - if (IsExpired (id)) - { - return TimeStep (0); - } - else - { - return TimeStep (id.GetTs () - m_currentTs); - } -} - -void -SimulatorPrivate::Remove (const EventId &ev) -{ - if (ev.GetUid () == 2) - { - // destroy events. - for (DestroyEvents::iterator i = m_destroyEvents.begin (); i != m_destroyEvents.end (); i++) - { - if (*i == ev) - { - m_destroyEvents.erase (i); - break; - } - } - return; - } - if (IsExpired (ev)) - { - return; - } - m_events->Remove (ev); - Cancel (ev); - - if (m_logEnable) - { - m_log << "r " << m_currentUid << " " << m_currentTs << " " - << ev.GetUid () << " " << ev.GetTs () << std::endl; - } - --m_unscheduledEvents; -} - -void -SimulatorPrivate::Cancel (const EventId &id) -{ - if (!IsExpired (id)) - { - id.PeekEventImpl ()->Cancel (); - } -} - -bool -SimulatorPrivate::IsExpired (const EventId &ev) const -{ - if (ev.GetUid () == 2) - { - // destroy events. - for (DestroyEvents::const_iterator i = m_destroyEvents.begin (); i != m_destroyEvents.end (); i++) - { - if (*i == ev) - { - return false; - } - } - return true; - } - if (ev.PeekEventImpl () == 0 || - ev.GetTs () < m_currentTs || - (ev.GetTs () == m_currentTs && - ev.GetUid () <= m_currentUid) || - ev.PeekEventImpl ()->IsCancelled ()) - { - return true; - } - else - { - return false; - } -} - -Time -SimulatorPrivate::GetMaximumSimulationTime (void) const -{ - // XXX: I am fairly certain other compilers use other non-standard - // post-fixes to indicate 64 bit constants. - return TimeStep (0x7fffffffffffffffLL); -} - - - -}; // namespace ns3 - - -#include "map-scheduler.h" - - -namespace ns3 { - -Ptr Simulator::m_priv = 0; - -void Simulator::SetScheduler (Ptr scheduler) -{ - GetPriv ()->SetScheduler (scheduler); -} -void Simulator::EnableLogTo (char const *filename) -{ - GetPriv ()->EnableLogTo (filename); -} - #ifdef NS3_LOG_ENABLE static void TimePrinter (std::ostream &os) @@ -424,88 +47,121 @@ TimePrinter (std::ostream &os) } #endif /* NS3_LOG_ENABLE */ -Ptr -Simulator::GetPriv (void) +Ptr Simulator::m_impl = 0; + +Ptr +Simulator::GetImpl (void) { - if (m_priv == 0) + NS_LOG_FUNCTION_NOARGS (); + + if (m_impl == 0) { - /* Note: we call LogSetTimePrinter below _after_ calling CreateObject because - * CreateObject can trigger calls to the logging framework which would call - * the TimePrinter function above which would call Simulator::Now which would - * call Simulator::GetPriv, and, thus, get us in an infinite recursion until the - * stack explodes. + /* Note: we call LogSetTimePrinter below _after_ calling CreateObject + * because CreateObject can trigger calls to the logging framework which + * would call the TimePrinter function above which would call + * Simulator::Now which would call Simulator::GetImpl, and, thus, get + * us in an infinite recursion until the stack explodes. */ - m_priv = CreateObject (); + m_impl = CreateObject (); + Ptr scheduler = CreateObject (); - m_priv->SetScheduler (scheduler); + m_impl->SetScheduler (scheduler); + LogSetTimePrinter (&TimePrinter); } - TRACE_S ("priv " << m_priv); - return m_priv; + NS_LOG_LOGIC ("priv " << m_impl); + return m_impl; } void Simulator::Destroy (void) { - if (m_priv == 0) + NS_LOG_FUNCTION_NOARGS (); + + if (m_impl == 0) { return; } - /* Note: we have to call LogSetTimePrinter (0) below because if we do not do this, - * and restart a simulation after this call to Destroy, (which is legal), - * Simulator::GetPriv will trigger again an infinite recursion until the stack - * explodes. + /* Note: we have to call LogSetTimePrinter (0) below because if we do not do + * this, and restart a simulation after this call to Destroy, (which is + * legal), Simulator::GetImpl will trigger again an infinite recursion until + * the stack explodes. */ LogSetTimePrinter (0); - m_priv->Destroy (); - m_priv = 0; + m_impl->Destroy (); + m_impl = 0; } +void +Simulator::SetScheduler (Ptr scheduler) +{ + NS_LOG_FUNCTION (scheduler); + GetImpl ()->SetScheduler (scheduler); +} + +void +Simulator::EnableLogTo (char const *filename) +{ + NS_LOG_FUNCTION (filename); + GetImpl ()->EnableLogTo (filename); +} bool Simulator::IsFinished (void) { - return GetPriv ()->IsFinished (); + NS_LOG_FUNCTION_NOARGS (); + return GetImpl ()->IsFinished (); } + Time Simulator::Next (void) { - return GetPriv ()->Next (); + NS_LOG_FUNCTION_NOARGS (); + return GetImpl ()->Next (); } - void Simulator::Run (void) { - GetPriv ()->Run (); + NS_LOG_FUNCTION_NOARGS (); + GetImpl ()->Run (); } + void Simulator::Stop (void) { - TRACE ("stop"); - GetPriv ()->Stop (); + NS_LOG_LOGIC ("stop"); + GetImpl ()->Stop (); } + void Simulator::Stop (Time const &time) { - GetPriv ()->Stop (time); + NS_LOG_FUNCTION (time); + GetImpl ()->Stop (time); } + Time Simulator::Now (void) { - return GetPriv ()->Now (); + NS_LOG_FUNCTION_NOARGS (); + return GetImpl ()->Now (); } + Time Simulator::GetDelayLeft (const EventId &id) { - return GetPriv ()->GetDelayLeft (id); + NS_LOG_FUNCTION (&id); + return GetImpl ()->GetDelayLeft (id); } Ptr Simulator::MakeEvent (void (*f) (void)) { - // zero arg version - class EventFunctionImpl0 : public EventImpl { + NS_LOG_FUNCTION (f); + // zero arg version + class EventFunctionImpl0 : public EventImpl + { public: typedef void (*F)(void); @@ -522,64 +178,81 @@ Simulator::MakeEvent (void (*f) (void)) } *ev = new EventFunctionImpl0 (f); return Ptr (ev, false); } + EventId Simulator::Schedule (Time const &time, const Ptr &ev) { - return GetPriv ()->Schedule (Now () + time, ev); + NS_LOG_FUNCTION (time << ev); + return GetImpl ()->Schedule (Now () + time, ev); } + EventId Simulator::ScheduleNow (const Ptr &ev) { - return GetPriv ()->ScheduleNow (ev); + NS_LOG_FUNCTION (ev); + return GetImpl ()->ScheduleNow (ev); } + EventId Simulator::ScheduleDestroy (const Ptr &ev) { - return GetPriv ()->ScheduleDestroy (ev); + NS_LOG_FUNCTION (ev); + return GetImpl ()->ScheduleDestroy (ev); } + EventId Simulator::Schedule (Time const &time, void (*f) (void)) { + NS_LOG_FUNCTION (time << f); return Schedule (time, MakeEvent (f)); } + EventId Simulator::ScheduleNow (void (*f) (void)) { + NS_LOG_FUNCTION (f); return ScheduleNow (MakeEvent (f)); } + EventId Simulator::ScheduleDestroy (void (*f) (void)) { + NS_LOG_FUNCTION (f); return ScheduleDestroy (MakeEvent (f)); } - void Simulator::Remove (const EventId &ev) { - return GetPriv ()->Remove (ev); + NS_LOG_FUNCTION (&ev); + return GetImpl ()->Remove (ev); } void Simulator::Cancel (const EventId &ev) { - return GetPriv ()->Cancel (ev); + NS_LOG_FUNCTION (&ev); + return GetImpl ()->Cancel (ev); } + bool Simulator::IsExpired (const EventId &id) { - return GetPriv ()->IsExpired (id); + NS_LOG_FUNCTION (&id); + return GetImpl ()->IsExpired (id); } Time Now (void) { + NS_LOG_FUNCTION_NOARGS (); return Time (Simulator::Now ()); } Time Simulator::GetMaximumSimulationTime (void) { - return GetPriv ()->GetMaximumSimulationTime (); + NS_LOG_FUNCTION_NOARGS (); + return GetImpl ()->GetMaximumSimulationTime (); } } // namespace ns3 @@ -697,25 +370,31 @@ private: SimulatorTests::SimulatorTests () : Test ("Simulator") {} + SimulatorTests::~SimulatorTests () {} + void SimulatorTests::Ref (void) const {} + void SimulatorTests::Unref (void) const {} + uint64_t SimulatorTests::NowUs (void) { uint64_t ns = Now ().GetNanoSeconds (); return ns / 1000; } + void SimulatorTests::A (int a) { m_a = false; } + void SimulatorTests::B (int b) { @@ -730,11 +409,13 @@ SimulatorTests::B (int b) Simulator::Remove (m_idC); Simulator::Schedule (MicroSeconds (10), &SimulatorTests::D, this, 4); } + void SimulatorTests::C (int c) { m_c = false; } + void SimulatorTests::D (int d) { @@ -747,6 +428,7 @@ SimulatorTests::D (int d) m_d = true; } } + void SimulatorTests::destroy (void) { @@ -755,21 +437,27 @@ SimulatorTests::destroy (void) m_destroy = true; } } + void SimulatorTests::bar0 (void) {} + void SimulatorTests::bar1 (int) {} + void SimulatorTests::bar2 (int, int) {} + void SimulatorTests::bar3 (int, int, int) {} + void SimulatorTests::bar4 (int, int, int, int) {} + void SimulatorTests::bar5 (int, int, int, int, int) {} @@ -777,15 +465,19 @@ SimulatorTests::bar5 (int, int, int, int, int) void SimulatorTests::baz1 (int &) {} + void SimulatorTests::baz2 (int &, int &) {} + void SimulatorTests::baz3 (int &, int &, int &) {} + void SimulatorTests::baz4 (int &, int &, int &, int &) {} + void SimulatorTests::baz5 (int &, int &, int &, int &, int &) {} @@ -793,15 +485,19 @@ SimulatorTests::baz5 (int &, int &, int &, int &, int &) void SimulatorTests::cbaz1 (const int &) {} + void SimulatorTests::cbaz2 (const int &, const int &) {} + void SimulatorTests::cbaz3 (const int &, const int &, const int &) {} + void SimulatorTests::cbaz4 (const int &, const int &, const int &, const int &) {} + void SimulatorTests::cbaz5 (const int &, const int &, const int &, const int &, const int &) {} @@ -809,18 +505,23 @@ SimulatorTests::cbaz5 (const int &, const int &, const int &, const int &, const void SimulatorTests::bar0c (void) const {} + void SimulatorTests::bar1c (int) const {} + void SimulatorTests::bar2c (int, int) const {} + void SimulatorTests::bar3c (int, int, int) const {} + void SimulatorTests::bar4c (int, int, int, int) const {} + void SimulatorTests::bar5c (int, int, int, int, int) const {} @@ -828,15 +529,19 @@ SimulatorTests::bar5c (int, int, int, int, int) const void SimulatorTests::baz1c (int &) const {} + void SimulatorTests::baz2c (int &, int &) const {} + void SimulatorTests::baz3c (int &, int &, int &) const {} + void SimulatorTests::baz4c (int &, int &, int &, int &) const {} + void SimulatorTests::baz5c (int &, int &, int &, int &, int &) const {} @@ -844,15 +549,19 @@ SimulatorTests::baz5c (int &, int &, int &, int &, int &) const void SimulatorTests::cbaz1c (const int &) const {} + void SimulatorTests::cbaz2c (const int &, const int &) const {} + void SimulatorTests::cbaz3c (const int &, const int &, const int &) const {} + void SimulatorTests::cbaz4c (const int &, const int &, const int &, const int &) const {} + void SimulatorTests::cbaz5c (const int &, const int &, const int &, const int &, const int &) const {} @@ -881,6 +590,7 @@ SimulatorTests::RunOneTest (void) NS_TEST_ASSERT (m_d); return result; } + void SimulatorTests::RunTestsConst (void) const { @@ -980,7 +690,6 @@ SimulatorTests::RunTests (void) } Simulator::Destroy (); - Simulator::Schedule (Seconds (0.0), &foo0); Simulator::Schedule (Seconds (0.0), &foo1, 0); Simulator::Schedule (Seconds (0.0), &foo2, 0, 0); diff --git a/src/simulator/simulator.h b/src/simulator/simulator.h index 6752b7644..5ceaf27e8 100644 --- a/src/simulator/simulator.h +++ b/src/simulator/simulator.h @@ -31,7 +31,7 @@ namespace ns3 { -class SimulatorPrivate; +class SimulatorImpl; class SchedulerFactory; /** @@ -606,8 +606,8 @@ private: typename T1, typename T2, typename T3, typename T4, typename T5> static Ptr MakeEvent (void (*f) (U1,U2,U3,U4,U5), T1 a1, T2 a2, T3 a3, T4 a4, T5 a5); - static Ptr GetPriv (void); - static Ptr m_priv; + static Ptr GetImpl (void); + static Ptr m_impl; }; /** diff --git a/src/simulator/wscript b/src/simulator/wscript index d41c5a356..9bdcef84f 100644 --- a/src/simulator/wscript +++ b/src/simulator/wscript @@ -58,6 +58,7 @@ def build(bld): 'heap-scheduler.cc', 'event-impl.cc', 'simulator.cc', + 'simulator-impl.cc', 'timer.cc', 'watchdog.cc', ] @@ -70,6 +71,7 @@ def build(bld): 'event-id.h', 'event-impl.h', 'simulator.h', + 'simulator-impl.h', 'scheduler.h', 'list-scheduler.h', 'map-scheduler.h', From ae074d9e03869921110a2d4c3b1f4804f61cfe1d Mon Sep 17 00:00:00 2001 From: "Gustavo J. A. M. Carneiro" Date: Fri, 18 Jul 2008 11:41:22 +0100 Subject: [PATCH 183/495] No need to make NetDevice::SendFrom pure virtual; instead just give a fatal error if used in runtime (it's only used by the learning bridge, anyway, so...). --- src/devices/wifi/wifi-net-device.cc | 6 ------ src/devices/wifi/wifi-net-device.h | 1 - src/node/net-device.cc | 6 ++++++ src/node/net-device.h | 2 +- 4 files changed, 7 insertions(+), 8 deletions(-) diff --git a/src/devices/wifi/wifi-net-device.cc b/src/devices/wifi/wifi-net-device.cc index 862dd8e9a..f3bcad80d 100644 --- a/src/devices/wifi/wifi-net-device.cc +++ b/src/devices/wifi/wifi-net-device.cc @@ -283,12 +283,6 @@ WifiNetDevice::Send(Ptr packet, const Address& dest, uint16_t protocolNu m_mac->Enqueue (packet, realTo); return true; } -bool -WifiNetDevice::SendFrom (Ptr packet, const Address& source, const Address& dest, uint16_t protocolNumber) -{ - NS_FATAL_ERROR ("WifiNetDevice::SendFrom not implemented."); - return false; -} Ptr WifiNetDevice::GetNode (void) const { diff --git a/src/devices/wifi/wifi-net-device.h b/src/devices/wifi/wifi-net-device.h index 81d9046b3..08867ae89 100644 --- a/src/devices/wifi/wifi-net-device.h +++ b/src/devices/wifi/wifi-net-device.h @@ -96,7 +96,6 @@ public: virtual Address MakeMulticastAddress (Ipv4Address multicastGroup) const; virtual bool IsPointToPoint (void) const; virtual bool Send(Ptr packet, const Address& dest, uint16_t protocolNumber); - virtual bool SendFrom (Ptr packet, const Address& src, const Address& dest, uint16_t protocolNumber); virtual Ptr GetNode (void) const; virtual void SetNode (Ptr node); virtual bool NeedsArp (void) const; diff --git a/src/node/net-device.cc b/src/node/net-device.cc index 92ea085ac..048fb1fe2 100644 --- a/src/node/net-device.cc +++ b/src/node/net-device.cc @@ -52,5 +52,11 @@ NetDevice::SetPromiscReceiveCallback (PromiscReceiveCallback cb) NS_ASSERT (!SupportsPromiscuous ()); } +bool +NetDevice::SendFrom (Ptr packet, const Address& source, const Address& dest, uint16_t protocolNumber) +{ + NS_FATAL_ERROR ("NetDevice::SendFrom not implemented for " << GetInstanceTypeId ().GetName ()); + return false; +} } // namespace ns3 diff --git a/src/node/net-device.h b/src/node/net-device.h index 2110dbb04..c718013c9 100644 --- a/src/node/net-device.h +++ b/src/node/net-device.h @@ -228,7 +228,7 @@ public: * * \return whether the Send operation succeeded */ - virtual bool SendFrom(Ptr packet, const Address& source, const Address& dest, uint16_t protocolNumber) = 0; + virtual bool SendFrom(Ptr packet, const Address& source, const Address& dest, uint16_t protocolNumber); /** * \returns the node base class which contains this network * interface. From a303c4bfad625117a3472c1ae60c141f5fdd33bb Mon Sep 17 00:00:00 2001 From: "Gustavo J. A. M. Carneiro" Date: Fri, 18 Jul 2008 12:12:43 +0100 Subject: [PATCH 184/495] Add release notes. --- RELEASE_NOTES | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/RELEASE_NOTES b/RELEASE_NOTES index 466a625da..05f935a45 100644 --- a/RELEASE_NOTES +++ b/RELEASE_NOTES @@ -11,6 +11,31 @@ Next Release (in ns-3-dev) - Kernel system condition support (class SystemCondition) added; - Move required methods in helper classes to constructors; - Change obsolete references to Parameter to Attribute in helpers; +- New NetDevice APIs: SendFrom and SetPromiscRxCallback; +- Add learning bridge (IEEE 802.1D) implementation: BridgeNetDevice; + + ---> API Changes in this release <--- + +In order to support the learning bridge, some API changes in Node and +NetDevice were made. + +In NetDevice, devices may optionally implement the virtual methods +SendFrom, SupportsPromiscuous, and SetPromiscReceiveCallback. If +these new methods are not implemented, the code still compiles and +works, except if they are used in a BridgeNetDevice. + +In Node, the signature for protocol handler callbacks (used in +AddProtocolHandler) has changed. Now it looks like: + + void ReceiveFromDevice (Ptr device, Ptr packet, uint16_t protocol, + Address const &source, Address const &destination, PacketType packetType); + +The extra parameters 'destination' and 'packetType' are present for +all protocol handlers, but only have valid values for promiscuous +protocol handlers. Protocol handlers are non-promiscuous by default, +so no action is needed to adapt existing code besides updating the +callback signature. + Release 3.1 (2008/06/30) ======================== From 9c8ee223b35cc81431e0fc63b59c02374476de85 Mon Sep 17 00:00:00 2001 From: Craig Dowell Date: Fri, 18 Jul 2008 21:51:31 -0700 Subject: [PATCH 185/495] make simulator implementation replaceable via global default value --- ...ator-impl.cc => default-simulator-impl.cc} | 56 ++++++------ src/simulator/default-simulator-impl.h | 90 +++++++++++++++++++ src/simulator/simulator-impl.h | 64 ++++--------- src/simulator/simulator.cc | 45 +++++++--- src/simulator/simulator.h | 65 ++++++++++++-- src/simulator/wscript | 3 +- 6 files changed, 230 insertions(+), 93 deletions(-) rename src/simulator/{simulator-impl.cc => default-simulator-impl.cc} (80%) create mode 100644 src/simulator/default-simulator-impl.h diff --git a/src/simulator/simulator-impl.cc b/src/simulator/default-simulator-impl.cc similarity index 80% rename from src/simulator/simulator-impl.cc rename to src/simulator/default-simulator-impl.cc index 0bfdc9995..fca228dd3 100644 --- a/src/simulator/simulator-impl.cc +++ b/src/simulator/default-simulator-impl.cc @@ -19,7 +19,7 @@ */ #include "simulator.h" -#include "simulator-impl.h" +#include "default-simulator-impl.h" #include "scheduler.h" #include "event-impl.h" @@ -30,23 +30,23 @@ #include -NS_LOG_COMPONENT_DEFINE ("SimulatorImpl"); +NS_LOG_COMPONENT_DEFINE ("DefaultSimulatorImpl"); namespace ns3 { -NS_OBJECT_ENSURE_REGISTERED (SimulatorImpl); +NS_OBJECT_ENSURE_REGISTERED (DefaultSimulatorImpl); TypeId -SimulatorImpl::GetTypeId (void) +DefaultSimulatorImpl::GetTypeId (void) { - static TypeId tid = TypeId ("ns3::SimulatorImpl") + static TypeId tid = TypeId ("ns3::DefaultSimulatorImpl") .SetParent () - .AddConstructor () + .AddConstructor () ; return tid; } -SimulatorImpl::SimulatorImpl () +DefaultSimulatorImpl::DefaultSimulatorImpl () { m_stop = false; m_stopAt = 0; @@ -62,7 +62,7 @@ SimulatorImpl::SimulatorImpl () m_unscheduledEvents = 0; } -SimulatorImpl::~SimulatorImpl () +DefaultSimulatorImpl::~DefaultSimulatorImpl () { while (!m_events->IsEmpty ()) { @@ -72,7 +72,7 @@ SimulatorImpl::~SimulatorImpl () } void -SimulatorImpl::Destroy () +DefaultSimulatorImpl::Destroy () { while (!m_destroyEvents.empty ()) { @@ -87,7 +87,7 @@ SimulatorImpl::Destroy () } void -SimulatorImpl::SetScheduler (Ptr scheduler) +DefaultSimulatorImpl::SetScheduler (Ptr scheduler) { if (m_events != 0) { @@ -101,20 +101,20 @@ SimulatorImpl::SetScheduler (Ptr scheduler) } Ptr -SimulatorImpl::GetScheduler (void) const +DefaultSimulatorImpl::GetScheduler (void) const { return m_events; } void -SimulatorImpl::EnableLogTo (char const *filename) +DefaultSimulatorImpl::EnableLogTo (char const *filename) { m_log.open (filename); m_logEnable = true; } void -SimulatorImpl::ProcessOneEvent (void) +DefaultSimulatorImpl::ProcessOneEvent (void) { EventId next = m_events->RemoveNext (); @@ -133,13 +133,13 @@ SimulatorImpl::ProcessOneEvent (void) } bool -SimulatorImpl::IsFinished (void) const +DefaultSimulatorImpl::IsFinished (void) const { return m_events->IsEmpty (); } uint64_t -SimulatorImpl::NextTs (void) const +DefaultSimulatorImpl::NextTs (void) const { NS_ASSERT (!m_events->IsEmpty ()); EventId id = m_events->PeekNext (); @@ -147,13 +147,13 @@ SimulatorImpl::NextTs (void) const } Time -SimulatorImpl::Next (void) const +DefaultSimulatorImpl::Next (void) const { return TimeStep (NextTs ()); } void -SimulatorImpl::Run (void) +DefaultSimulatorImpl::Run (void) { while (!m_events->IsEmpty () && !m_stop && @@ -170,13 +170,13 @@ SimulatorImpl::Run (void) } void -SimulatorImpl::Stop (void) +DefaultSimulatorImpl::Stop (void) { m_stop = true; } void -SimulatorImpl::Stop (Time const &time) +DefaultSimulatorImpl::Stop (Time const &time) { NS_ASSERT (time.IsPositive ()); Time absolute = Simulator::Now () + time; @@ -184,7 +184,7 @@ SimulatorImpl::Stop (Time const &time) } EventId -SimulatorImpl::Schedule (Time const &time, const Ptr &event) +DefaultSimulatorImpl::Schedule (Time const &time, const Ptr &event) { NS_ASSERT (time.IsPositive ()); NS_ASSERT (time >= TimeStep (m_currentTs)); @@ -202,7 +202,7 @@ SimulatorImpl::Schedule (Time const &time, const Ptr &event) } EventId -SimulatorImpl::ScheduleNow (const Ptr &event) +DefaultSimulatorImpl::ScheduleNow (const Ptr &event) { EventId id (event, m_currentTs, m_uid); if (m_logEnable) @@ -217,7 +217,7 @@ SimulatorImpl::ScheduleNow (const Ptr &event) } EventId -SimulatorImpl::ScheduleDestroy (const Ptr &event) +DefaultSimulatorImpl::ScheduleDestroy (const Ptr &event) { EventId id (event, m_currentTs, 2); m_destroyEvents.push_back (id); @@ -231,13 +231,13 @@ SimulatorImpl::ScheduleDestroy (const Ptr &event) } Time -SimulatorImpl::Now (void) const +DefaultSimulatorImpl::Now (void) const { return TimeStep (m_currentTs); } Time -SimulatorImpl::GetDelayLeft (const EventId &id) const +DefaultSimulatorImpl::GetDelayLeft (const EventId &id) const { if (IsExpired (id)) { @@ -250,7 +250,7 @@ SimulatorImpl::GetDelayLeft (const EventId &id) const } void -SimulatorImpl::Remove (const EventId &ev) +DefaultSimulatorImpl::Remove (const EventId &ev) { if (ev.GetUid () == 2) { @@ -281,7 +281,7 @@ SimulatorImpl::Remove (const EventId &ev) } void -SimulatorImpl::Cancel (const EventId &id) +DefaultSimulatorImpl::Cancel (const EventId &id) { if (!IsExpired (id)) { @@ -290,7 +290,7 @@ SimulatorImpl::Cancel (const EventId &id) } bool -SimulatorImpl::IsExpired (const EventId &ev) const +DefaultSimulatorImpl::IsExpired (const EventId &ev) const { if (ev.GetUid () == 2) { @@ -319,7 +319,7 @@ SimulatorImpl::IsExpired (const EventId &ev) const } Time -SimulatorImpl::GetMaximumSimulationTime (void) const +DefaultSimulatorImpl::GetMaximumSimulationTime (void) const { // XXX: I am fairly certain other compilers use other non-standard // post-fixes to indicate 64 bit constants. diff --git a/src/simulator/default-simulator-impl.h b/src/simulator/default-simulator-impl.h new file mode 100644 index 000000000..a3c321018 --- /dev/null +++ b/src/simulator/default-simulator-impl.h @@ -0,0 +1,90 @@ +/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ +/* + * Copyright (c) 2005,2006 INRIA + * + * 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 + * + * Author: Mathieu Lacage + */ + +#ifndef DEFAULT_SIMULATOR_IMPL_H +#define DEFAULT_SIMULATOR_IMPL_H + +#include "simulator-impl.h" + +#include "scheduler.h" +#include "event-impl.h" + +#include "ns3/ptr.h" +#include "ns3/assert.h" +#include "ns3/log.h" + +#include +#include + +namespace ns3 { + + class DefaultSimulatorImpl : public SimulatorImpl +{ +public: + static TypeId GetTypeId (void); + + DefaultSimulatorImpl (); + ~DefaultSimulatorImpl (); + + void Destroy (); + + void EnableLogTo (char const *filename); + + bool IsFinished (void) const; + Time Next (void) const; + void Stop (void); + void Stop (Time const &time); + EventId Schedule (Time const &time, const Ptr &event); + EventId ScheduleNow (const Ptr &event); + EventId ScheduleDestroy (const Ptr &event); + void Remove (const EventId &ev); + void Cancel (const EventId &ev); + bool IsExpired (const EventId &ev) const; + void Run (void); + Time Now (void) const; + Time GetDelayLeft (const EventId &id) const; + Time GetMaximumSimulationTime (void) const; + + void SetScheduler (Ptr scheduler); + Ptr GetScheduler (void) const; + +private: + void ProcessOneEvent (void); + uint64_t NextTs (void) const; + + typedef std::list DestroyEvents; + DestroyEvents m_destroyEvents; + uint64_t m_stopAt; + bool m_stop; + Ptr m_events; + uint32_t m_uid; + uint32_t m_currentUid; + uint64_t m_currentTs; + std::ofstream m_log; + std::ifstream m_inputLog; + bool m_logEnable; + // number of events that have been inserted but not yet scheduled, + // not counting the "destroy" events; this is used for validation + int m_unscheduledEvents; +}; + +} // namespace ns3 + +#endif /* DEFAULT_SIMULATOR_IMPL_H */ diff --git a/src/simulator/simulator-impl.h b/src/simulator/simulator-impl.h index f72a71952..86b871d58 100644 --- a/src/simulator/simulator-impl.h +++ b/src/simulator/simulator-impl.h @@ -23,6 +23,7 @@ #include "scheduler.h" #include "event-impl.h" +#include "nstime.h" #include "ns3/ptr.h" #include "ns3/assert.h" @@ -36,51 +37,24 @@ namespace ns3 { class SimulatorImpl : public Object { public: - static TypeId GetTypeId (void); - - SimulatorImpl (); - ~SimulatorImpl (); - - void Destroy (); - - void EnableLogTo (char const *filename); - - bool IsFinished (void) const; - Time Next (void) const; - void Stop (void); - void Stop (Time const &time); - EventId Schedule (Time const &time, const Ptr &event); - EventId ScheduleNow (const Ptr &event); - EventId ScheduleDestroy (const Ptr &event); - void Remove (const EventId &ev); - void Cancel (const EventId &ev); - bool IsExpired (const EventId &ev) const; - void Run (void); - Time Now (void) const; - Time GetDelayLeft (const EventId &id) const; - Time GetMaximumSimulationTime (void) const; - - void SetScheduler (Ptr scheduler); - Ptr GetScheduler (void) const; - -private: - void ProcessOneEvent (void); - uint64_t NextTs (void) const; - - typedef std::list DestroyEvents; - DestroyEvents m_destroyEvents; - uint64_t m_stopAt; - bool m_stop; - Ptr m_events; - uint32_t m_uid; - uint32_t m_currentUid; - uint64_t m_currentTs; - std::ofstream m_log; - std::ifstream m_inputLog; - bool m_logEnable; - // number of events that have been inserted but not yet scheduled, - // not counting the "destroy" events; this is used for validation - int m_unscheduledEvents; + virtual void Destroy () = 0; + virtual void EnableLogTo (char const *filename) = 0; + virtual bool IsFinished (void) const = 0; + virtual Time Next (void) const = 0; + virtual void Stop (void) = 0; + virtual void Stop (Time const &time) = 0; + virtual EventId Schedule (Time const &time, const Ptr &event) = 0; + virtual EventId ScheduleNow (const Ptr &event) = 0; + virtual EventId ScheduleDestroy (const Ptr &event) = 0; + virtual void Remove (const EventId &ev) = 0; + virtual void Cancel (const EventId &ev) = 0; + virtual bool IsExpired (const EventId &ev) const = 0; + virtual void Run (void) = 0; + virtual Time Now (void) const = 0; + virtual Time GetDelayLeft (const EventId &id) const = 0; + virtual Time GetMaximumSimulationTime (void) const = 0; + virtual void SetScheduler (Ptr scheduler) = 0; + virtual Ptr GetScheduler (void) const = 0; }; } // namespace ns3 diff --git a/src/simulator/simulator.cc b/src/simulator/simulator.cc index 7d20ec4d9..2abaf218a 100644 --- a/src/simulator/simulator.cc +++ b/src/simulator/simulator.cc @@ -20,12 +20,15 @@ #include "simulator.h" #include "simulator-impl.h" +#include "default-simulator-impl.h" #include "scheduler.h" #include "map-scheduler.h" #include "event-impl.h" #include "ns3/ptr.h" -#include "ns3/pointer.h" +#include "ns3/string.h" +#include "ns3/object-factory.h" +#include "ns3/global-value.h" #include "ns3/assert.h" #include "ns3/log.h" @@ -39,38 +42,56 @@ NS_LOG_COMPONENT_DEFINE ("Simulator"); namespace ns3 { +GlobalValue g_simTypeImpl = GlobalValue ("SimulatorImplementationType", + "The object class to use as the simulator implementation", + StringValue ("ns3::DefaultSimulatorImpl"), + MakeStringChecker ()); + +Ptr Simulator::m_impl = 0; + #ifdef NS3_LOG_ENABLE + +// +// Note: Calls that take TimePrinter as a parameter are defined as nothing +// in the logging module if NS3_LOG_ENABLE is not defined. +// + static void TimePrinter (std::ostream &os) { os << Simulator::Now (); } + #endif /* NS3_LOG_ENABLE */ -Ptr Simulator::m_impl = 0; - -Ptr +SimulatorImpl * Simulator::GetImpl (void) { NS_LOG_FUNCTION_NOARGS (); if (m_impl == 0) { - /* Note: we call LogSetTimePrinter below _after_ calling CreateObject - * because CreateObject can trigger calls to the logging framework which - * would call the TimePrinter function above which would call - * Simulator::Now which would call Simulator::GetImpl, and, thus, get - * us in an infinite recursion until the stack explodes. - */ - m_impl = CreateObject (); + ObjectFactory factory; + StringValue s; + + g_simTypeImpl.GetValue (s); + factory.SetTypeId (s.Get ()); + m_impl = factory.Create (); Ptr scheduler = CreateObject (); m_impl->SetScheduler (scheduler); +// +// Note: we call LogSetTimePrinter _after_ creating the implementation +// object because the act of creation can trigger calls to the logging +// framework which would call the TimePrinter function which would call +// Simulator::Now which would call Simulator::GetImpl, and, thus, get us +// in an infinite recursion until the stack explodes. +// LogSetTimePrinter (&TimePrinter); } NS_LOG_LOGIC ("priv " << m_impl); - return m_impl; + return PeekPointer (m_impl); } void diff --git a/src/simulator/simulator.h b/src/simulator/simulator.h index 5ceaf27e8..8b833dede 100644 --- a/src/simulator/simulator.h +++ b/src/simulator/simulator.h @@ -21,18 +21,19 @@ #ifndef SIMULATOR_H #define SIMULATOR_H -#include #include "event-id.h" #include "event-impl.h" #include "nstime.h" #include "scheduler.h" + #include "ns3/type-traits.h" +#include +#include + namespace ns3 { - class SimulatorImpl; -class SchedulerFactory; /** * \ingroup simulator @@ -55,6 +56,20 @@ class SchedulerFactory; class Simulator { public: + /** + * \param impl a new simulator implementation + * + * The simulator provides a mechanism to swap out different implementations. + * For example, the default implementation is a single-threaded simulator + * that performs no realtime synchronization. By calling this method, you + * can substitute in a new simulator implementation that might be multi- + * threaded and synchronize events to a realtime clock. + * + * The simulator implementation can be set when the simulator is not + * running. + */ + static void SetImplementation (Ptr impl); + /** * \param scheduler a new event scheduler * @@ -91,7 +106,6 @@ public: */ static void Destroy (void); - /** * If there any any events lefts to be scheduled, return * true. Return false otherwise. @@ -113,12 +127,14 @@ public: * is greater than or equal to the stop time. */ static void Run (void); + /** * If an event invokes this method, it will be the last * event scheduled by the Simulator::run method before * returning to the caller. */ static void Stop (void); + /** * Force the Simulator::run method to return to the caller when the * expiration time of the next event to be processed is greater than @@ -140,6 +156,7 @@ public: */ template static EventId Schedule (Time const &time, MEM mem_ptr, OBJ obj); + /** * @param time the relative expiration time of the event. * @param mem_ptr member method pointer to invoke @@ -149,6 +166,7 @@ public: */ template static EventId Schedule (Time const &time, MEM mem_ptr, OBJ obj, T1 a1); + /** * @param time the relative expiration time of the event. * @param mem_ptr member method pointer to invoke @@ -159,6 +177,7 @@ public: */ template static EventId Schedule (Time const &time, MEM mem_ptr, OBJ obj, T1 a1, T2 a2); + /** * @param time the relative expiration time of the event. * @param mem_ptr member method pointer to invoke @@ -171,6 +190,7 @@ public: template static EventId Schedule (Time const &time, MEM mem_ptr, OBJ obj, T1 a1, T2 a2, T3 a3); + /** * @param time the relative expiration time of the event. * @param mem_ptr member method pointer to invoke @@ -184,6 +204,7 @@ public: template static EventId Schedule (Time const &time, MEM mem_ptr, OBJ obj, T1 a1, T2 a2, T3 a3, T4 a4); + /** * @param time the relative expiration time of the event. * @param mem_ptr member method pointer to invoke @@ -205,6 +226,7 @@ public: * @returns an id for the scheduled event. */ static EventId Schedule (Time const &time, void (*f) (void)); + /** * @param time the relative expiration time of the event. * @param f the function to invoke @@ -213,6 +235,7 @@ public: */ template static EventId Schedule (Time const &time, void (*f) (U1), T1 a1); + /** * @param time the relative expiration time of the event. * @param f the function to invoke @@ -222,6 +245,7 @@ public: */ template static EventId Schedule (Time const &time, void (*f) (U1,U2), T1 a1, T2 a2); + /** * @param time the relative expiration time of the event. * @param f the function to invoke @@ -232,6 +256,7 @@ public: */ template static EventId Schedule (Time const &time, void (*f) (U1,U2,U3), T1 a1, T2 a2, T3 a3); + /** * @param time the relative expiration time of the event. * @param f the function to invoke @@ -244,6 +269,7 @@ public: template static EventId Schedule (Time const &time, void (*f) (U1,U2,U3,U4), T1 a1, T2 a2, T3 a3, T4 a4); + /** * @param time the relative expiration time of the event. * @param f the function to invoke @@ -258,7 +284,6 @@ public: typename T1, typename T2, typename T3, typename T4, typename T5> static EventId Schedule (Time const &time, void (*f) (U1,U2,U3,U4,U5), T1 a1, T2 a2, T3 a3, T4 a4, T5 a5); - /** * Schedule an event to expire Now. All events scheduled to * to expire "Now" are scheduled FIFO, after all normal events @@ -269,6 +294,7 @@ public: */ template static EventId ScheduleNow (MEM mem_ptr, OBJ obj); + /** * @param mem_ptr member method pointer to invoke * @param obj the object on which to invoke the member method @@ -277,6 +303,7 @@ public: template static EventId ScheduleNow (MEM mem_ptr, OBJ obj, T1 a1); + /** * @param mem_ptr member method pointer to invoke * @param obj the object on which to invoke the member method @@ -286,6 +313,7 @@ public: template static EventId ScheduleNow (MEM mem_ptr, OBJ obj, T1 a1, T2 a2); + /** * @param mem_ptr member method pointer to invoke * @param obj the object on which to invoke the member method @@ -296,6 +324,7 @@ public: template static EventId ScheduleNow (MEM mem_ptr, OBJ obj, T1 a1, T2 a2, T3 a3); + /** * @param mem_ptr member method pointer to invoke * @param obj the object on which to invoke the member method @@ -325,6 +354,7 @@ public: * @param f the function to invoke */ static EventId ScheduleNow (void (*f) (void)); + /** * @param f the function to invoke * @param a1 the first argument to pass to the function to invoke @@ -332,6 +362,7 @@ public: template static EventId ScheduleNow (void (*f) (U1), T1 a1); + /** * @param f the function to invoke * @param a1 the first argument to pass to the function to invoke @@ -340,6 +371,7 @@ public: template static EventId ScheduleNow (void (*f) (U1,U2), T1 a1, T2 a2); + /** * @param f the function to invoke * @param a1 the first argument to pass to the function to invoke @@ -349,6 +381,7 @@ public: template static EventId ScheduleNow (void (*f) (U1,U2,U3), T1 a1, T2 a2, T3 a3); + /** * @param f the function to invoke * @param a1 the first argument to pass to the function to invoke @@ -359,6 +392,7 @@ public: template static EventId ScheduleNow (void (*f) (U1,U2,U3,U4), T1 a1, T2 a2, T3 a3, T4 a4); + /** * @param f the function to invoke * @param a1 the first argument to pass to the function to invoke @@ -371,7 +405,6 @@ public: typename T1, typename T2, typename T3, typename T4, typename T5> static EventId ScheduleNow (void (*f) (U1,U2,U3,U4,U5), T1 a1, T2 a2, T3 a3, T4 a4, T5 a5); - /** * Schedule an event to expire at Destroy time. All events * scheduled to expire at "Destroy" time are scheduled FIFO, @@ -383,6 +416,7 @@ public: */ template static EventId ScheduleDestroy (MEM mem_ptr, OBJ obj); + /** * @param mem_ptr member method pointer to invoke * @param obj the object on which to invoke the member method @@ -391,6 +425,7 @@ public: template static EventId ScheduleDestroy (MEM mem_ptr, OBJ obj, T1 a1); + /** * @param mem_ptr member method pointer to invoke * @param obj the object on which to invoke the member method @@ -400,6 +435,7 @@ public: template static EventId ScheduleDestroy (MEM mem_ptr, OBJ obj, T1 a1, T2 a2); + /** * @param mem_ptr member method pointer to invoke * @param obj the object on which to invoke the member method @@ -410,6 +446,7 @@ public: template static EventId ScheduleDestroy (MEM mem_ptr, OBJ obj, T1 a1, T2 a2, T3 a3); + /** * @param mem_ptr member method pointer to invoke * @param obj the object on which to invoke the member method @@ -439,6 +476,7 @@ public: * @param f the function to invoke */ static EventId ScheduleDestroy (void (*f) (void)); + /** * @param f the function to invoke * @param a1 the first argument to pass to the function to invoke @@ -446,6 +484,7 @@ public: template static EventId ScheduleDestroy (void (*f) (U1), T1 a1); + /** * @param f the function to invoke * @param a1 the first argument to pass to the function to invoke @@ -454,6 +493,7 @@ public: template static EventId ScheduleDestroy (void (*f) (U1,U2), T1 a1, T2 a2); + /** * @param f the function to invoke * @param a1 the first argument to pass to the function to invoke @@ -463,6 +503,7 @@ public: template static EventId ScheduleDestroy (void (*f) (U1,U2,U3), T1 a1, T2 a2, T3 a3); + /** * @param f the function to invoke * @param a1 the first argument to pass to the function to invoke @@ -473,6 +514,7 @@ public: template static EventId ScheduleDestroy (void (*f) (U1,U2,U3,U4), T1 a1, T2 a2, T3 a3, T4 a4); + /** * @param f the function to invoke * @param a1 the first argument to pass to the function to invoke @@ -497,6 +539,7 @@ public: * @param id the event to remove from the list of scheduled events. */ static void Remove (const EventId &id); + /** * Set the cancel bit on this event: the event's associated function * will not be invoked when it expires. @@ -510,6 +553,7 @@ public: * @param id the event to cancel */ static void Cancel (const EventId &id); + /** * This method has O(1) complexity. * Note that it is not possible to test for the expiration of @@ -523,10 +567,12 @@ public: * @returns true if the event has expired, false otherwise. */ static bool IsExpired (const EventId &id); + /** * Return the "current simulation time". */ static Time Now (void); + /** * \param id the event id to analyse * \returns the delay left until the input event id expires. @@ -542,6 +588,7 @@ public: * The returned value will always be bigger than or equal to Simulator::Now. */ static Time GetMaximumSimulationTime (void); + /** * \param time delay until the event expires * \param event the event to schedule @@ -551,6 +598,7 @@ public: * to delegate events to their own subclass of the EventImpl base class. */ static EventId Schedule (Time const &time, const Ptr &event); + /** * \param event the event to schedule * \returns a unique identifier for the newly-scheduled event. @@ -559,6 +607,7 @@ public: * to delegate events to their own subclass of the EventImpl base class. */ static EventId ScheduleDestroy (const Ptr &event); + /** * \param event the event to schedule * \returns a unique identifier for the newly-scheduled event. @@ -606,8 +655,10 @@ private: typename T1, typename T2, typename T3, typename T4, typename T5> static Ptr MakeEvent (void (*f) (U1,U2,U3,U4,U5), T1 a1, T2 a2, T3 a3, T4 a4, T5 a5); - static Ptr GetImpl (void); + static SimulatorImpl *GetImpl (void); static Ptr m_impl; + static std::string m_typeImpl; + static std::string m_typeSched; }; /** diff --git a/src/simulator/wscript b/src/simulator/wscript index 9bdcef84f..1b4d92003 100644 --- a/src/simulator/wscript +++ b/src/simulator/wscript @@ -58,7 +58,7 @@ def build(bld): 'heap-scheduler.cc', 'event-impl.cc', 'simulator.cc', - 'simulator-impl.cc', + 'default-simulator-impl.cc', 'timer.cc', 'watchdog.cc', ] @@ -72,6 +72,7 @@ def build(bld): 'event-impl.h', 'simulator.h', 'simulator-impl.h', + 'default-simulator-impl.h', 'scheduler.h', 'list-scheduler.h', 'map-scheduler.h', From 44c48d41e3de8fce1324ce351caed6ebbfa1e855 Mon Sep 17 00:00:00 2001 From: Craig Dowell Date: Fri, 18 Jul 2008 21:59:43 -0700 Subject: [PATCH 186/495] update on-demand RELEASE_NOTES --- RELEASE_NOTES | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/RELEASE_NOTES b/RELEASE_NOTES index 466a625da..dbb443c47 100644 --- a/RELEASE_NOTES +++ b/RELEASE_NOTES @@ -11,6 +11,10 @@ Next Release (in ns-3-dev) - Kernel system condition support (class SystemCondition) added; - Move required methods in helper classes to constructors; - Change obsolete references to Parameter to Attribute in helpers; +- Split simulator into interface and implementation pieces, make + implementation a replaceable component via the + "SimulatorImplementationType" global value. + Hint: try ./waf --run "udp-echo --PrintGlobals" Release 3.1 (2008/06/30) ======================== From d711e853d09011180c54c92534804549713ccf7c Mon Sep 17 00:00:00 2001 From: Tom Henderson Date: Sun, 20 Jul 2008 07:59:21 -0700 Subject: [PATCH 187/495] more details for 3.2 release notes --- RELEASE_NOTES | 36 ++++++++++++++++++++++++++---------- 1 file changed, 26 insertions(+), 10 deletions(-) diff --git a/RELEASE_NOTES b/RELEASE_NOTES index 05f935a45..f940d5491 100644 --- a/RELEASE_NOTES +++ b/RELEASE_NOTES @@ -3,18 +3,34 @@ This file contains ns-3 release notes (most recent releases first). -Next Release (in ns-3-dev) -========================== +Release 3.2 (pending) +===================== + +New functionality added +----------------------- +- Add learning bridge (IEEE 802.1D) implementation: BridgeNetDevice; +- Python bindings added - Kernel thread support (class SystemThread) added; - Kernel mutual exclusion support (class SystemMutex) added; - Kernel critical section RAII support (class CriticalSection) added; - Kernel system condition support (class SystemCondition) added; -- Move required methods in helper classes to constructors; -- Change obsolete references to Parameter to Attribute in helpers; -- New NetDevice APIs: SendFrom and SetPromiscRxCallback; -- Add learning bridge (IEEE 802.1D) implementation: BridgeNetDevice; +- implement Packet::PeekHeader and Packet::PeekTrailer to avoid evil workarounds when receiving tcp packets. - ---> API Changes in this release <--- +Bugs fixed +---------- +- add optional support for TCP and UDP checksum (bug 236) +- close socket upon PacketSink::StopApplication (bug 243) +- fix build failure with gcc 4.3.x (bug 245) + +API changes from 3.1 to 3.2 +--------------------------- +- several helper APIs related to attribute setting (changeset d5f8e5fae1c6, + bug 234); old variants are currently deprecated API and will be removed + in a future release +- remove references to Parameter in helper APIs (changeset 3cdd9d60f7c7, + bug 232); old variants are currently deprecated API and will be removed + in a future release +- New NetDevice APIs: SendFrom and SetPromiscRxCallback; In order to support the learning bridge, some API changes in Node and NetDevice were made. @@ -27,8 +43,9 @@ works, except if they are used in a BridgeNetDevice. In Node, the signature for protocol handler callbacks (used in AddProtocolHandler) has changed. Now it looks like: - void ReceiveFromDevice (Ptr device, Ptr packet, uint16_t protocol, - Address const &source, Address const &destination, PacketType packetType); + void ReceiveFromDevice (Ptr device, Ptr packet, + uint16_t protocol, Address const &source, Address const &destination, + PacketType packetType); The extra parameters 'destination' and 'packetType' are present for all protocol handlers, but only have valid values for promiscuous @@ -36,7 +53,6 @@ protocol handlers. Protocol handlers are non-promiscuous by default, so no action is needed to adapt existing code besides updating the callback signature. - Release 3.1 (2008/06/30) ======================== From fd2cf07d30296a5e3443a7f2bdc15003a3e380cc Mon Sep 17 00:00:00 2001 From: "Gustavo J. A. M. Carneiro" Date: Mon, 21 Jul 2008 11:43:05 +0100 Subject: [PATCH 188/495] python scanning: remove redundant incref/decref_method annotations --- bindings/python/ns3modulescan.py | 4 ---- 1 file changed, 4 deletions(-) diff --git a/bindings/python/ns3modulescan.py b/bindings/python/ns3modulescan.py index 978069b2b..3a460d953 100644 --- a/bindings/python/ns3modulescan.py +++ b/bindings/python/ns3modulescan.py @@ -52,14 +52,10 @@ type_annotations = { 'ignore': None, }, '::ns3::AttributeChecker': { - 'incref_method': 'Ref', - 'decref_method': 'Unref', 'automatic_type_narrowing': 'true', 'allow_subclassing': 'false', }, '::ns3::AttributeValue': { - 'incref_method': 'Ref', - 'decref_method': 'Unref', 'automatic_type_narrowing': 'true', 'allow_subclassing': 'false', }, From f890b8e13803be96d45ee9625cb448c92ba9d9d8 Mon Sep 17 00:00:00 2001 From: "Gustavo J. A. M. Carneiro" Date: Mon, 21 Jul 2008 15:30:15 +0100 Subject: [PATCH 189/495] Python: new pybindgen, rescan API definitions, new API definition files are more multi-line and hopefully easier to read --- bindings/python/ns3_module_bridge.py | 184 +- bindings/python/ns3_module_common.py | 761 ++++-- bindings/python/ns3_module_contrib.py | 85 +- bindings/python/ns3_module_core.py | 1580 +++++++++---- bindings/python/ns3_module_csma.py | 305 ++- bindings/python/ns3_module_global_routing.py | 180 +- bindings/python/ns3_module_helper.py | 486 +++- bindings/python/ns3_module_internet_stack.py | 536 ++++- bindings/python/ns3_module_mobility.py | 482 +++- bindings/python/ns3_module_node.py | 2181 ++++++++++++++---- bindings/python/ns3_module_olsr.py | 299 ++- bindings/python/ns3_module_onoff.py | 28 +- bindings/python/ns3_module_packet_sink.py | 24 +- bindings/python/ns3_module_point_to_point.py | 182 +- bindings/python/ns3_module_simulator.py | 587 +++-- bindings/python/ns3_module_udp_echo.py | 50 +- bindings/python/ns3_module_wifi.py | 2006 ++++++++++++---- bindings/python/ns3modulegen_generated.py | 3 +- bindings/python/wscript | 2 +- 19 files changed, 7622 insertions(+), 2339 deletions(-) diff --git a/bindings/python/ns3_module_bridge.py b/bindings/python/ns3_module_bridge.py index 72822a316..932595ea3 100644 --- a/bindings/python/ns3_module_bridge.py +++ b/bindings/python/ns3_module_bridge.py @@ -1,4 +1,4 @@ -from pybindgen import Module, FileCodeSink, write_preamble, param, retval +from pybindgen import Module, FileCodeSink, param, retval, cppclass def register_types(module): root_module = module.get_root() @@ -55,84 +55,190 @@ def register_methods(root_module): def register_Ns3BridgeNetDevice_methods(root_module, cls): ## bridge-net-device.h: static ns3::TypeId ns3::BridgeNetDevice::GetTypeId() [member function] - cls.add_method('GetTypeId', 'ns3::TypeId', [], is_static=True) + cls.add_method('GetTypeId', + 'ns3::TypeId', + [], + is_static=True) ## bridge-net-device.h: ns3::BridgeNetDevice::BridgeNetDevice() [constructor] - cls.add_constructor([], visibility='public') + cls.add_constructor([]) ## bridge-net-device.h: void ns3::BridgeNetDevice::AddBridgePort(ns3::Ptr bridgePort) [member function] - cls.add_method('AddBridgePort', 'void', [param('ns3::Ptr< ns3::NetDevice >', 'bridgePort')]) + cls.add_method('AddBridgePort', + 'void', + [param('ns3::Ptr< ns3::NetDevice >', 'bridgePort')]) ## bridge-net-device.h: void ns3::BridgeNetDevice::SetName(std::string const name) [member function] - cls.add_method('SetName', 'void', [param('std::string', 'name', is_const=True)], is_virtual=True) + cls.add_method('SetName', + 'void', + [param('std::string', 'name', is_const=True)], + is_virtual=True) ## bridge-net-device.h: std::string ns3::BridgeNetDevice::GetName() const [member function] - cls.add_method('GetName', 'std::string', [], is_const=True, is_virtual=True) + cls.add_method('GetName', + 'std::string', + [], + is_const=True, is_virtual=True) ## bridge-net-device.h: void ns3::BridgeNetDevice::SetIfIndex(uint32_t const index) [member function] - cls.add_method('SetIfIndex', 'void', [param('uint32_t', 'index', is_const=True)], is_virtual=True) + cls.add_method('SetIfIndex', + 'void', + [param('uint32_t', 'index', is_const=True)], + is_virtual=True) ## bridge-net-device.h: uint32_t ns3::BridgeNetDevice::GetIfIndex() const [member function] - cls.add_method('GetIfIndex', 'uint32_t', [], is_const=True, is_virtual=True) + cls.add_method('GetIfIndex', + 'uint32_t', + [], + is_const=True, is_virtual=True) ## bridge-net-device.h: ns3::Ptr ns3::BridgeNetDevice::GetChannel() const [member function] - cls.add_method('GetChannel', 'ns3::Ptr< ns3::Channel >', [], is_const=True, is_virtual=True) + cls.add_method('GetChannel', + 'ns3::Ptr< ns3::Channel >', + [], + is_const=True, is_virtual=True) ## bridge-net-device.h: ns3::Address ns3::BridgeNetDevice::GetAddress() const [member function] - cls.add_method('GetAddress', 'ns3::Address', [], is_const=True, is_virtual=True) + cls.add_method('GetAddress', + 'ns3::Address', + [], + is_const=True, is_virtual=True) ## bridge-net-device.h: bool ns3::BridgeNetDevice::SetMtu(uint16_t const mtu) [member function] - cls.add_method('SetMtu', 'bool', [param('uint16_t', 'mtu', is_const=True)], is_virtual=True) + cls.add_method('SetMtu', + 'bool', + [param('uint16_t', 'mtu', is_const=True)], + is_virtual=True) ## bridge-net-device.h: uint16_t ns3::BridgeNetDevice::GetMtu() const [member function] - cls.add_method('GetMtu', 'uint16_t', [], is_const=True, is_virtual=True) + cls.add_method('GetMtu', + 'uint16_t', + [], + is_const=True, is_virtual=True) ## bridge-net-device.h: bool ns3::BridgeNetDevice::IsLinkUp() const [member function] - cls.add_method('IsLinkUp', 'bool', [], is_const=True, is_virtual=True) + cls.add_method('IsLinkUp', + 'bool', + [], + is_const=True, is_virtual=True) ## bridge-net-device.h: void ns3::BridgeNetDevice::SetLinkChangeCallback(ns3::Callback callback) [member function] - cls.add_method('SetLinkChangeCallback', 'void', [param('ns3::Callback< void, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty >', 'callback')], is_virtual=True) + cls.add_method('SetLinkChangeCallback', + 'void', + [param('ns3::Callback< void, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty >', 'callback')], + is_virtual=True) ## bridge-net-device.h: bool ns3::BridgeNetDevice::IsBroadcast() const [member function] - cls.add_method('IsBroadcast', 'bool', [], is_const=True, is_virtual=True) + cls.add_method('IsBroadcast', + 'bool', + [], + is_const=True, is_virtual=True) ## bridge-net-device.h: ns3::Address ns3::BridgeNetDevice::GetBroadcast() const [member function] - cls.add_method('GetBroadcast', 'ns3::Address', [], is_const=True, is_virtual=True) + cls.add_method('GetBroadcast', + 'ns3::Address', + [], + is_const=True, is_virtual=True) ## bridge-net-device.h: bool ns3::BridgeNetDevice::IsMulticast() const [member function] - cls.add_method('IsMulticast', 'bool', [], is_const=True, is_virtual=True) + cls.add_method('IsMulticast', + 'bool', + [], + is_const=True, is_virtual=True) ## bridge-net-device.h: ns3::Address ns3::BridgeNetDevice::GetMulticast() const [member function] - cls.add_method('GetMulticast', 'ns3::Address', [], is_const=True, is_virtual=True) + cls.add_method('GetMulticast', + 'ns3::Address', + [], + is_const=True, is_virtual=True) ## bridge-net-device.h: ns3::Address ns3::BridgeNetDevice::MakeMulticastAddress(ns3::Ipv4Address multicastGroup) const [member function] - cls.add_method('MakeMulticastAddress', 'ns3::Address', [param('ns3::Ipv4Address', 'multicastGroup')], is_const=True, is_virtual=True) + cls.add_method('MakeMulticastAddress', + 'ns3::Address', + [param('ns3::Ipv4Address', 'multicastGroup')], + is_const=True, is_virtual=True) ## bridge-net-device.h: bool ns3::BridgeNetDevice::IsPointToPoint() const [member function] - cls.add_method('IsPointToPoint', 'bool', [], is_const=True, is_virtual=True) + cls.add_method('IsPointToPoint', + 'bool', + [], + is_const=True, is_virtual=True) ## bridge-net-device.h: bool ns3::BridgeNetDevice::Send(ns3::Ptr packet, ns3::Address const & dest, uint16_t protocolNumber) [member function] - cls.add_method('Send', 'bool', [param('ns3::Ptr< ns3::Packet >', 'packet'), param('ns3::Address&', 'dest', is_const=True), param('uint16_t', 'protocolNumber')], is_virtual=True) + cls.add_method('Send', + 'bool', + [param('ns3::Ptr< ns3::Packet >', 'packet'), param('ns3::Address&', 'dest', is_const=True), param('uint16_t', 'protocolNumber')], + is_virtual=True) ## bridge-net-device.h: bool ns3::BridgeNetDevice::SendFrom(ns3::Ptr packet, ns3::Address const & source, ns3::Address const & dest, uint16_t protocolNumber) [member function] - cls.add_method('SendFrom', 'bool', [param('ns3::Ptr< ns3::Packet >', 'packet'), param('ns3::Address&', 'source', is_const=True), param('ns3::Address&', 'dest', is_const=True), param('uint16_t', 'protocolNumber')], is_virtual=True) + cls.add_method('SendFrom', + 'bool', + [param('ns3::Ptr< ns3::Packet >', 'packet'), param('ns3::Address&', 'source', is_const=True), param('ns3::Address&', 'dest', is_const=True), param('uint16_t', 'protocolNumber')], + is_virtual=True) ## bridge-net-device.h: ns3::Ptr ns3::BridgeNetDevice::GetNode() const [member function] - cls.add_method('GetNode', 'ns3::Ptr< ns3::Node >', [], is_const=True, is_virtual=True) + cls.add_method('GetNode', + 'ns3::Ptr< ns3::Node >', + [], + is_const=True, is_virtual=True) ## bridge-net-device.h: void ns3::BridgeNetDevice::SetNode(ns3::Ptr node) [member function] - cls.add_method('SetNode', 'void', [param('ns3::Ptr< ns3::Node >', 'node')], is_virtual=True) + cls.add_method('SetNode', + 'void', + [param('ns3::Ptr< ns3::Node >', 'node')], + is_virtual=True) ## bridge-net-device.h: bool ns3::BridgeNetDevice::NeedsArp() const [member function] - cls.add_method('NeedsArp', 'bool', [], is_const=True, is_virtual=True) + cls.add_method('NeedsArp', + 'bool', + [], + is_const=True, is_virtual=True) ## bridge-net-device.h: void ns3::BridgeNetDevice::SetReceiveCallback(ns3::Callback, ns3::Ptr, unsigned short, ns3::Address const&, ns3::empty, ns3::empty> cb) [member function] - cls.add_method('SetReceiveCallback', 'void', [param('ns3::Callback< bool, ns3::Ptr< ns3::NetDevice >, ns3::Ptr< ns3::Packet >, unsigned short, ns3::Address const&, ns3::empty, ns3::empty >', 'cb')], is_virtual=True) + cls.add_method('SetReceiveCallback', + 'void', + [param('ns3::Callback< bool, ns3::Ptr< ns3::NetDevice >, ns3::Ptr< ns3::Packet >, unsigned short, ns3::Address const&, ns3::empty, ns3::empty >', 'cb')], + is_virtual=True) ## bridge-net-device.h: void ns3::BridgeNetDevice::SetPromiscReceiveCallback(ns3::Callback, ns3::Ptr, unsigned short, ns3::Address const&, ns3::Address const&, ns3::NetDevice::PacketType> cb) [member function] - cls.add_method('SetPromiscReceiveCallback', 'void', [param('ns3::Callback< bool, ns3::Ptr< ns3::NetDevice >, ns3::Ptr< ns3::Packet >, unsigned short, ns3::Address const&, ns3::Address const&, ns3::NetDevice::PacketType >', 'cb')], is_virtual=True) + cls.add_method('SetPromiscReceiveCallback', + 'void', + [param('ns3::Callback< bool, ns3::Ptr< ns3::NetDevice >, ns3::Ptr< ns3::Packet >, unsigned short, ns3::Address const&, ns3::Address const&, ns3::NetDevice::PacketType >', 'cb')], + is_virtual=True) ## bridge-net-device.h: bool ns3::BridgeNetDevice::SupportsPromiscuous() const [member function] - cls.add_method('SupportsPromiscuous', 'bool', [], is_const=True, is_virtual=True) + cls.add_method('SupportsPromiscuous', + 'bool', + [], + is_const=True, is_virtual=True) ## bridge-net-device.h: void ns3::BridgeNetDevice::DoDispose() [member function] - cls.add_method('DoDispose', 'void', [], visibility='protected', is_virtual=True) + cls.add_method('DoDispose', + 'void', + [], + visibility='protected', is_virtual=True) ## bridge-net-device.h: void ns3::BridgeNetDevice::ReceiveFromDevice(ns3::Ptr device, ns3::Ptr packet, uint16_t protocol, ns3::Address const & source, ns3::Address const & destination, ns3::NetDevice::PacketType packetType) [member function] - cls.add_method('ReceiveFromDevice', 'void', [param('ns3::Ptr< ns3::NetDevice >', 'device'), param('ns3::Ptr< ns3::Packet >', 'packet'), param('uint16_t', 'protocol'), param('ns3::Address&', 'source', is_const=True), param('ns3::Address&', 'destination', is_const=True), param('ns3::NetDevice::PacketType', 'packetType')], visibility='protected') + cls.add_method('ReceiveFromDevice', + 'void', + [param('ns3::Ptr< ns3::NetDevice >', 'device'), param('ns3::Ptr< ns3::Packet >', 'packet'), param('uint16_t', 'protocol'), param('ns3::Address&', 'source', is_const=True), param('ns3::Address&', 'destination', is_const=True), param('ns3::NetDevice::PacketType', 'packetType')], + visibility='protected') ## bridge-net-device.h: void ns3::BridgeNetDevice::ForwardUnicast(ns3::Ptr incomingPort, ns3::Ptr packet, uint16_t protocol, ns3::Mac48Address src, ns3::Mac48Address dst) [member function] - cls.add_method('ForwardUnicast', 'void', [param('ns3::Ptr< ns3::NetDevice >', 'incomingPort'), param('ns3::Ptr< ns3::Packet >', 'packet'), param('uint16_t', 'protocol'), param('ns3::Mac48Address', 'src'), param('ns3::Mac48Address', 'dst')], visibility='protected') + cls.add_method('ForwardUnicast', + 'void', + [param('ns3::Ptr< ns3::NetDevice >', 'incomingPort'), param('ns3::Ptr< ns3::Packet >', 'packet'), param('uint16_t', 'protocol'), param('ns3::Mac48Address', 'src'), param('ns3::Mac48Address', 'dst')], + visibility='protected') ## bridge-net-device.h: void ns3::BridgeNetDevice::ForwardBroadcast(ns3::Ptr incomingPort, ns3::Ptr packet, uint16_t protocol, ns3::Mac48Address src, ns3::Mac48Address dst) [member function] - cls.add_method('ForwardBroadcast', 'void', [param('ns3::Ptr< ns3::NetDevice >', 'incomingPort'), param('ns3::Ptr< ns3::Packet >', 'packet'), param('uint16_t', 'protocol'), param('ns3::Mac48Address', 'src'), param('ns3::Mac48Address', 'dst')], visibility='protected') + cls.add_method('ForwardBroadcast', + 'void', + [param('ns3::Ptr< ns3::NetDevice >', 'incomingPort'), param('ns3::Ptr< ns3::Packet >', 'packet'), param('uint16_t', 'protocol'), param('ns3::Mac48Address', 'src'), param('ns3::Mac48Address', 'dst')], + visibility='protected') ## bridge-net-device.h: void ns3::BridgeNetDevice::Learn(ns3::Mac48Address source, ns3::Ptr port) [member function] - cls.add_method('Learn', 'void', [param('ns3::Mac48Address', 'source'), param('ns3::Ptr< ns3::NetDevice >', 'port')], visibility='protected') + cls.add_method('Learn', + 'void', + [param('ns3::Mac48Address', 'source'), param('ns3::Ptr< ns3::NetDevice >', 'port')], + visibility='protected') ## bridge-net-device.h: ns3::Ptr ns3::BridgeNetDevice::GetLearnedState(ns3::Mac48Address source) [member function] - cls.add_method('GetLearnedState', 'ns3::Ptr< ns3::NetDevice >', [param('ns3::Mac48Address', 'source')], visibility='protected') + cls.add_method('GetLearnedState', + 'ns3::Ptr< ns3::NetDevice >', + [param('ns3::Mac48Address', 'source')], + visibility='protected') return def register_Ns3BridgeChannel_methods(root_module, cls): ## bridge-channel.h: static ns3::TypeId ns3::BridgeChannel::GetTypeId() [member function] - cls.add_method('GetTypeId', 'ns3::TypeId', [], is_static=True) + cls.add_method('GetTypeId', + 'ns3::TypeId', + [], + is_static=True) ## bridge-channel.h: ns3::BridgeChannel::BridgeChannel() [constructor] - cls.add_constructor([], visibility='public') + cls.add_constructor([]) ## bridge-channel.h: void ns3::BridgeChannel::AddChannel(ns3::Ptr bridgedChannel) [member function] - cls.add_method('AddChannel', 'void', [param('ns3::Ptr< ns3::Channel >', 'bridgedChannel')]) + cls.add_method('AddChannel', + 'void', + [param('ns3::Ptr< ns3::Channel >', 'bridgedChannel')]) ## bridge-channel.h: uint32_t ns3::BridgeChannel::GetNDevices() const [member function] - cls.add_method('GetNDevices', 'uint32_t', [], is_const=True, is_virtual=True) + cls.add_method('GetNDevices', + 'uint32_t', + [], + is_const=True, is_virtual=True) ## bridge-channel.h: ns3::Ptr ns3::BridgeChannel::GetDevice(uint32_t i) const [member function] - cls.add_method('GetDevice', 'ns3::Ptr< ns3::NetDevice >', [param('uint32_t', 'i')], is_const=True, is_virtual=True) + cls.add_method('GetDevice', + 'ns3::Ptr< ns3::NetDevice >', + [param('uint32_t', 'i')], + is_const=True, is_virtual=True) return def register_functions(root_module): diff --git a/bindings/python/ns3_module_common.py b/bindings/python/ns3_module_common.py index ee80eda02..2b9ad84e3 100644 --- a/bindings/python/ns3_module_common.py +++ b/bindings/python/ns3_module_common.py @@ -1,4 +1,4 @@ -from pybindgen import Module, FileCodeSink, write_preamble, param, retval +from pybindgen import Module, FileCodeSink, param, retval, cppclass def register_types(module): root_module = module.get_root() @@ -6,7 +6,7 @@ def register_types(module): ## error-model.h: ns3::ErrorUnit [enumeration] module.add_enum('ErrorUnit', ['EU_BIT', 'EU_BYTE', 'EU_PKT']) ## packet.h: ns3::Packet [class] - module.add_class('Packet', incref_method='Ref', decref_method='Unref', peekref_method='GetReferenceCount') + module.add_class('Packet', memory_policy=cppclass.ReferenceCountingMethodsPolicy(incref_method='Ref', decref_method='Unref', peekref_method='GetReferenceCount')) ## packet.h: ns3::TagIterator [class] module.add_class('TagIterator') ## packet.h: ns3::TagIterator::Item [class] @@ -111,110 +111,211 @@ def register_methods(root_module): def register_Ns3Packet_methods(root_module, cls): ## packet.h: ns3::Packet::Packet() [constructor] - cls.add_constructor([], visibility='public') + cls.add_constructor([]) ## packet.h: ns3::Packet::Packet(ns3::Packet const & o) [copy constructor] - cls.add_constructor([param('ns3::Packet&', 'o', is_const=True)], visibility='public') + cls.add_constructor([param('ns3::Packet&', 'o', is_const=True)]) ## packet.h: ns3::Packet::Packet(uint32_t size) [constructor] - cls.add_constructor([param('uint32_t', 'size')], visibility='public') + cls.add_constructor([param('uint32_t', 'size')]) ## packet.h: ns3::Packet::Packet(uint8_t const * buffer, uint32_t size) [constructor] - cls.add_constructor([param('uint8_t *', 'buffer', transfer_ownership=False, is_const=True), param('uint32_t', 'size')], visibility='public') + cls.add_constructor([param('uint8_t *', 'buffer', transfer_ownership=False, is_const=True), param('uint32_t', 'size')]) ## packet.h: void ns3::Packet::AddAtEnd(ns3::Ptr packet) [member function] - cls.add_method('AddAtEnd', 'void', [param('ns3::Ptr< const ns3::Packet >', 'packet')]) + cls.add_method('AddAtEnd', + 'void', + [param('ns3::Ptr< const ns3::Packet >', 'packet')]) ## packet.h: void ns3::Packet::AddHeader(ns3::Header const & header) [member function] - cls.add_method('AddHeader', 'void', [param('ns3::Header&', 'header', is_const=True)]) + cls.add_method('AddHeader', + 'void', + [param('ns3::Header&', 'header', is_const=True)]) ## packet.h: void ns3::Packet::AddPaddingAtEnd(uint32_t size) [member function] - cls.add_method('AddPaddingAtEnd', 'void', [param('uint32_t', 'size')]) + cls.add_method('AddPaddingAtEnd', + 'void', + [param('uint32_t', 'size')]) ## packet.h: void ns3::Packet::AddTag(ns3::Tag const & tag) const [member function] - cls.add_method('AddTag', 'void', [param('ns3::Tag&', 'tag', is_const=True)], is_const=True) + cls.add_method('AddTag', + 'void', + [param('ns3::Tag&', 'tag', is_const=True)], + is_const=True) ## packet.h: void ns3::Packet::AddTrailer(ns3::Trailer const & trailer) [member function] - cls.add_method('AddTrailer', 'void', [param('ns3::Trailer&', 'trailer', is_const=True)]) + cls.add_method('AddTrailer', + 'void', + [param('ns3::Trailer&', 'trailer', is_const=True)]) ## packet.h: ns3::PacketMetadata::ItemIterator ns3::Packet::BeginItem() const [member function] - cls.add_method('BeginItem', 'ns3::PacketMetadata::ItemIterator', [], is_const=True) + cls.add_method('BeginItem', + 'ns3::PacketMetadata::ItemIterator', + [], + is_const=True) ## packet.h: ns3::Ptr ns3::Packet::Copy() const [member function] - cls.add_method('Copy', 'ns3::Ptr< ns3::Packet >', [], is_const=True) + cls.add_method('Copy', + 'ns3::Ptr< ns3::Packet >', + [], + is_const=True) ## packet.h: ns3::Ptr ns3::Packet::CreateFragment(uint32_t start, uint32_t length) const [member function] - cls.add_method('CreateFragment', 'ns3::Ptr< ns3::Packet >', [param('uint32_t', 'start'), param('uint32_t', 'length')], is_const=True) + cls.add_method('CreateFragment', + 'ns3::Ptr< ns3::Packet >', + [param('uint32_t', 'start'), param('uint32_t', 'length')], + is_const=True) ## packet.h: void ns3::Packet::Deserialize(ns3::Buffer buffer) [member function] - cls.add_method('Deserialize', 'void', [param('ns3::Buffer', 'buffer')]) + cls.add_method('Deserialize', + 'void', + [param('ns3::Buffer', 'buffer')]) ## packet.h: static void ns3::Packet::EnableMetadata() [member function] - cls.add_method('EnableMetadata', 'void', [], is_static=True) + cls.add_method('EnableMetadata', + 'void', + [], + is_static=True) ## packet.h: bool ns3::Packet::FindFirstMatchingTag(ns3::Tag & tag) const [member function] - cls.add_method('FindFirstMatchingTag', 'bool', [param('ns3::Tag&', 'tag')], is_const=True) + cls.add_method('FindFirstMatchingTag', + 'bool', + [param('ns3::Tag&', 'tag')], + is_const=True) ## packet.h: uint32_t ns3::Packet::GetSize() const [member function] - cls.add_method('GetSize', 'uint32_t', [], is_const=True) + cls.add_method('GetSize', + 'uint32_t', + [], + is_const=True) ## packet.h: ns3::TagIterator ns3::Packet::GetTagIterator() const [member function] - cls.add_method('GetTagIterator', 'ns3::TagIterator', [], is_const=True) + cls.add_method('GetTagIterator', + 'ns3::TagIterator', + [], + is_const=True) ## packet.h: uint32_t ns3::Packet::GetUid() const [member function] - cls.add_method('GetUid', 'uint32_t', [], is_const=True) + cls.add_method('GetUid', + 'uint32_t', + [], + is_const=True) ## packet.h: uint8_t const * ns3::Packet::PeekData() const [member function] - cls.add_method('PeekData', retval('uint8_t *', is_const=True, caller_owns_return=False), [], is_const=True) + cls.add_method('PeekData', + retval('uint8_t *', is_const=True, caller_owns_return=False), + [], + is_const=True) ## packet.h: uint32_t ns3::Packet::PeekHeader(ns3::Header & header) [member function] - cls.add_method('PeekHeader', 'uint32_t', [param('ns3::Header&', 'header')]) + cls.add_method('PeekHeader', + 'uint32_t', + [param('ns3::Header&', 'header')]) ## packet.h: uint32_t ns3::Packet::PeekTrailer(ns3::Trailer & trailer) [member function] - cls.add_method('PeekTrailer', 'uint32_t', [param('ns3::Trailer&', 'trailer')]) + cls.add_method('PeekTrailer', + 'uint32_t', + [param('ns3::Trailer&', 'trailer')]) ## packet.h: void ns3::Packet::Print(std::ostream & os) const [member function] - cls.add_method('Print', 'void', [param('std::ostream&', 'os')], is_const=True) + cls.add_method('Print', + 'void', + [param('std::ostream&', 'os')], + is_const=True) ## packet.h: void ns3::Packet::PrintTags(std::ostream & os) const [member function] - cls.add_method('PrintTags', 'void', [param('std::ostream&', 'os')], is_const=True) + cls.add_method('PrintTags', + 'void', + [param('std::ostream&', 'os')], + is_const=True) ## packet.h: void ns3::Packet::RemoveAllTags() [member function] - cls.add_method('RemoveAllTags', 'void', []) + cls.add_method('RemoveAllTags', + 'void', + []) ## packet.h: void ns3::Packet::RemoveAtEnd(uint32_t size) [member function] - cls.add_method('RemoveAtEnd', 'void', [param('uint32_t', 'size')]) + cls.add_method('RemoveAtEnd', + 'void', + [param('uint32_t', 'size')]) ## packet.h: void ns3::Packet::RemoveAtStart(uint32_t size) [member function] - cls.add_method('RemoveAtStart', 'void', [param('uint32_t', 'size')]) + cls.add_method('RemoveAtStart', + 'void', + [param('uint32_t', 'size')]) ## packet.h: uint32_t ns3::Packet::RemoveHeader(ns3::Header & header) [member function] - cls.add_method('RemoveHeader', 'uint32_t', [param('ns3::Header&', 'header')]) + cls.add_method('RemoveHeader', + 'uint32_t', + [param('ns3::Header&', 'header')]) ## packet.h: uint32_t ns3::Packet::RemoveTrailer(ns3::Trailer & trailer) [member function] - cls.add_method('RemoveTrailer', 'uint32_t', [param('ns3::Trailer&', 'trailer')]) + cls.add_method('RemoveTrailer', + 'uint32_t', + [param('ns3::Trailer&', 'trailer')]) ## packet.h: ns3::Buffer ns3::Packet::Serialize() const [member function] - cls.add_method('Serialize', 'ns3::Buffer', [], is_const=True) + cls.add_method('Serialize', + 'ns3::Buffer', + [], + is_const=True) cls.add_output_stream_operator() return def register_Ns3TagIterator_methods(root_module, cls): ## packet.h: bool ns3::TagIterator::HasNext() const [member function] - cls.add_method('HasNext', 'bool', [], is_const=True) + cls.add_method('HasNext', + 'bool', + [], + is_const=True) ## packet.h: ns3::TagIterator::Item ns3::TagIterator::Next() [member function] - cls.add_method('Next', 'ns3::TagIterator::Item', []) + cls.add_method('Next', + 'ns3::TagIterator::Item', + []) return def register_Ns3TagIteratorItem_methods(root_module, cls): ## packet.h: ns3::TypeId ns3::TagIterator::Item::GetTypeId() const [member function] - cls.add_method('GetTypeId', 'ns3::TypeId', [], is_const=True) + cls.add_method('GetTypeId', + 'ns3::TypeId', + [], + is_const=True) ## packet.h: uint32_t ns3::TagIterator::Item::GetStart() const [member function] - cls.add_method('GetStart', 'uint32_t', [], is_const=True) + cls.add_method('GetStart', + 'uint32_t', + [], + is_const=True) ## packet.h: uint32_t ns3::TagIterator::Item::GetEnd() const [member function] - cls.add_method('GetEnd', 'uint32_t', [], is_const=True) + cls.add_method('GetEnd', + 'uint32_t', + [], + is_const=True) ## packet.h: void ns3::TagIterator::Item::GetTag(ns3::Tag & tag) const [member function] - cls.add_method('GetTag', 'void', [param('ns3::Tag&', 'tag')], is_const=True) + cls.add_method('GetTag', + 'void', + [param('ns3::Tag&', 'tag')], + is_const=True) return def register_Ns3TagList_methods(root_module, cls): ## tag-list.h: ns3::TagList::TagList() [constructor] - cls.add_constructor([], visibility='public') + cls.add_constructor([]) ## tag-list.h: ns3::TagList::TagList(ns3::TagList const & o) [copy constructor] - cls.add_constructor([param('ns3::TagList&', 'o', is_const=True)], visibility='public') + cls.add_constructor([param('ns3::TagList&', 'o', is_const=True)]) ## tag-list.h: ns3::TagBuffer ns3::TagList::Add(ns3::TypeId tid, uint32_t bufferSize, int32_t start, int32_t end) [member function] - cls.add_method('Add', 'ns3::TagBuffer', [param('ns3::TypeId', 'tid'), param('uint32_t', 'bufferSize'), param('int32_t', 'start'), param('int32_t', 'end')]) + cls.add_method('Add', + 'ns3::TagBuffer', + [param('ns3::TypeId', 'tid'), param('uint32_t', 'bufferSize'), param('int32_t', 'start'), param('int32_t', 'end')]) ## tag-list.h: void ns3::TagList::Add(ns3::TagList const & o) [member function] - cls.add_method('Add', 'void', [param('ns3::TagList&', 'o', is_const=True)]) + cls.add_method('Add', + 'void', + [param('ns3::TagList&', 'o', is_const=True)]) ## tag-list.h: void ns3::TagList::RemoveAll() [member function] - cls.add_method('RemoveAll', 'void', []) + cls.add_method('RemoveAll', + 'void', + []) ## tag-list.h: ns3::TagList::Iterator ns3::TagList::Begin(int32_t offsetStart, int32_t offsetEnd) const [member function] - cls.add_method('Begin', 'ns3::TagList::Iterator', [param('int32_t', 'offsetStart'), param('int32_t', 'offsetEnd')], is_const=True) + cls.add_method('Begin', + 'ns3::TagList::Iterator', + [param('int32_t', 'offsetStart'), param('int32_t', 'offsetEnd')], + is_const=True) ## tag-list.h: void ns3::TagList::AddAtEnd(int32_t adjustment, int32_t appendOffset) [member function] - cls.add_method('AddAtEnd', 'void', [param('int32_t', 'adjustment'), param('int32_t', 'appendOffset')]) + cls.add_method('AddAtEnd', + 'void', + [param('int32_t', 'adjustment'), param('int32_t', 'appendOffset')]) ## tag-list.h: void ns3::TagList::AddAtStart(int32_t adjustment, int32_t prependOffset) [member function] - cls.add_method('AddAtStart', 'void', [param('int32_t', 'adjustment'), param('int32_t', 'prependOffset')]) + cls.add_method('AddAtStart', + 'void', + [param('int32_t', 'adjustment'), param('int32_t', 'prependOffset')]) return def register_Ns3TagListIterator_methods(root_module, cls): ## tag-list.h: bool ns3::TagList::Iterator::HasNext() const [member function] - cls.add_method('HasNext', 'bool', [], is_const=True) + cls.add_method('HasNext', + 'bool', + [], + is_const=True) ## tag-list.h: ns3::TagList::Iterator::Item ns3::TagList::Iterator::Next() [member function] - cls.add_method('Next', 'ns3::TagList::Iterator::Item', []) + cls.add_method('Next', + 'ns3::TagList::Iterator::Item', + []) ## tag-list.h: uint32_t ns3::TagList::Iterator::GetOffsetStart() const [member function] - cls.add_method('GetOffsetStart', 'uint32_t', [], is_const=True) + cls.add_method('GetOffsetStart', + 'uint32_t', + [], + is_const=True) return def register_Ns3TagListIteratorItem_methods(root_module, cls): @@ -229,208 +330,384 @@ def register_Ns3TagListIteratorItem_methods(root_module, cls): ## tag-list.h: ns3::TagList::Iterator::Item::buf [variable] cls.add_instance_attribute('buf', 'ns3::TagBuffer', is_const=False) ## tag-list.h: ns3::TagList::Iterator::Item::Item(ns3::TagBuffer buf) [constructor] - cls.add_constructor([param('ns3::TagBuffer', 'buf')], visibility='public') + cls.add_constructor([param('ns3::TagBuffer', 'buf')]) return def register_Ns3TagBuffer_methods(root_module, cls): ## tag-buffer.h: ns3::TagBuffer::TagBuffer(uint8_t * start, uint8_t * end) [constructor] - cls.add_constructor([param('uint8_t *', 'start'), param('uint8_t *', 'end')], visibility='public') + cls.add_constructor([param('uint8_t *', 'start'), param('uint8_t *', 'end')]) ## tag-buffer.h: void ns3::TagBuffer::TrimAtEnd(uint32_t trim) [member function] - cls.add_method('TrimAtEnd', 'void', [param('uint32_t', 'trim')]) + cls.add_method('TrimAtEnd', + 'void', + [param('uint32_t', 'trim')]) ## tag-buffer.h: void ns3::TagBuffer::CopyFrom(ns3::TagBuffer o) [member function] - cls.add_method('CopyFrom', 'void', [param('ns3::TagBuffer', 'o')]) + cls.add_method('CopyFrom', + 'void', + [param('ns3::TagBuffer', 'o')]) ## tag-buffer.h: void ns3::TagBuffer::WriteU8(uint8_t v) [member function] - cls.add_method('WriteU8', 'void', [param('uint8_t', 'v')]) + cls.add_method('WriteU8', + 'void', + [param('uint8_t', 'v')]) ## tag-buffer.h: void ns3::TagBuffer::WriteU16(uint16_t data) [member function] - cls.add_method('WriteU16', 'void', [param('uint16_t', 'data')]) + cls.add_method('WriteU16', + 'void', + [param('uint16_t', 'data')]) ## tag-buffer.h: void ns3::TagBuffer::WriteU32(uint32_t data) [member function] - cls.add_method('WriteU32', 'void', [param('uint32_t', 'data')]) + cls.add_method('WriteU32', + 'void', + [param('uint32_t', 'data')]) ## tag-buffer.h: void ns3::TagBuffer::WriteU64(uint64_t v) [member function] - cls.add_method('WriteU64', 'void', [param('uint64_t', 'v')]) + cls.add_method('WriteU64', + 'void', + [param('uint64_t', 'v')]) ## tag-buffer.h: void ns3::TagBuffer::WriteDouble(double v) [member function] - cls.add_method('WriteDouble', 'void', [param('double', 'v')]) + cls.add_method('WriteDouble', + 'void', + [param('double', 'v')]) ## tag-buffer.h: void ns3::TagBuffer::Write(uint8_t const * buffer, uint32_t size) [member function] - cls.add_method('Write', 'void', [param('uint8_t *', 'buffer', transfer_ownership=False, is_const=True), param('uint32_t', 'size')]) + cls.add_method('Write', + 'void', + [param('uint8_t *', 'buffer', transfer_ownership=False, is_const=True), param('uint32_t', 'size')]) ## tag-buffer.h: uint8_t ns3::TagBuffer::ReadU8() [member function] - cls.add_method('ReadU8', 'uint8_t', []) + cls.add_method('ReadU8', + 'uint8_t', + []) ## tag-buffer.h: uint16_t ns3::TagBuffer::ReadU16() [member function] - cls.add_method('ReadU16', 'uint16_t', []) + cls.add_method('ReadU16', + 'uint16_t', + []) ## tag-buffer.h: uint32_t ns3::TagBuffer::ReadU32() [member function] - cls.add_method('ReadU32', 'uint32_t', []) + cls.add_method('ReadU32', + 'uint32_t', + []) ## tag-buffer.h: uint64_t ns3::TagBuffer::ReadU64() [member function] - cls.add_method('ReadU64', 'uint64_t', []) + cls.add_method('ReadU64', + 'uint64_t', + []) ## tag-buffer.h: double ns3::TagBuffer::ReadDouble() [member function] - cls.add_method('ReadDouble', 'double', []) + cls.add_method('ReadDouble', + 'double', + []) ## tag-buffer.h: void ns3::TagBuffer::Read(uint8_t * buffer, uint32_t size) [member function] - cls.add_method('Read', 'void', [param('uint8_t *', 'buffer'), param('uint32_t', 'size')]) + cls.add_method('Read', + 'void', + [param('uint8_t *', 'buffer'), param('uint32_t', 'size')]) return def register_Ns3Buffer_methods(root_module, cls): ## buffer.h: uint32_t ns3::Buffer::GetSize() const [member function] - cls.add_method('GetSize', 'uint32_t', [], is_const=True) + cls.add_method('GetSize', + 'uint32_t', + [], + is_const=True) ## buffer.h: uint8_t const * ns3::Buffer::PeekData() const [member function] - cls.add_method('PeekData', retval('uint8_t *', is_const=True, caller_owns_return=False), [], is_const=True) + cls.add_method('PeekData', + retval('uint8_t *', is_const=True, caller_owns_return=False), + [], + is_const=True) ## buffer.h: bool ns3::Buffer::AddAtStart(uint32_t start) [member function] - cls.add_method('AddAtStart', 'bool', [param('uint32_t', 'start')]) + cls.add_method('AddAtStart', + 'bool', + [param('uint32_t', 'start')]) ## buffer.h: bool ns3::Buffer::AddAtEnd(uint32_t end) [member function] - cls.add_method('AddAtEnd', 'bool', [param('uint32_t', 'end')]) + cls.add_method('AddAtEnd', + 'bool', + [param('uint32_t', 'end')]) ## buffer.h: void ns3::Buffer::AddAtEnd(ns3::Buffer const & o) [member function] - cls.add_method('AddAtEnd', 'void', [param('ns3::Buffer&', 'o', is_const=True)]) + cls.add_method('AddAtEnd', + 'void', + [param('ns3::Buffer&', 'o', is_const=True)]) ## buffer.h: void ns3::Buffer::RemoveAtStart(uint32_t start) [member function] - cls.add_method('RemoveAtStart', 'void', [param('uint32_t', 'start')]) + cls.add_method('RemoveAtStart', + 'void', + [param('uint32_t', 'start')]) ## buffer.h: void ns3::Buffer::RemoveAtEnd(uint32_t end) [member function] - cls.add_method('RemoveAtEnd', 'void', [param('uint32_t', 'end')]) + cls.add_method('RemoveAtEnd', + 'void', + [param('uint32_t', 'end')]) ## buffer.h: ns3::Buffer ns3::Buffer::CreateFragment(uint32_t start, uint32_t length) const [member function] - cls.add_method('CreateFragment', 'ns3::Buffer', [param('uint32_t', 'start'), param('uint32_t', 'length')], is_const=True) + cls.add_method('CreateFragment', + 'ns3::Buffer', + [param('uint32_t', 'start'), param('uint32_t', 'length')], + is_const=True) ## buffer.h: ns3::Buffer::Iterator ns3::Buffer::Begin() const [member function] - cls.add_method('Begin', 'ns3::Buffer::Iterator', [], is_const=True) + cls.add_method('Begin', + 'ns3::Buffer::Iterator', + [], + is_const=True) ## buffer.h: ns3::Buffer::Iterator ns3::Buffer::End() const [member function] - cls.add_method('End', 'ns3::Buffer::Iterator', [], is_const=True) + cls.add_method('End', + 'ns3::Buffer::Iterator', + [], + is_const=True) ## buffer.h: ns3::Buffer ns3::Buffer::CreateFullCopy() const [member function] - cls.add_method('CreateFullCopy', 'ns3::Buffer', [], is_const=True) + cls.add_method('CreateFullCopy', + 'ns3::Buffer', + [], + is_const=True) ## buffer.h: int32_t ns3::Buffer::GetCurrentStartOffset() const [member function] - cls.add_method('GetCurrentStartOffset', 'int32_t', [], is_const=True) + cls.add_method('GetCurrentStartOffset', + 'int32_t', + [], + is_const=True) ## buffer.h: int32_t ns3::Buffer::GetCurrentEndOffset() const [member function] - cls.add_method('GetCurrentEndOffset', 'int32_t', [], is_const=True) + cls.add_method('GetCurrentEndOffset', + 'int32_t', + [], + is_const=True) ## buffer.h: ns3::Buffer::Buffer(ns3::Buffer const & o) [copy constructor] - cls.add_constructor([param('ns3::Buffer&', 'o', is_const=True)], visibility='public') + cls.add_constructor([param('ns3::Buffer&', 'o', is_const=True)]) ## buffer.h: ns3::Buffer::Buffer() [constructor] - cls.add_constructor([], visibility='public') + cls.add_constructor([]) ## buffer.h: ns3::Buffer::Buffer(uint32_t dataSize) [constructor] - cls.add_constructor([param('uint32_t', 'dataSize')], visibility='public') + cls.add_constructor([param('uint32_t', 'dataSize')]) return def register_Ns3BufferIterator_methods(root_module, cls): ## buffer.h: ns3::Buffer::Iterator::Iterator() [constructor] - cls.add_constructor([], visibility='public') + cls.add_constructor([]) ## buffer.h: void ns3::Buffer::Iterator::Next() [member function] - cls.add_method('Next', 'void', []) + cls.add_method('Next', + 'void', + []) ## buffer.h: void ns3::Buffer::Iterator::Prev() [member function] - cls.add_method('Prev', 'void', []) + cls.add_method('Prev', + 'void', + []) ## buffer.h: void ns3::Buffer::Iterator::Next(uint32_t delta) [member function] - cls.add_method('Next', 'void', [param('uint32_t', 'delta')]) + cls.add_method('Next', + 'void', + [param('uint32_t', 'delta')]) ## buffer.h: void ns3::Buffer::Iterator::Prev(uint32_t delta) [member function] - cls.add_method('Prev', 'void', [param('uint32_t', 'delta')]) + cls.add_method('Prev', + 'void', + [param('uint32_t', 'delta')]) ## buffer.h: uint32_t ns3::Buffer::Iterator::GetDistanceFrom(ns3::Buffer::Iterator const & o) const [member function] - cls.add_method('GetDistanceFrom', 'uint32_t', [param('ns3::Buffer::Iterator&', 'o', is_const=True)], is_const=True) + cls.add_method('GetDistanceFrom', + 'uint32_t', + [param('ns3::Buffer::Iterator&', 'o', is_const=True)], + is_const=True) ## buffer.h: bool ns3::Buffer::Iterator::IsEnd() const [member function] - cls.add_method('IsEnd', 'bool', [], is_const=True) + cls.add_method('IsEnd', + 'bool', + [], + is_const=True) ## buffer.h: bool ns3::Buffer::Iterator::IsStart() const [member function] - cls.add_method('IsStart', 'bool', [], is_const=True) + cls.add_method('IsStart', + 'bool', + [], + is_const=True) ## buffer.h: void ns3::Buffer::Iterator::WriteU8(uint8_t data) [member function] - cls.add_method('WriteU8', 'void', [param('uint8_t', 'data')]) + cls.add_method('WriteU8', + 'void', + [param('uint8_t', 'data')]) ## buffer.h: void ns3::Buffer::Iterator::WriteU8(uint8_t data, uint32_t len) [member function] - cls.add_method('WriteU8', 'void', [param('uint8_t', 'data'), param('uint32_t', 'len')]) + cls.add_method('WriteU8', + 'void', + [param('uint8_t', 'data'), param('uint32_t', 'len')]) ## buffer.h: void ns3::Buffer::Iterator::WriteU16(uint16_t data) [member function] - cls.add_method('WriteU16', 'void', [param('uint16_t', 'data')]) + cls.add_method('WriteU16', + 'void', + [param('uint16_t', 'data')]) ## buffer.h: void ns3::Buffer::Iterator::WriteU32(uint32_t data) [member function] - cls.add_method('WriteU32', 'void', [param('uint32_t', 'data')]) + cls.add_method('WriteU32', + 'void', + [param('uint32_t', 'data')]) ## buffer.h: void ns3::Buffer::Iterator::WriteU64(uint64_t data) [member function] - cls.add_method('WriteU64', 'void', [param('uint64_t', 'data')]) + cls.add_method('WriteU64', + 'void', + [param('uint64_t', 'data')]) ## buffer.h: void ns3::Buffer::Iterator::WriteHtolsbU16(uint16_t data) [member function] - cls.add_method('WriteHtolsbU16', 'void', [param('uint16_t', 'data')]) + cls.add_method('WriteHtolsbU16', + 'void', + [param('uint16_t', 'data')]) ## buffer.h: void ns3::Buffer::Iterator::WriteHtolsbU32(uint32_t data) [member function] - cls.add_method('WriteHtolsbU32', 'void', [param('uint32_t', 'data')]) + cls.add_method('WriteHtolsbU32', + 'void', + [param('uint32_t', 'data')]) ## buffer.h: void ns3::Buffer::Iterator::WriteHtolsbU64(uint64_t data) [member function] - cls.add_method('WriteHtolsbU64', 'void', [param('uint64_t', 'data')]) + cls.add_method('WriteHtolsbU64', + 'void', + [param('uint64_t', 'data')]) ## buffer.h: void ns3::Buffer::Iterator::WriteHtonU16(uint16_t data) [member function] - cls.add_method('WriteHtonU16', 'void', [param('uint16_t', 'data')]) + cls.add_method('WriteHtonU16', + 'void', + [param('uint16_t', 'data')]) ## buffer.h: void ns3::Buffer::Iterator::WriteHtonU32(uint32_t data) [member function] - cls.add_method('WriteHtonU32', 'void', [param('uint32_t', 'data')]) + cls.add_method('WriteHtonU32', + 'void', + [param('uint32_t', 'data')]) ## buffer.h: void ns3::Buffer::Iterator::WriteHtonU64(uint64_t data) [member function] - cls.add_method('WriteHtonU64', 'void', [param('uint64_t', 'data')]) + cls.add_method('WriteHtonU64', + 'void', + [param('uint64_t', 'data')]) ## buffer.h: void ns3::Buffer::Iterator::Write(uint8_t const * buffer, uint32_t size) [member function] - cls.add_method('Write', 'void', [param('uint8_t *', 'buffer', transfer_ownership=False, is_const=True), param('uint32_t', 'size')]) + cls.add_method('Write', + 'void', + [param('uint8_t *', 'buffer', transfer_ownership=False, is_const=True), param('uint32_t', 'size')]) ## buffer.h: void ns3::Buffer::Iterator::Write(ns3::Buffer::Iterator start, ns3::Buffer::Iterator end) [member function] - cls.add_method('Write', 'void', [param('ns3::Buffer::Iterator', 'start'), param('ns3::Buffer::Iterator', 'end')]) + cls.add_method('Write', + 'void', + [param('ns3::Buffer::Iterator', 'start'), param('ns3::Buffer::Iterator', 'end')]) ## buffer.h: uint8_t ns3::Buffer::Iterator::ReadU8() [member function] - cls.add_method('ReadU8', 'uint8_t', []) + cls.add_method('ReadU8', + 'uint8_t', + []) ## buffer.h: uint16_t ns3::Buffer::Iterator::ReadU16() [member function] - cls.add_method('ReadU16', 'uint16_t', []) + cls.add_method('ReadU16', + 'uint16_t', + []) ## buffer.h: uint32_t ns3::Buffer::Iterator::ReadU32() [member function] - cls.add_method('ReadU32', 'uint32_t', []) + cls.add_method('ReadU32', + 'uint32_t', + []) ## buffer.h: uint64_t ns3::Buffer::Iterator::ReadU64() [member function] - cls.add_method('ReadU64', 'uint64_t', []) + cls.add_method('ReadU64', + 'uint64_t', + []) ## buffer.h: uint16_t ns3::Buffer::Iterator::ReadNtohU16() [member function] - cls.add_method('ReadNtohU16', 'uint16_t', []) + cls.add_method('ReadNtohU16', + 'uint16_t', + []) ## buffer.h: uint32_t ns3::Buffer::Iterator::ReadNtohU32() [member function] - cls.add_method('ReadNtohU32', 'uint32_t', []) + cls.add_method('ReadNtohU32', + 'uint32_t', + []) ## buffer.h: uint64_t ns3::Buffer::Iterator::ReadNtohU64() [member function] - cls.add_method('ReadNtohU64', 'uint64_t', []) + cls.add_method('ReadNtohU64', + 'uint64_t', + []) ## buffer.h: uint16_t ns3::Buffer::Iterator::ReadLsbtohU16() [member function] - cls.add_method('ReadLsbtohU16', 'uint16_t', []) + cls.add_method('ReadLsbtohU16', + 'uint16_t', + []) ## buffer.h: uint32_t ns3::Buffer::Iterator::ReadLsbtohU32() [member function] - cls.add_method('ReadLsbtohU32', 'uint32_t', []) + cls.add_method('ReadLsbtohU32', + 'uint32_t', + []) ## buffer.h: uint64_t ns3::Buffer::Iterator::ReadLsbtohU64() [member function] - cls.add_method('ReadLsbtohU64', 'uint64_t', []) + cls.add_method('ReadLsbtohU64', + 'uint64_t', + []) ## buffer.h: void ns3::Buffer::Iterator::Read(uint8_t * buffer, uint32_t size) [member function] - cls.add_method('Read', 'void', [param('uint8_t *', 'buffer'), param('uint32_t', 'size')]) + cls.add_method('Read', + 'void', + [param('uint8_t *', 'buffer'), param('uint32_t', 'size')]) ## buffer.h: uint16_t ns3::Buffer::Iterator::CalculateIpChecksum(uint16_t size) [member function] - cls.add_method('CalculateIpChecksum', 'uint16_t', [param('uint16_t', 'size')]) + cls.add_method('CalculateIpChecksum', + 'uint16_t', + [param('uint16_t', 'size')]) ## buffer.h: uint16_t ns3::Buffer::Iterator::CalculateIpChecksum(uint16_t size, uint32_t initialChecksum) [member function] - cls.add_method('CalculateIpChecksum', 'uint16_t', [param('uint16_t', 'size'), param('uint32_t', 'initialChecksum')]) + cls.add_method('CalculateIpChecksum', + 'uint16_t', + [param('uint16_t', 'size'), param('uint32_t', 'initialChecksum')]) ## buffer.h: uint32_t ns3::Buffer::Iterator::GetSize() const [member function] - cls.add_method('GetSize', 'uint32_t', [], is_const=True) + cls.add_method('GetSize', + 'uint32_t', + [], + is_const=True) return def register_Ns3Chunk_methods(root_module, cls): ## chunk.h: ns3::Chunk::Chunk() [constructor] - cls.add_constructor([], visibility='public') + cls.add_constructor([]) ## chunk.h: ns3::Chunk::Chunk(ns3::Chunk const & arg0) [copy constructor] - cls.add_constructor([param('ns3::Chunk&', 'arg0', is_const=True)], visibility='public') + cls.add_constructor([param('ns3::Chunk&', 'arg0', is_const=True)]) ## chunk.h: static ns3::TypeId ns3::Chunk::GetTypeId() [member function] - cls.add_method('GetTypeId', 'ns3::TypeId', [], is_static=True) + cls.add_method('GetTypeId', + 'ns3::TypeId', + [], + is_static=True) ## chunk.h: uint32_t ns3::Chunk::Deserialize(ns3::Buffer::Iterator start) [member function] - cls.add_method('Deserialize', 'uint32_t', [param('ns3::Buffer::Iterator', 'start')], is_pure_virtual=True, is_virtual=True) + cls.add_method('Deserialize', + 'uint32_t', + [param('ns3::Buffer::Iterator', 'start')], + is_pure_virtual=True, is_virtual=True) ## chunk.h: void ns3::Chunk::Print(std::ostream & os) const [member function] - cls.add_method('Print', 'void', [param('std::ostream&', 'os')], is_pure_virtual=True, is_const=True, is_virtual=True) + cls.add_method('Print', + 'void', + [param('std::ostream&', 'os')], + is_pure_virtual=True, is_const=True, is_virtual=True) return def register_Ns3DataRate_methods(root_module, cls): ## data-rate.h: ns3::DataRate::DataRate(ns3::DataRate const & arg0) [copy constructor] - cls.add_constructor([param('ns3::DataRate&', 'arg0', is_const=True)], visibility='public') + cls.add_constructor([param('ns3::DataRate&', 'arg0', is_const=True)]) ## data-rate.h: ns3::DataRate::DataRate() [constructor] - cls.add_constructor([], visibility='public') + cls.add_constructor([]) ## data-rate.h: ns3::DataRate::DataRate(uint64_t bps) [constructor] - cls.add_constructor([param('uint64_t', 'bps')], visibility='public') + cls.add_constructor([param('uint64_t', 'bps')]) ## data-rate.h: ns3::DataRate::DataRate(std::string rate) [constructor] - cls.add_constructor([param('std::string', 'rate')], visibility='public') + cls.add_constructor([param('std::string', 'rate')]) ## data-rate.h: double ns3::DataRate::CalculateTxTime(uint32_t bytes) const [member function] - cls.add_method('CalculateTxTime', 'double', [param('uint32_t', 'bytes')], is_const=True) + cls.add_method('CalculateTxTime', + 'double', + [param('uint32_t', 'bytes')], + is_const=True) ## data-rate.h: uint64_t ns3::DataRate::GetBitRate() const [member function] - cls.add_method('GetBitRate', 'uint64_t', [], is_const=True) + cls.add_method('GetBitRate', + 'uint64_t', + [], + is_const=True) cls.add_output_stream_operator() return def register_Ns3Tag_methods(root_module, cls): ## tag.h: static ns3::TypeId ns3::Tag::GetTypeId() [member function] - cls.add_method('GetTypeId', 'ns3::TypeId', [], is_static=True) + cls.add_method('GetTypeId', + 'ns3::TypeId', + [], + is_static=True) ## tag.h: uint32_t ns3::Tag::GetSerializedSize() const [member function] - cls.add_method('GetSerializedSize', 'uint32_t', [], is_pure_virtual=True, is_const=True, is_virtual=True) + cls.add_method('GetSerializedSize', + 'uint32_t', + [], + is_pure_virtual=True, is_const=True, is_virtual=True) ## tag.h: void ns3::Tag::Serialize(ns3::TagBuffer i) const [member function] - cls.add_method('Serialize', 'void', [param('ns3::TagBuffer', 'i')], is_pure_virtual=True, is_const=True, is_virtual=True) + cls.add_method('Serialize', + 'void', + [param('ns3::TagBuffer', 'i')], + is_pure_virtual=True, is_const=True, is_virtual=True) ## tag.h: void ns3::Tag::Deserialize(ns3::TagBuffer i) [member function] - cls.add_method('Deserialize', 'void', [param('ns3::TagBuffer', 'i')], is_pure_virtual=True, is_virtual=True) + cls.add_method('Deserialize', + 'void', + [param('ns3::TagBuffer', 'i')], + is_pure_virtual=True, is_virtual=True) ## tag.h: void ns3::Tag::Print(std::ostream & os) const [member function] - cls.add_method('Print', 'void', [param('std::ostream&', 'os')], is_pure_virtual=True, is_const=True, is_virtual=True) + cls.add_method('Print', + 'void', + [param('std::ostream&', 'os')], + is_pure_virtual=True, is_const=True, is_virtual=True) cls.add_constructor([]) return def register_Ns3PcapWriter_methods(root_module, cls): ## pcap-writer.h: ns3::PcapWriter::PcapWriter() [constructor] - cls.add_constructor([], visibility='public') + cls.add_constructor([]) ## pcap-writer.h: void ns3::PcapWriter::Open(std::string const & name) [member function] - cls.add_method('Open', 'void', [param('std::string&', 'name', is_const=True)]) + cls.add_method('Open', + 'void', + [param('std::string&', 'name', is_const=True)]) ## pcap-writer.h: void ns3::PcapWriter::WriteEthernetHeader() [member function] - cls.add_method('WriteEthernetHeader', 'void', []) + cls.add_method('WriteEthernetHeader', + 'void', + []) ## pcap-writer.h: void ns3::PcapWriter::WriteIpHeader() [member function] - cls.add_method('WriteIpHeader', 'void', []) + cls.add_method('WriteIpHeader', + 'void', + []) ## pcap-writer.h: void ns3::PcapWriter::WriteWifiHeader() [member function] - cls.add_method('WriteWifiHeader', 'void', []) + cls.add_method('WriteWifiHeader', + 'void', + []) ## pcap-writer.h: void ns3::PcapWriter::WritePppHeader() [member function] - cls.add_method('WritePppHeader', 'void', []) + cls.add_method('WritePppHeader', + 'void', + []) ## pcap-writer.h: void ns3::PcapWriter::WritePacket(ns3::Ptr packet) [member function] - cls.add_method('WritePacket', 'void', [param('ns3::Ptr< const ns3::Packet >', 'packet')]) + cls.add_method('WritePacket', + 'void', + [param('ns3::Ptr< const ns3::Packet >', 'packet')]) return def register_Ns3DataRateChecker_methods(root_module, cls): @@ -439,124 +716,234 @@ def register_Ns3DataRateChecker_methods(root_module, cls): def register_Ns3ErrorModel_methods(root_module, cls): ## error-model.h: static ns3::TypeId ns3::ErrorModel::GetTypeId() [member function] - cls.add_method('GetTypeId', 'ns3::TypeId', [], is_static=True) + cls.add_method('GetTypeId', + 'ns3::TypeId', + [], + is_static=True) ## error-model.h: ns3::ErrorModel::ErrorModel() [constructor] - cls.add_constructor([], visibility='public') + cls.add_constructor([]) ## error-model.h: bool ns3::ErrorModel::IsCorrupt(ns3::Ptr pkt) [member function] - cls.add_method('IsCorrupt', 'bool', [param('ns3::Ptr< ns3::Packet >', 'pkt')]) + cls.add_method('IsCorrupt', + 'bool', + [param('ns3::Ptr< ns3::Packet >', 'pkt')]) ## error-model.h: void ns3::ErrorModel::Reset() [member function] - cls.add_method('Reset', 'void', []) + cls.add_method('Reset', + 'void', + []) ## error-model.h: void ns3::ErrorModel::Enable() [member function] - cls.add_method('Enable', 'void', []) + cls.add_method('Enable', + 'void', + []) ## error-model.h: void ns3::ErrorModel::Disable() [member function] - cls.add_method('Disable', 'void', []) + cls.add_method('Disable', + 'void', + []) ## error-model.h: bool ns3::ErrorModel::IsEnabled() const [member function] - cls.add_method('IsEnabled', 'bool', [], is_const=True) + cls.add_method('IsEnabled', + 'bool', + [], + is_const=True) ## error-model.h: bool ns3::ErrorModel::DoCorrupt(ns3::Ptr arg0) [member function] - cls.add_method('DoCorrupt', 'bool', [param('ns3::Ptr< ns3::Packet >', 'arg0')], is_pure_virtual=True, visibility='private', is_virtual=True) + cls.add_method('DoCorrupt', + 'bool', + [param('ns3::Ptr< ns3::Packet >', 'arg0')], + is_pure_virtual=True, visibility='private', is_virtual=True) ## error-model.h: void ns3::ErrorModel::DoReset() [member function] - cls.add_method('DoReset', 'void', [], is_pure_virtual=True, visibility='private', is_virtual=True) + cls.add_method('DoReset', + 'void', + [], + is_pure_virtual=True, visibility='private', is_virtual=True) return def register_Ns3Header_methods(root_module, cls): ## header.h: ns3::Header::Header() [constructor] - cls.add_constructor([], visibility='public') + cls.add_constructor([]) ## header.h: ns3::Header::Header(ns3::Header const & arg0) [copy constructor] - cls.add_constructor([param('ns3::Header&', 'arg0', is_const=True)], visibility='public') + cls.add_constructor([param('ns3::Header&', 'arg0', is_const=True)]) ## header.h: uint32_t ns3::Header::Deserialize(ns3::Buffer::Iterator start) [member function] - cls.add_method('Deserialize', 'uint32_t', [param('ns3::Buffer::Iterator', 'start')], is_pure_virtual=True, is_virtual=True) + cls.add_method('Deserialize', + 'uint32_t', + [param('ns3::Buffer::Iterator', 'start')], + is_pure_virtual=True, is_virtual=True) ## header.h: uint32_t ns3::Header::GetSerializedSize() const [member function] - cls.add_method('GetSerializedSize', 'uint32_t', [], is_pure_virtual=True, is_const=True, is_virtual=True) + cls.add_method('GetSerializedSize', + 'uint32_t', + [], + is_pure_virtual=True, is_const=True, is_virtual=True) ## header.h: static ns3::TypeId ns3::Header::GetTypeId() [member function] - cls.add_method('GetTypeId', 'ns3::TypeId', [], is_static=True) + cls.add_method('GetTypeId', + 'ns3::TypeId', + [], + is_static=True) ## header.h: void ns3::Header::Print(std::ostream & os) const [member function] - cls.add_method('Print', 'void', [param('std::ostream&', 'os')], is_pure_virtual=True, is_const=True, is_virtual=True) + cls.add_method('Print', + 'void', + [param('std::ostream&', 'os')], + is_pure_virtual=True, is_const=True, is_virtual=True) ## header.h: void ns3::Header::Serialize(ns3::Buffer::Iterator start) const [member function] - cls.add_method('Serialize', 'void', [param('ns3::Buffer::Iterator', 'start')], is_pure_virtual=True, is_const=True, is_virtual=True) + cls.add_method('Serialize', + 'void', + [param('ns3::Buffer::Iterator', 'start')], + is_pure_virtual=True, is_const=True, is_virtual=True) cls.add_output_stream_operator() return def register_Ns3Trailer_methods(root_module, cls): ## trailer.h: ns3::Trailer::Trailer() [constructor] - cls.add_constructor([], visibility='public') + cls.add_constructor([]) ## trailer.h: ns3::Trailer::Trailer(ns3::Trailer const & arg0) [copy constructor] - cls.add_constructor([param('ns3::Trailer&', 'arg0', is_const=True)], visibility='public') + cls.add_constructor([param('ns3::Trailer&', 'arg0', is_const=True)]) ## trailer.h: uint32_t ns3::Trailer::Deserialize(ns3::Buffer::Iterator end) [member function] - cls.add_method('Deserialize', 'uint32_t', [param('ns3::Buffer::Iterator', 'end')], is_pure_virtual=True, is_virtual=True) + cls.add_method('Deserialize', + 'uint32_t', + [param('ns3::Buffer::Iterator', 'end')], + is_pure_virtual=True, is_virtual=True) ## trailer.h: uint32_t ns3::Trailer::GetSerializedSize() const [member function] - cls.add_method('GetSerializedSize', 'uint32_t', [], is_pure_virtual=True, is_const=True, is_virtual=True) + cls.add_method('GetSerializedSize', + 'uint32_t', + [], + is_pure_virtual=True, is_const=True, is_virtual=True) ## trailer.h: static ns3::TypeId ns3::Trailer::GetTypeId() [member function] - cls.add_method('GetTypeId', 'ns3::TypeId', [], is_static=True) + cls.add_method('GetTypeId', + 'ns3::TypeId', + [], + is_static=True) ## trailer.h: void ns3::Trailer::Print(std::ostream & os) const [member function] - cls.add_method('Print', 'void', [param('std::ostream&', 'os')], is_pure_virtual=True, is_const=True, is_virtual=True) + cls.add_method('Print', + 'void', + [param('std::ostream&', 'os')], + is_pure_virtual=True, is_const=True, is_virtual=True) ## trailer.h: void ns3::Trailer::Serialize(ns3::Buffer::Iterator start) const [member function] - cls.add_method('Serialize', 'void', [param('ns3::Buffer::Iterator', 'start')], is_pure_virtual=True, is_const=True, is_virtual=True) + cls.add_method('Serialize', + 'void', + [param('ns3::Buffer::Iterator', 'start')], + is_pure_virtual=True, is_const=True, is_virtual=True) cls.add_output_stream_operator() return def register_Ns3ListErrorModel_methods(root_module, cls): ## error-model.h: static ns3::TypeId ns3::ListErrorModel::GetTypeId() [member function] - cls.add_method('GetTypeId', 'ns3::TypeId', [], is_static=True) + cls.add_method('GetTypeId', + 'ns3::TypeId', + [], + is_static=True) ## error-model.h: ns3::ListErrorModel::ListErrorModel() [constructor] - cls.add_constructor([], visibility='public') + cls.add_constructor([]) ## error-model.h: std::list > ns3::ListErrorModel::GetList() const [member function] - cls.add_method('GetList', 'std::list< unsigned int, std::allocator< unsigned int > >', [], is_const=True) + cls.add_method('GetList', + 'std::list< unsigned int, std::allocator< unsigned int > >', + [], + is_const=True) ## error-model.h: void ns3::ListErrorModel::SetList(std::list > const & packetlist) [member function] - cls.add_method('SetList', 'void', [param('std::list< unsigned int, std::allocator< unsigned int > >&', 'packetlist', is_const=True)]) + cls.add_method('SetList', + 'void', + [param('std::list< unsigned int, std::allocator< unsigned int > >&', 'packetlist', is_const=True)]) ## error-model.h: bool ns3::ListErrorModel::DoCorrupt(ns3::Ptr p) [member function] - cls.add_method('DoCorrupt', 'bool', [param('ns3::Ptr< ns3::Packet >', 'p')], visibility='private', is_virtual=True) + cls.add_method('DoCorrupt', + 'bool', + [param('ns3::Ptr< ns3::Packet >', 'p')], + visibility='private', is_virtual=True) ## error-model.h: void ns3::ListErrorModel::DoReset() [member function] - cls.add_method('DoReset', 'void', [], visibility='private', is_virtual=True) + cls.add_method('DoReset', + 'void', + [], + visibility='private', is_virtual=True) return def register_Ns3DataRateValue_methods(root_module, cls): ## data-rate.h: ns3::DataRateValue::DataRateValue() [constructor] - cls.add_constructor([], visibility='public') + cls.add_constructor([]) ## data-rate.h: ns3::DataRateValue::DataRateValue(ns3::DataRate const & value) [constructor] - cls.add_constructor([param('ns3::DataRate&', 'value', is_const=True)], visibility='public') + cls.add_constructor([param('ns3::DataRate&', 'value', is_const=True)]) ## data-rate.h: void ns3::DataRateValue::Set(ns3::DataRate const & value) [member function] - cls.add_method('Set', 'void', [param('ns3::DataRate&', 'value', is_const=True)]) + cls.add_method('Set', + 'void', + [param('ns3::DataRate&', 'value', is_const=True)]) ## data-rate.h: ns3::DataRate ns3::DataRateValue::Get() const [member function] - cls.add_method('Get', 'ns3::DataRate', [], is_const=True) + cls.add_method('Get', + 'ns3::DataRate', + [], + is_const=True) ## data-rate.h: ns3::Ptr ns3::DataRateValue::Copy() const [member function] - cls.add_method('Copy', 'ns3::Ptr< ns3::AttributeValue >', [], is_const=True, is_virtual=True) + cls.add_method('Copy', + 'ns3::Ptr< ns3::AttributeValue >', + [], + is_const=True, is_virtual=True) ## data-rate.h: std::string ns3::DataRateValue::SerializeToString(ns3::Ptr checker) const [member function] - cls.add_method('SerializeToString', 'std::string', [param('ns3::Ptr< ns3::AttributeChecker const >', 'checker')], is_const=True, is_virtual=True) + cls.add_method('SerializeToString', + 'std::string', + [param('ns3::Ptr< ns3::AttributeChecker const >', 'checker')], + is_const=True, is_virtual=True) ## data-rate.h: bool ns3::DataRateValue::DeserializeFromString(std::string value, ns3::Ptr checker) [member function] - cls.add_method('DeserializeFromString', 'bool', [param('std::string', 'value'), param('ns3::Ptr< ns3::AttributeChecker const >', 'checker')], is_virtual=True) + cls.add_method('DeserializeFromString', + 'bool', + [param('std::string', 'value'), param('ns3::Ptr< ns3::AttributeChecker const >', 'checker')], + is_virtual=True) return def register_Ns3RateErrorModel_methods(root_module, cls): ## error-model.h: static ns3::TypeId ns3::RateErrorModel::GetTypeId() [member function] - cls.add_method('GetTypeId', 'ns3::TypeId', [], is_static=True) + cls.add_method('GetTypeId', + 'ns3::TypeId', + [], + is_static=True) ## error-model.h: ns3::RateErrorModel::RateErrorModel() [constructor] - cls.add_constructor([], visibility='public') + cls.add_constructor([]) ## error-model.h: ns3::ErrorUnit ns3::RateErrorModel::GetUnit() const [member function] - cls.add_method('GetUnit', 'ns3::ErrorUnit', [], is_const=True) + cls.add_method('GetUnit', + 'ns3::ErrorUnit', + [], + is_const=True) ## error-model.h: void ns3::RateErrorModel::SetUnit(ns3::ErrorUnit error_unit) [member function] - cls.add_method('SetUnit', 'void', [param('ns3::ErrorUnit', 'error_unit')]) + cls.add_method('SetUnit', + 'void', + [param('ns3::ErrorUnit', 'error_unit')]) ## error-model.h: double ns3::RateErrorModel::GetRate() const [member function] - cls.add_method('GetRate', 'double', [], is_const=True) + cls.add_method('GetRate', + 'double', + [], + is_const=True) ## error-model.h: void ns3::RateErrorModel::SetRate(double rate) [member function] - cls.add_method('SetRate', 'void', [param('double', 'rate')]) + cls.add_method('SetRate', + 'void', + [param('double', 'rate')]) ## error-model.h: void ns3::RateErrorModel::SetRandomVariable(ns3::RandomVariable const & ranvar) [member function] - cls.add_method('SetRandomVariable', 'void', [param('ns3::RandomVariable&', 'ranvar', is_const=True)]) + cls.add_method('SetRandomVariable', + 'void', + [param('ns3::RandomVariable&', 'ranvar', is_const=True)]) ## error-model.h: bool ns3::RateErrorModel::DoCorrupt(ns3::Ptr p) [member function] - cls.add_method('DoCorrupt', 'bool', [param('ns3::Ptr< ns3::Packet >', 'p')], visibility='private', is_virtual=True) + cls.add_method('DoCorrupt', + 'bool', + [param('ns3::Ptr< ns3::Packet >', 'p')], + visibility='private', is_virtual=True) ## error-model.h: bool ns3::RateErrorModel::DoCorruptPkt(ns3::Ptr p) [member function] - cls.add_method('DoCorruptPkt', 'bool', [param('ns3::Ptr< ns3::Packet >', 'p')], visibility='private', is_virtual=True) + cls.add_method('DoCorruptPkt', + 'bool', + [param('ns3::Ptr< ns3::Packet >', 'p')], + visibility='private', is_virtual=True) ## error-model.h: bool ns3::RateErrorModel::DoCorruptByte(ns3::Ptr p) [member function] - cls.add_method('DoCorruptByte', 'bool', [param('ns3::Ptr< ns3::Packet >', 'p')], visibility='private', is_virtual=True) + cls.add_method('DoCorruptByte', + 'bool', + [param('ns3::Ptr< ns3::Packet >', 'p')], + visibility='private', is_virtual=True) ## error-model.h: bool ns3::RateErrorModel::DoCorruptBit(ns3::Ptr p) [member function] - cls.add_method('DoCorruptBit', 'bool', [param('ns3::Ptr< ns3::Packet >', 'p')], visibility='private', is_virtual=True) + cls.add_method('DoCorruptBit', + 'bool', + [param('ns3::Ptr< ns3::Packet >', 'p')], + visibility='private', is_virtual=True) ## error-model.h: void ns3::RateErrorModel::DoReset() [member function] - cls.add_method('DoReset', 'void', [], visibility='private', is_virtual=True) + cls.add_method('DoReset', + 'void', + [], + visibility='private', is_virtual=True) return def register_functions(root_module): module = root_module ## data-rate.h: extern ns3::Ptr ns3::MakeDataRateChecker() [free function] - module.add_function('MakeDataRateChecker', 'ns3::Ptr< ns3::AttributeChecker const >', []) + module.add_function('MakeDataRateChecker', + 'ns3::Ptr< ns3::AttributeChecker const >', + []) register_functions_ns3_internal(module.get_submodule('internal'), root_module) register_functions_ns3_TimeStepPrecision(module.get_submodule('TimeStepPrecision'), root_module) register_functions_ns3_Config(module.get_submodule('Config'), root_module) diff --git a/bindings/python/ns3_module_contrib.py b/bindings/python/ns3_module_contrib.py index 550413ff7..ab97841b7 100644 --- a/bindings/python/ns3_module_contrib.py +++ b/bindings/python/ns3_module_contrib.py @@ -1,4 +1,4 @@ -from pybindgen import Module, FileCodeSink, write_preamble, param, retval +from pybindgen import Module, FileCodeSink, param, retval, cppclass def register_types(module): root_module = module.get_root() @@ -71,66 +71,103 @@ def register_methods(root_module): def register_Ns3Gnuplot_methods(root_module, cls): ## gnuplot.h: ns3::Gnuplot::Gnuplot(std::string pngFilename) [constructor] - cls.add_constructor([param('std::string', 'pngFilename')], visibility='public') + cls.add_constructor([param('std::string', 'pngFilename')]) ## gnuplot.h: void ns3::Gnuplot::SetLegend(std::string xLegend, std::string yLegend) [member function] - cls.add_method('SetLegend', 'void', [param('std::string', 'xLegend'), param('std::string', 'yLegend')]) + cls.add_method('SetLegend', + 'void', + [param('std::string', 'xLegend'), param('std::string', 'yLegend')]) ## gnuplot.h: void ns3::Gnuplot::AddDataset(ns3::GnuplotDataset const & dataset) [member function] - cls.add_method('AddDataset', 'void', [param('ns3::GnuplotDataset&', 'dataset', is_const=True)]) + cls.add_method('AddDataset', + 'void', + [param('ns3::GnuplotDataset&', 'dataset', is_const=True)]) ## gnuplot.h: void ns3::Gnuplot::GenerateOutput(std::ostream & os) [member function] - cls.add_method('GenerateOutput', 'void', [param('std::ostream&', 'os')]) + cls.add_method('GenerateOutput', + 'void', + [param('std::ostream&', 'os')]) return def register_Ns3EventGarbageCollector_methods(root_module, cls): ## event-garbage-collector.h: ns3::EventGarbageCollector::EventGarbageCollector() [constructor] - cls.add_constructor([], visibility='public') + cls.add_constructor([]) ## event-garbage-collector.h: void ns3::EventGarbageCollector::Track(ns3::EventId event) [member function] - cls.add_method('Track', 'void', [param('ns3::EventId', 'event')]) + cls.add_method('Track', + 'void', + [param('ns3::EventId', 'event')]) return def register_Ns3GnuplotDataset_methods(root_module, cls): ## gnuplot.h: ns3::GnuplotDataset::GnuplotDataset() [constructor] - cls.add_constructor([], visibility='public') + cls.add_constructor([]) ## gnuplot.h: ns3::GnuplotDataset::GnuplotDataset(std::string title) [constructor] - cls.add_constructor([param('std::string', 'title')], visibility='public') + cls.add_constructor([param('std::string', 'title')]) ## gnuplot.h: void ns3::GnuplotDataset::SetStyle(ns3::GnuplotDataset::Style style) [member function] - cls.add_method('SetStyle', 'void', [param('ns3::GnuplotDataset::Style', 'style')]) + cls.add_method('SetStyle', + 'void', + [param('ns3::GnuplotDataset::Style', 'style')]) ## gnuplot.h: void ns3::GnuplotDataset::SetErrorBars(ns3::GnuplotDataset::ErrorBars errorBars) [member function] - cls.add_method('SetErrorBars', 'void', [param('ns3::GnuplotDataset::ErrorBars', 'errorBars')]) + cls.add_method('SetErrorBars', + 'void', + [param('ns3::GnuplotDataset::ErrorBars', 'errorBars')]) ## gnuplot.h: void ns3::GnuplotDataset::Add(double x, double y) [member function] - cls.add_method('Add', 'void', [param('double', 'x'), param('double', 'y')]) + cls.add_method('Add', + 'void', + [param('double', 'x'), param('double', 'y')]) ## gnuplot.h: void ns3::GnuplotDataset::Add(double x, double y, double errorDelta) [member function] - cls.add_method('Add', 'void', [param('double', 'x'), param('double', 'y'), param('double', 'errorDelta')]) + cls.add_method('Add', + 'void', + [param('double', 'x'), param('double', 'y'), param('double', 'errorDelta')]) return def register_Ns3GtkConfigStore_methods(root_module, cls): ## gtk-config-store.h: ns3::GtkConfigStore::GtkConfigStore() [constructor] - cls.add_constructor([], visibility='public') + cls.add_constructor([]) ## gtk-config-store.h: void ns3::GtkConfigStore::Configure() [member function] - cls.add_method('Configure', 'void', []) + cls.add_method('Configure', + 'void', + []) return def register_Ns3ConfigStore_methods(root_module, cls): ## config-store.h: static ns3::TypeId ns3::ConfigStore::GetTypeId() [member function] - cls.add_method('GetTypeId', 'ns3::TypeId', [], is_static=True) + cls.add_method('GetTypeId', + 'ns3::TypeId', + [], + is_static=True) ## config-store.h: ns3::TypeId ns3::ConfigStore::GetInstanceTypeId() const [member function] - cls.add_method('GetInstanceTypeId', 'ns3::TypeId', [], is_const=True, is_virtual=True) + cls.add_method('GetInstanceTypeId', + 'ns3::TypeId', + [], + is_const=True, is_virtual=True) ## config-store.h: ns3::ConfigStore::ConfigStore() [constructor] - cls.add_constructor([], visibility='public') + cls.add_constructor([]) ## config-store.h: void ns3::ConfigStore::Configure() [member function] - cls.add_method('Configure', 'void', []) + cls.add_method('Configure', + 'void', + []) return def register_Ns3DelayJitterEstimation_methods(root_module, cls): ## delay-jitter-estimation.h: ns3::DelayJitterEstimation::DelayJitterEstimation() [constructor] - cls.add_constructor([], visibility='public') + cls.add_constructor([]) ## delay-jitter-estimation.h: static void ns3::DelayJitterEstimation::PrepareTx(ns3::Ptr packet) [member function] - cls.add_method('PrepareTx', 'void', [param('ns3::Ptr< const ns3::Packet >', 'packet')], is_static=True) + cls.add_method('PrepareTx', + 'void', + [param('ns3::Ptr< const ns3::Packet >', 'packet')], + is_static=True) ## delay-jitter-estimation.h: void ns3::DelayJitterEstimation::RecordRx(ns3::Ptr packet) [member function] - cls.add_method('RecordRx', 'void', [param('ns3::Ptr< const ns3::Packet >', 'packet')]) + cls.add_method('RecordRx', + 'void', + [param('ns3::Ptr< const ns3::Packet >', 'packet')]) ## delay-jitter-estimation.h: ns3::Time ns3::DelayJitterEstimation::GetLastDelay() const [member function] - cls.add_method('GetLastDelay', 'ns3::Time', [], is_const=True) + cls.add_method('GetLastDelay', + 'ns3::Time', + [], + is_const=True) ## delay-jitter-estimation.h: ns3::Time ns3::DelayJitterEstimation::GetLastJitter() const [member function] - cls.add_method('GetLastJitter', 'ns3::Time', [], is_const=True) + cls.add_method('GetLastJitter', + 'ns3::Time', + [], + is_const=True) return def register_functions(root_module): diff --git a/bindings/python/ns3_module_core.py b/bindings/python/ns3_module_core.py index a9a3b35d9..2e27dd214 100644 --- a/bindings/python/ns3_module_core.py +++ b/bindings/python/ns3_module_core.py @@ -1,4 +1,4 @@ -from pybindgen import Module, FileCodeSink, write_preamble, param, retval +from pybindgen import Module, FileCodeSink, param, retval, cppclass def register_types(module): root_module = module.get_root() @@ -10,7 +10,7 @@ def register_types(module): ## global-value.h: ns3::GlobalValue [class] module.add_class('GlobalValue') ## ref-count-base.h: ns3::RefCountBase [class] - module.add_class('RefCountBase', incref_method='Ref', automatic_type_narrowing=True, decref_method='Unref', peekref_method='GetReferenceCount') + module.add_class('RefCountBase', automatic_type_narrowing=True, memory_policy=cppclass.ReferenceCountingMethodsPolicy(incref_method='Ref', decref_method='Unref', peekref_method='GetReferenceCount')) ## type-id.h: ns3::TypeId [class] module.add_class('TypeId') ## type-id.h: ns3::TypeId::AttributeFlag [enumeration] @@ -20,13 +20,13 @@ def register_types(module): ## system-wall-clock-ms.h: ns3::SystemWallClockMs [class] module.add_class('SystemWallClockMs') ## callback.h: ns3::CallbackImplBase [class] - module.add_class('CallbackImplBase', incref_method='Ref', allow_subclassing=True, decref_method='Unref', peekref_method='GetReferenceCount') + module.add_class('CallbackImplBase', allow_subclassing=True, memory_policy=cppclass.ReferenceCountingMethodsPolicy(incref_method='Ref', decref_method='Unref', peekref_method='GetReferenceCount')) ## system-mutex.h: ns3::CriticalSection [class] module.add_class('CriticalSection') ## trace-source-accessor.h: ns3::TraceSourceAccessor [class] module.add_class('TraceSourceAccessor', allow_subclassing=True) ## attribute.h: ns3::AttributeChecker [class] - module.add_class('AttributeChecker', incref_method='Ref', allow_subclassing=False, automatic_type_narrowing=True, decref_method='Unref', parent=root_module['ns3::RefCountBase']) + module.add_class('AttributeChecker', allow_subclassing=False, automatic_type_narrowing=True, parent=root_module['ns3::RefCountBase']) ## random-variable.h: ns3::RandomVariableChecker [class] module.add_class('RandomVariableChecker', parent=root_module['ns3::AttributeChecker']) ## system-mutex.h: ns3::SystemMutex [class] @@ -120,11 +120,11 @@ def register_types(module): ## attribute-list.h: ns3::AttributeList [class] module.add_class('AttributeList') ## attribute.h: ns3::AttributeValue [class] - module.add_class('AttributeValue', incref_method='Ref', allow_subclassing=False, automatic_type_narrowing=True, decref_method='Unref', parent=root_module['ns3::RefCountBase']) + module.add_class('AttributeValue', allow_subclassing=False, automatic_type_narrowing=True, parent=root_module['ns3::RefCountBase']) ## random-variable.h: ns3::UniformVariable [class] module.add_class('UniformVariable', parent=root_module['ns3::RandomVariable']) ## object.h: ns3::Object [class] - module.add_class('Object', incref_method='Ref', automatic_type_narrowing=True, decref_method='Unref', parent=root_module['ns3::ObjectBase'], peekref_method='GetReferenceCount') + module.add_class('Object', automatic_type_narrowing=True, parent=root_module['ns3::ObjectBase'], memory_policy=cppclass.ReferenceCountingMethodsPolicy(incref_method='Ref', decref_method='Unref', peekref_method='GetReferenceCount')) ## object.h: ns3::Object::AggregateIterator [class] module.add_class('AggregateIterator', outer_class=root_module['ns3::Object']) ## system-condition.h: ns3::SystemCondition [class] @@ -298,138 +298,280 @@ def register_methods(root_module): def register_Ns3RandomVariable_methods(root_module, cls): ## random-variable.h: ns3::RandomVariable::RandomVariable() [constructor] - cls.add_constructor([], visibility='public') + cls.add_constructor([]) ## random-variable.h: ns3::RandomVariable::RandomVariable(ns3::RandomVariable const & o) [copy constructor] - cls.add_constructor([param('ns3::RandomVariable&', 'o', is_const=True)], visibility='public') + cls.add_constructor([param('ns3::RandomVariable&', 'o', is_const=True)]) ## random-variable.h: uint32_t ns3::RandomVariable::GetInteger() const [member function] - cls.add_method('GetInteger', 'uint32_t', [], is_const=True) + cls.add_method('GetInteger', + 'uint32_t', + [], + is_const=True) ## random-variable.h: void ns3::RandomVariable::GetSeed(uint32_t * seed) const [member function] - cls.add_method('GetSeed', 'void', [param('uint32_t *', 'seed', direction=2, array_length=6)], is_const=True) + cls.add_method('GetSeed', + 'void', + [param('uint32_t *', 'seed', direction=2, array_length=6)], + is_const=True) ## random-variable.h: double ns3::RandomVariable::GetValue() const [member function] - cls.add_method('GetValue', 'double', [], is_const=True) + cls.add_method('GetValue', + 'double', + [], + is_const=True) ## random-variable.h: static void ns3::RandomVariable::SetRunNumber(uint32_t n) [member function] - cls.add_method('SetRunNumber', 'void', [param('uint32_t', 'n')], is_static=True) + cls.add_method('SetRunNumber', + 'void', + [param('uint32_t', 'n')], + is_static=True) ## random-variable.h: static void ns3::RandomVariable::UseDevRandom(bool udr=true) [member function] - cls.add_method('UseDevRandom', 'void', [param('bool', 'udr', default_value='true')], is_static=True) + cls.add_method('UseDevRandom', + 'void', + [param('bool', 'udr', default_value='true')], + is_static=True) ## random-variable.h: static void ns3::RandomVariable::UseGlobalSeed(uint32_t s0, uint32_t s1, uint32_t s2, uint32_t s3, uint32_t s4, uint32_t s5) [member function] - cls.add_method('UseGlobalSeed', 'void', [param('uint32_t', 's0'), param('uint32_t', 's1'), param('uint32_t', 's2'), param('uint32_t', 's3'), param('uint32_t', 's4'), param('uint32_t', 's5')], is_static=True) + cls.add_method('UseGlobalSeed', + 'void', + [param('uint32_t', 's0'), param('uint32_t', 's1'), param('uint32_t', 's2'), param('uint32_t', 's3'), param('uint32_t', 's4'), param('uint32_t', 's5')], + is_static=True) cls.add_output_stream_operator() return def register_Ns3TriangularVariable_methods(root_module, cls): ## random-variable.h: ns3::TriangularVariable::TriangularVariable() [constructor] - cls.add_constructor([], visibility='public') + cls.add_constructor([]) ## random-variable.h: ns3::TriangularVariable::TriangularVariable(double s, double l, double mean) [constructor] - cls.add_constructor([param('double', 's'), param('double', 'l'), param('double', 'mean')], visibility='public') + cls.add_constructor([param('double', 's'), param('double', 'l'), param('double', 'mean')]) ## random-variable.h: static double ns3::TriangularVariable::GetSingleValue(double s, double l, double mean) [member function] - cls.add_method('GetSingleValue', 'double', [param('double', 's'), param('double', 'l'), param('double', 'mean')], is_static=True) + cls.add_method('GetSingleValue', + 'double', + [param('double', 's'), param('double', 'l'), param('double', 'mean')], + is_static=True) return def register_Ns3GlobalValue_methods(root_module, cls): ## global-value.h: ns3::GlobalValue::GlobalValue(std::string name, std::string help, ns3::AttributeValue const & initialValue, ns3::Ptr checker) [constructor] - cls.add_constructor([param('std::string', 'name'), param('std::string', 'help'), param('ns3::AttributeValue&', 'initialValue', is_const=True), param('ns3::Ptr< ns3::AttributeChecker const >', 'checker')], visibility='public') + cls.add_constructor([param('std::string', 'name'), param('std::string', 'help'), param('ns3::AttributeValue&', 'initialValue', is_const=True), param('ns3::Ptr< ns3::AttributeChecker const >', 'checker')]) ## global-value.h: std::string ns3::GlobalValue::GetName() const [member function] - cls.add_method('GetName', 'std::string', [], is_const=True) + cls.add_method('GetName', + 'std::string', + [], + is_const=True) ## global-value.h: std::string ns3::GlobalValue::GetHelp() const [member function] - cls.add_method('GetHelp', 'std::string', [], is_const=True) + cls.add_method('GetHelp', + 'std::string', + [], + is_const=True) ## global-value.h: void ns3::GlobalValue::GetValue(ns3::AttributeValue & value) const [member function] - cls.add_method('GetValue', 'void', [param('ns3::AttributeValue&', 'value')], is_const=True) + cls.add_method('GetValue', + 'void', + [param('ns3::AttributeValue&', 'value')], + is_const=True) ## global-value.h: ns3::Ptr ns3::GlobalValue::GetChecker() const [member function] - cls.add_method('GetChecker', 'ns3::Ptr< ns3::AttributeChecker const >', [], is_const=True) + cls.add_method('GetChecker', + 'ns3::Ptr< ns3::AttributeChecker const >', + [], + is_const=True) ## global-value.h: bool ns3::GlobalValue::SetValue(ns3::AttributeValue const & value) [member function] - cls.add_method('SetValue', 'bool', [param('ns3::AttributeValue&', 'value', is_const=True)]) + cls.add_method('SetValue', + 'bool', + [param('ns3::AttributeValue&', 'value', is_const=True)]) ## global-value.h: static void ns3::GlobalValue::Bind(std::string name, ns3::AttributeValue const & value) [member function] - cls.add_method('Bind', 'void', [param('std::string', 'name'), param('ns3::AttributeValue&', 'value', is_const=True)], is_static=True) + cls.add_method('Bind', + 'void', + [param('std::string', 'name'), param('ns3::AttributeValue&', 'value', is_const=True)], + is_static=True) ## global-value.h: static bool ns3::GlobalValue::BindFailSafe(std::string name, ns3::AttributeValue const & value) [member function] - cls.add_method('BindFailSafe', 'bool', [param('std::string', 'name'), param('ns3::AttributeValue&', 'value', is_const=True)], is_static=True) + cls.add_method('BindFailSafe', + 'bool', + [param('std::string', 'name'), param('ns3::AttributeValue&', 'value', is_const=True)], + is_static=True) ## global-value.h: static __gnu_cxx::__normal_iterator > > ns3::GlobalValue::Begin() [member function] - cls.add_method('Begin', '__gnu_cxx::__normal_iterator< ns3::GlobalValue* const*, std::vector< ns3::GlobalValue*, std::allocator< ns3::GlobalValue* > > >', [], is_static=True) + cls.add_method('Begin', + '__gnu_cxx::__normal_iterator< ns3::GlobalValue* const*, std::vector< ns3::GlobalValue*, std::allocator< ns3::GlobalValue* > > >', + [], + is_static=True) ## global-value.h: static __gnu_cxx::__normal_iterator > > ns3::GlobalValue::End() [member function] - cls.add_method('End', '__gnu_cxx::__normal_iterator< ns3::GlobalValue* const*, std::vector< ns3::GlobalValue*, std::allocator< ns3::GlobalValue* > > >', [], is_static=True) + cls.add_method('End', + '__gnu_cxx::__normal_iterator< ns3::GlobalValue* const*, std::vector< ns3::GlobalValue*, std::allocator< ns3::GlobalValue* > > >', + [], + is_static=True) return def register_Ns3RefCountBase_methods(root_module, cls): ## ref-count-base.h: ns3::RefCountBase::RefCountBase() [constructor] - cls.add_constructor([], visibility='public') + cls.add_constructor([]) ## ref-count-base.h: ns3::RefCountBase::RefCountBase(ns3::RefCountBase const & o) [copy constructor] - cls.add_constructor([param('ns3::RefCountBase&', 'o', is_const=True)], visibility='public') + cls.add_constructor([param('ns3::RefCountBase&', 'o', is_const=True)]) return def register_Ns3TypeId_methods(root_module, cls): ## type-id.h: ns3::TypeId::TypeId(ns3::TypeId const & arg0) [copy constructor] - cls.add_constructor([param('ns3::TypeId&', 'arg0', is_const=True)], visibility='public') + cls.add_constructor([param('ns3::TypeId&', 'arg0', is_const=True)]) ## type-id.h: ns3::TypeId::TypeId(char const * name) [constructor] - cls.add_constructor([param('char *', 'name', transfer_ownership=False, is_const=True)], visibility='public') + cls.add_constructor([param('char *', 'name', transfer_ownership=False, is_const=True)]) ## type-id.h: ns3::TypeId::TypeId() [constructor] - cls.add_constructor([], visibility='public') + cls.add_constructor([]) ## type-id.h: ns3::TypeId ns3::TypeId::AddAttribute(std::string name, std::string help, ns3::AttributeValue const & initialValue, ns3::Ptr accessor, ns3::Ptr checker) [member function] - cls.add_method('AddAttribute', 'ns3::TypeId', [param('std::string', 'name'), param('std::string', 'help'), param('ns3::AttributeValue&', 'initialValue', is_const=True), param('ns3::Ptr< ns3::AttributeAccessor const >', 'accessor'), param('ns3::Ptr< ns3::AttributeChecker const >', 'checker')]) + cls.add_method('AddAttribute', + 'ns3::TypeId', + [param('std::string', 'name'), param('std::string', 'help'), param('ns3::AttributeValue&', 'initialValue', is_const=True), param('ns3::Ptr< ns3::AttributeAccessor const >', 'accessor'), param('ns3::Ptr< ns3::AttributeChecker const >', 'checker')]) ## type-id.h: ns3::TypeId ns3::TypeId::AddAttribute(std::string name, std::string help, uint32_t flags, ns3::AttributeValue const & initialValue, ns3::Ptr accessor, ns3::Ptr checker) [member function] - cls.add_method('AddAttribute', 'ns3::TypeId', [param('std::string', 'name'), param('std::string', 'help'), param('uint32_t', 'flags'), param('ns3::AttributeValue&', 'initialValue', is_const=True), param('ns3::Ptr< ns3::AttributeAccessor const >', 'accessor'), param('ns3::Ptr< ns3::AttributeChecker const >', 'checker')]) + cls.add_method('AddAttribute', + 'ns3::TypeId', + [param('std::string', 'name'), param('std::string', 'help'), param('uint32_t', 'flags'), param('ns3::AttributeValue&', 'initialValue', is_const=True), param('ns3::Ptr< ns3::AttributeAccessor const >', 'accessor'), param('ns3::Ptr< ns3::AttributeChecker const >', 'checker')]) ## type-id.h: ns3::TypeId ns3::TypeId::AddTraceSource(std::string name, std::string help, ns3::Ptr accessor) [member function] - cls.add_method('AddTraceSource', 'ns3::TypeId', [param('std::string', 'name'), param('std::string', 'help'), param('ns3::Ptr< ns3::TraceSourceAccessor const >', 'accessor')]) + cls.add_method('AddTraceSource', + 'ns3::TypeId', + [param('std::string', 'name'), param('std::string', 'help'), param('ns3::Ptr< ns3::TraceSourceAccessor const >', 'accessor')]) ## type-id.h: ns3::Ptr ns3::TypeId::GetAttributeAccessor(uint32_t i) const [member function] - cls.add_method('GetAttributeAccessor', 'ns3::Ptr< ns3::AttributeAccessor const >', [param('uint32_t', 'i')], is_const=True) + cls.add_method('GetAttributeAccessor', + 'ns3::Ptr< ns3::AttributeAccessor const >', + [param('uint32_t', 'i')], + is_const=True) ## type-id.h: ns3::Ptr ns3::TypeId::GetAttributeChecker(uint32_t i) const [member function] - cls.add_method('GetAttributeChecker', 'ns3::Ptr< ns3::AttributeChecker const >', [param('uint32_t', 'i')], is_const=True) + cls.add_method('GetAttributeChecker', + 'ns3::Ptr< ns3::AttributeChecker const >', + [param('uint32_t', 'i')], + is_const=True) ## type-id.h: uint32_t ns3::TypeId::GetAttributeFlags(uint32_t i) const [member function] - cls.add_method('GetAttributeFlags', 'uint32_t', [param('uint32_t', 'i')], is_const=True) + cls.add_method('GetAttributeFlags', + 'uint32_t', + [param('uint32_t', 'i')], + is_const=True) ## type-id.h: std::string ns3::TypeId::GetAttributeFullName(uint32_t i) const [member function] - cls.add_method('GetAttributeFullName', 'std::string', [param('uint32_t', 'i')], is_const=True) + cls.add_method('GetAttributeFullName', + 'std::string', + [param('uint32_t', 'i')], + is_const=True) ## type-id.h: std::string ns3::TypeId::GetAttributeHelp(uint32_t i) const [member function] - cls.add_method('GetAttributeHelp', 'std::string', [param('uint32_t', 'i')], is_const=True) + cls.add_method('GetAttributeHelp', + 'std::string', + [param('uint32_t', 'i')], + is_const=True) ## type-id.h: ns3::Ptr ns3::TypeId::GetAttributeInitialValue(uint32_t i) const [member function] - cls.add_method('GetAttributeInitialValue', 'ns3::Ptr< ns3::AttributeValue const >', [param('uint32_t', 'i')], is_const=True) + cls.add_method('GetAttributeInitialValue', + 'ns3::Ptr< ns3::AttributeValue const >', + [param('uint32_t', 'i')], + is_const=True) ## type-id.h: uint32_t ns3::TypeId::GetAttributeN() const [member function] - cls.add_method('GetAttributeN', 'uint32_t', [], is_const=True) + cls.add_method('GetAttributeN', + 'uint32_t', + [], + is_const=True) ## type-id.h: std::string ns3::TypeId::GetAttributeName(uint32_t i) const [member function] - cls.add_method('GetAttributeName', 'std::string', [param('uint32_t', 'i')], is_const=True) + cls.add_method('GetAttributeName', + 'std::string', + [param('uint32_t', 'i')], + is_const=True) ## type-id.h: ns3::Callback ns3::TypeId::GetConstructor() const [member function] - cls.add_method('GetConstructor', 'ns3::Callback< ns3::ObjectBase*, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty >', [], is_const=True) + cls.add_method('GetConstructor', + 'ns3::Callback< ns3::ObjectBase*, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty >', + [], + is_const=True) ## type-id.h: std::string ns3::TypeId::GetGroupName() const [member function] - cls.add_method('GetGroupName', 'std::string', [], is_const=True) + cls.add_method('GetGroupName', + 'std::string', + [], + is_const=True) ## type-id.h: std::string ns3::TypeId::GetName() const [member function] - cls.add_method('GetName', 'std::string', [], is_const=True) + cls.add_method('GetName', + 'std::string', + [], + is_const=True) ## type-id.h: ns3::TypeId ns3::TypeId::GetParent() const [member function] - cls.add_method('GetParent', 'ns3::TypeId', [], is_const=True) + cls.add_method('GetParent', + 'ns3::TypeId', + [], + is_const=True) ## type-id.h: static ns3::TypeId ns3::TypeId::GetRegistered(uint32_t i) [member function] - cls.add_method('GetRegistered', 'ns3::TypeId', [param('uint32_t', 'i')], is_static=True) + cls.add_method('GetRegistered', + 'ns3::TypeId', + [param('uint32_t', 'i')], + is_static=True) ## type-id.h: static uint32_t ns3::TypeId::GetRegisteredN() [member function] - cls.add_method('GetRegisteredN', 'uint32_t', [], is_static=True) + cls.add_method('GetRegisteredN', + 'uint32_t', + [], + is_static=True) ## type-id.h: ns3::Ptr ns3::TypeId::GetTraceSourceAccessor(uint32_t i) const [member function] - cls.add_method('GetTraceSourceAccessor', 'ns3::Ptr< ns3::TraceSourceAccessor const >', [param('uint32_t', 'i')], is_const=True) + cls.add_method('GetTraceSourceAccessor', + 'ns3::Ptr< ns3::TraceSourceAccessor const >', + [param('uint32_t', 'i')], + is_const=True) ## type-id.h: std::string ns3::TypeId::GetTraceSourceHelp(uint32_t i) const [member function] - cls.add_method('GetTraceSourceHelp', 'std::string', [param('uint32_t', 'i')], is_const=True) + cls.add_method('GetTraceSourceHelp', + 'std::string', + [param('uint32_t', 'i')], + is_const=True) ## type-id.h: uint32_t ns3::TypeId::GetTraceSourceN() const [member function] - cls.add_method('GetTraceSourceN', 'uint32_t', [], is_const=True) + cls.add_method('GetTraceSourceN', + 'uint32_t', + [], + is_const=True) ## type-id.h: std::string ns3::TypeId::GetTraceSourceName(uint32_t i) const [member function] - cls.add_method('GetTraceSourceName', 'std::string', [param('uint32_t', 'i')], is_const=True) + cls.add_method('GetTraceSourceName', + 'std::string', + [param('uint32_t', 'i')], + is_const=True) ## type-id.h: uint16_t ns3::TypeId::GetUid() const [member function] - cls.add_method('GetUid', 'uint16_t', [], is_const=True) + cls.add_method('GetUid', + 'uint16_t', + [], + is_const=True) ## type-id.h: bool ns3::TypeId::HasConstructor() const [member function] - cls.add_method('HasConstructor', 'bool', [], is_const=True) + cls.add_method('HasConstructor', + 'bool', + [], + is_const=True) ## type-id.h: bool ns3::TypeId::HasParent() const [member function] - cls.add_method('HasParent', 'bool', [], is_const=True) + cls.add_method('HasParent', + 'bool', + [], + is_const=True) ## type-id.h: ns3::TypeId ns3::TypeId::HideFromDocumentation() [member function] - cls.add_method('HideFromDocumentation', 'ns3::TypeId', []) + cls.add_method('HideFromDocumentation', + 'ns3::TypeId', + []) ## type-id.h: bool ns3::TypeId::IsChildOf(ns3::TypeId other) const [member function] - cls.add_method('IsChildOf', 'bool', [param('ns3::TypeId', 'other')], is_const=True) + cls.add_method('IsChildOf', + 'bool', + [param('ns3::TypeId', 'other')], + is_const=True) ## type-id.h: bool ns3::TypeId::LookupAttributeByName(std::string name, ns3::TypeId::AttributeInfo * info) const [member function] - cls.add_method('LookupAttributeByName', 'bool', [param('std::string', 'name'), param('ns3::TypeId::AttributeInfo *', 'info', transfer_ownership=False)], is_const=True) + cls.add_method('LookupAttributeByName', + 'bool', + [param('std::string', 'name'), param('ns3::TypeId::AttributeInfo *', 'info', transfer_ownership=False)], + is_const=True) ## type-id.h: static ns3::TypeId ns3::TypeId::LookupByName(std::string name) [member function] - cls.add_method('LookupByName', 'ns3::TypeId', [param('std::string', 'name')], is_static=True) + cls.add_method('LookupByName', + 'ns3::TypeId', + [param('std::string', 'name')], + is_static=True) ## type-id.h: static bool ns3::TypeId::LookupByNameFailSafe(std::string name, ns3::TypeId * tid) [member function] - cls.add_method('LookupByNameFailSafe', 'bool', [param('std::string', 'name'), param('ns3::TypeId *', 'tid', transfer_ownership=False)], is_static=True) + cls.add_method('LookupByNameFailSafe', + 'bool', + [param('std::string', 'name'), param('ns3::TypeId *', 'tid', transfer_ownership=False)], + is_static=True) ## type-id.h: ns3::Ptr ns3::TypeId::LookupTraceSourceByName(std::string name) const [member function] - cls.add_method('LookupTraceSourceByName', 'ns3::Ptr< ns3::TraceSourceAccessor const >', [param('std::string', 'name')], is_const=True) + cls.add_method('LookupTraceSourceByName', + 'ns3::Ptr< ns3::TraceSourceAccessor const >', + [param('std::string', 'name')], + is_const=True) ## type-id.h: bool ns3::TypeId::MustHideFromDocumentation() const [member function] - cls.add_method('MustHideFromDocumentation', 'bool', [], is_const=True) + cls.add_method('MustHideFromDocumentation', + 'bool', + [], + is_const=True) ## type-id.h: ns3::TypeId ns3::TypeId::SetGroupName(std::string groupName) [member function] - cls.add_method('SetGroupName', 'ns3::TypeId', [param('std::string', 'groupName')]) + cls.add_method('SetGroupName', + 'ns3::TypeId', + [param('std::string', 'groupName')]) ## type-id.h: ns3::TypeId ns3::TypeId::SetParent(ns3::TypeId tid) [member function] - cls.add_method('SetParent', 'ns3::TypeId', [param('ns3::TypeId', 'tid')]) + cls.add_method('SetParent', + 'ns3::TypeId', + [param('ns3::TypeId', 'tid')]) ## type-id.h: void ns3::TypeId::SetUid(uint16_t tid) [member function] - cls.add_method('SetUid', 'void', [param('uint16_t', 'tid')]) + cls.add_method('SetUid', + 'void', + [param('uint16_t', 'tid')]) cls.add_output_stream_operator() return @@ -447,57 +589,100 @@ def register_Ns3TypeIdAttributeInfo_methods(root_module, cls): def register_Ns3SystemWallClockMs_methods(root_module, cls): ## system-wall-clock-ms.h: ns3::SystemWallClockMs::SystemWallClockMs() [constructor] - cls.add_constructor([], visibility='public') + cls.add_constructor([]) ## system-wall-clock-ms.h: void ns3::SystemWallClockMs::Start() [member function] - cls.add_method('Start', 'void', []) + cls.add_method('Start', + 'void', + []) ## system-wall-clock-ms.h: long long unsigned int ns3::SystemWallClockMs::End() [member function] - cls.add_method('End', 'long long unsigned int', []) + cls.add_method('End', + 'long long unsigned int', + []) return def register_Ns3CallbackImplBase_methods(root_module, cls): ## callback.h: ns3::CallbackImplBase::CallbackImplBase() [constructor] - cls.add_constructor([], visibility='public') + cls.add_constructor([]) ## callback.h: bool ns3::CallbackImplBase::IsEqual(ns3::Ptr other) const [member function] - cls.add_method('IsEqual', 'bool', [param('ns3::Ptr< ns3::CallbackImplBase const >', 'other')], is_pure_virtual=True, is_const=True, is_virtual=True) + cls.add_method('IsEqual', + 'bool', + [param('ns3::Ptr< ns3::CallbackImplBase const >', 'other')], + is_pure_virtual=True, is_const=True, is_virtual=True) return def register_Ns3CriticalSection_methods(root_module, cls): ## system-mutex.h: ns3::CriticalSection::CriticalSection(ns3::SystemMutex & mutex) [constructor] - cls.add_constructor([param('ns3::SystemMutex&', 'mutex')], visibility='public') + cls.add_constructor([param('ns3::SystemMutex&', 'mutex')]) return def register_Ns3TraceSourceAccessor_methods(root_module, cls): ## trace-source-accessor.h: ns3::TraceSourceAccessor::TraceSourceAccessor() [constructor] - cls.add_constructor([], visibility='public') + cls.add_constructor([]) ## trace-source-accessor.h: void ns3::TraceSourceAccessor::Ref() const [member function] - cls.add_method('Ref', 'void', [], is_const=True) + cls.add_method('Ref', + 'void', + [], + is_const=True) ## trace-source-accessor.h: void ns3::TraceSourceAccessor::Unref() const [member function] - cls.add_method('Unref', 'void', [], is_const=True) + cls.add_method('Unref', + 'void', + [], + is_const=True) ## trace-source-accessor.h: bool ns3::TraceSourceAccessor::ConnectWithoutContext(ns3::ObjectBase * obj, ns3::CallbackBase const & cb) const [member function] - cls.add_method('ConnectWithoutContext', 'bool', [param('ns3::ObjectBase *', 'obj', transfer_ownership=False), param('ns3::CallbackBase&', 'cb', is_const=True)], is_pure_virtual=True, is_const=True, is_virtual=True) + cls.add_method('ConnectWithoutContext', + 'bool', + [param('ns3::ObjectBase *', 'obj', transfer_ownership=False), param('ns3::CallbackBase&', 'cb', is_const=True)], + is_pure_virtual=True, is_const=True, is_virtual=True) ## trace-source-accessor.h: bool ns3::TraceSourceAccessor::Connect(ns3::ObjectBase * obj, std::string context, ns3::CallbackBase const & cb) const [member function] - cls.add_method('Connect', 'bool', [param('ns3::ObjectBase *', 'obj', transfer_ownership=False), param('std::string', 'context'), param('ns3::CallbackBase&', 'cb', is_const=True)], is_pure_virtual=True, is_const=True, is_virtual=True) + cls.add_method('Connect', + 'bool', + [param('ns3::ObjectBase *', 'obj', transfer_ownership=False), param('std::string', 'context'), param('ns3::CallbackBase&', 'cb', is_const=True)], + is_pure_virtual=True, is_const=True, is_virtual=True) ## trace-source-accessor.h: bool ns3::TraceSourceAccessor::DisconnectWithoutContext(ns3::ObjectBase * obj, ns3::CallbackBase const & cb) const [member function] - cls.add_method('DisconnectWithoutContext', 'bool', [param('ns3::ObjectBase *', 'obj', transfer_ownership=False), param('ns3::CallbackBase&', 'cb', is_const=True)], is_pure_virtual=True, is_const=True, is_virtual=True) + cls.add_method('DisconnectWithoutContext', + 'bool', + [param('ns3::ObjectBase *', 'obj', transfer_ownership=False), param('ns3::CallbackBase&', 'cb', is_const=True)], + is_pure_virtual=True, is_const=True, is_virtual=True) ## trace-source-accessor.h: bool ns3::TraceSourceAccessor::Disconnect(ns3::ObjectBase * obj, std::string context, ns3::CallbackBase const & cb) const [member function] - cls.add_method('Disconnect', 'bool', [param('ns3::ObjectBase *', 'obj', transfer_ownership=False), param('std::string', 'context'), param('ns3::CallbackBase&', 'cb', is_const=True)], is_pure_virtual=True, is_const=True, is_virtual=True) + cls.add_method('Disconnect', + 'bool', + [param('ns3::ObjectBase *', 'obj', transfer_ownership=False), param('std::string', 'context'), param('ns3::CallbackBase&', 'cb', is_const=True)], + is_pure_virtual=True, is_const=True, is_virtual=True) return def register_Ns3AttributeChecker_methods(root_module, cls): ## attribute.h: ns3::AttributeChecker::AttributeChecker() [constructor] - cls.add_constructor([], visibility='public') + cls.add_constructor([]) ## attribute.h: bool ns3::AttributeChecker::Check(ns3::AttributeValue const & value) const [member function] - cls.add_method('Check', 'bool', [param('ns3::AttributeValue&', 'value', is_const=True)], is_pure_virtual=True, is_const=True, is_virtual=True) + cls.add_method('Check', + 'bool', + [param('ns3::AttributeValue&', 'value', is_const=True)], + is_pure_virtual=True, is_const=True, is_virtual=True) ## attribute.h: std::string ns3::AttributeChecker::GetValueTypeName() const [member function] - cls.add_method('GetValueTypeName', 'std::string', [], is_pure_virtual=True, is_const=True, is_virtual=True) + cls.add_method('GetValueTypeName', + 'std::string', + [], + is_pure_virtual=True, is_const=True, is_virtual=True) ## attribute.h: bool ns3::AttributeChecker::HasUnderlyingTypeInformation() const [member function] - cls.add_method('HasUnderlyingTypeInformation', 'bool', [], is_pure_virtual=True, is_const=True, is_virtual=True) + cls.add_method('HasUnderlyingTypeInformation', + 'bool', + [], + is_pure_virtual=True, is_const=True, is_virtual=True) ## attribute.h: std::string ns3::AttributeChecker::GetUnderlyingTypeInformation() const [member function] - cls.add_method('GetUnderlyingTypeInformation', 'std::string', [], is_pure_virtual=True, is_const=True, is_virtual=True) + cls.add_method('GetUnderlyingTypeInformation', + 'std::string', + [], + is_pure_virtual=True, is_const=True, is_virtual=True) ## attribute.h: ns3::Ptr ns3::AttributeChecker::Create() const [member function] - cls.add_method('Create', 'ns3::Ptr< ns3::AttributeValue >', [], is_pure_virtual=True, is_const=True, is_virtual=True) + cls.add_method('Create', + 'ns3::Ptr< ns3::AttributeValue >', + [], + is_pure_virtual=True, is_const=True, is_virtual=True) ## attribute.h: bool ns3::AttributeChecker::Copy(ns3::AttributeValue const & source, ns3::AttributeValue & destination) const [member function] - cls.add_method('Copy', 'bool', [param('ns3::AttributeValue&', 'source', is_const=True), param('ns3::AttributeValue&', 'destination')], is_pure_virtual=True, is_const=True, is_virtual=True) + cls.add_method('Copy', + 'bool', + [param('ns3::AttributeValue&', 'source', is_const=True), param('ns3::AttributeValue&', 'destination')], + is_pure_virtual=True, is_const=True, is_virtual=True) return def register_Ns3RandomVariableChecker_methods(root_module, cls): @@ -506,120 +691,195 @@ def register_Ns3RandomVariableChecker_methods(root_module, cls): def register_Ns3SystemMutex_methods(root_module, cls): ## system-mutex.h: ns3::SystemMutex::SystemMutex() [constructor] - cls.add_constructor([], visibility='public') + cls.add_constructor([]) ## system-mutex.h: void ns3::SystemMutex::Lock() [member function] - cls.add_method('Lock', 'void', []) + cls.add_method('Lock', + 'void', + []) ## system-mutex.h: void ns3::SystemMutex::Unlock() [member function] - cls.add_method('Unlock', 'void', []) + cls.add_method('Unlock', + 'void', + []) return def register_Ns3NormalVariable_methods(root_module, cls): ## random-variable.h: ns3::NormalVariable::NormalVariable() [constructor] - cls.add_constructor([], visibility='public') + cls.add_constructor([]) ## random-variable.h: ns3::NormalVariable::NormalVariable(double m, double v) [constructor] - cls.add_constructor([param('double', 'm'), param('double', 'v')], visibility='public') + cls.add_constructor([param('double', 'm'), param('double', 'v')]) ## random-variable.h: ns3::NormalVariable::NormalVariable(double m, double v, double b) [constructor] - cls.add_constructor([param('double', 'm'), param('double', 'v'), param('double', 'b')], visibility='public') + cls.add_constructor([param('double', 'm'), param('double', 'v'), param('double', 'b')]) ## random-variable.h: static double ns3::NormalVariable::GetSingleValue(double m, double v) [member function] - cls.add_method('GetSingleValue', 'double', [param('double', 'm'), param('double', 'v')], is_static=True) + cls.add_method('GetSingleValue', + 'double', + [param('double', 'm'), param('double', 'v')], + is_static=True) ## random-variable.h: static double ns3::NormalVariable::GetSingleValue(double m, double v, double b) [member function] - cls.add_method('GetSingleValue', 'double', [param('double', 'm'), param('double', 'v'), param('double', 'b')], is_static=True) + cls.add_method('GetSingleValue', + 'double', + [param('double', 'm'), param('double', 'v'), param('double', 'b')], + is_static=True) return def register_Ns3ObjectFactory_methods(root_module, cls): ## object-factory.h: ns3::ObjectFactory::ObjectFactory(ns3::ObjectFactory const & arg0) [copy constructor] - cls.add_constructor([param('ns3::ObjectFactory&', 'arg0', is_const=True)], visibility='public') + cls.add_constructor([param('ns3::ObjectFactory&', 'arg0', is_const=True)]) ## object-factory.h: ns3::ObjectFactory::ObjectFactory() [constructor] - cls.add_constructor([], visibility='public') + cls.add_constructor([]) ## object-factory.h: ns3::Ptr ns3::ObjectFactory::Create() const [member function] - cls.add_method('Create', 'ns3::Ptr< ns3::Object >', [], is_const=True) + cls.add_method('Create', + 'ns3::Ptr< ns3::Object >', + [], + is_const=True) ## object-factory.h: ns3::TypeId ns3::ObjectFactory::GetTypeId() const [member function] - cls.add_method('GetTypeId', 'ns3::TypeId', [], is_const=True) + cls.add_method('GetTypeId', + 'ns3::TypeId', + [], + is_const=True) ## object-factory.h: void ns3::ObjectFactory::Set(std::string name, ns3::AttributeValue const & value) [member function] - cls.add_method('Set', 'void', [param('std::string', 'name'), param('ns3::AttributeValue&', 'value', is_const=True)]) + cls.add_method('Set', + 'void', + [param('std::string', 'name'), param('ns3::AttributeValue&', 'value', is_const=True)]) ## object-factory.h: void ns3::ObjectFactory::SetTypeId(ns3::TypeId tid) [member function] - cls.add_method('SetTypeId', 'void', [param('ns3::TypeId', 'tid')]) + cls.add_method('SetTypeId', + 'void', + [param('ns3::TypeId', 'tid')]) ## object-factory.h: void ns3::ObjectFactory::SetTypeId(char const * tid) [member function] - cls.add_method('SetTypeId', 'void', [param('char *', 'tid', transfer_ownership=False, is_const=True)]) + cls.add_method('SetTypeId', + 'void', + [param('char *', 'tid', transfer_ownership=False, is_const=True)]) ## object-factory.h: void ns3::ObjectFactory::SetTypeId(std::string tid) [member function] - cls.add_method('SetTypeId', 'void', [param('std::string', 'tid')]) + cls.add_method('SetTypeId', + 'void', + [param('std::string', 'tid')]) cls.add_output_stream_operator() return def register_Ns3AttributeAccessor_methods(root_module, cls): ## attribute.h: ns3::AttributeAccessor::AttributeAccessor() [constructor] - cls.add_constructor([], visibility='public') + cls.add_constructor([]) ## attribute.h: bool ns3::AttributeAccessor::Set(ns3::ObjectBase * object, ns3::AttributeValue const & value) const [member function] - cls.add_method('Set', 'bool', [param('ns3::ObjectBase *', 'object', transfer_ownership=False), param('ns3::AttributeValue&', 'value', is_const=True)], is_pure_virtual=True, is_const=True, is_virtual=True) + cls.add_method('Set', + 'bool', + [param('ns3::ObjectBase *', 'object', transfer_ownership=False), param('ns3::AttributeValue&', 'value', is_const=True)], + is_pure_virtual=True, is_const=True, is_virtual=True) ## attribute.h: bool ns3::AttributeAccessor::Get(ns3::ObjectBase const * object, ns3::AttributeValue & attribute) const [member function] - cls.add_method('Get', 'bool', [param('ns3::ObjectBase *', 'object', transfer_ownership=False, is_const=True), param('ns3::AttributeValue&', 'attribute')], is_pure_virtual=True, is_const=True, is_virtual=True) + cls.add_method('Get', + 'bool', + [param('ns3::ObjectBase *', 'object', transfer_ownership=False, is_const=True), param('ns3::AttributeValue&', 'attribute')], + is_pure_virtual=True, is_const=True, is_virtual=True) ## attribute.h: bool ns3::AttributeAccessor::HasGetter() const [member function] - cls.add_method('HasGetter', 'bool', [], is_pure_virtual=True, is_const=True, is_virtual=True) + cls.add_method('HasGetter', + 'bool', + [], + is_pure_virtual=True, is_const=True, is_virtual=True) ## attribute.h: bool ns3::AttributeAccessor::HasSetter() const [member function] - cls.add_method('HasSetter', 'bool', [], is_pure_virtual=True, is_const=True, is_virtual=True) + cls.add_method('HasSetter', + 'bool', + [], + is_pure_virtual=True, is_const=True, is_virtual=True) return def register_Ns3ParetoVariable_methods(root_module, cls): ## random-variable.h: ns3::ParetoVariable::ParetoVariable() [constructor] - cls.add_constructor([], visibility='public') + cls.add_constructor([]) ## random-variable.h: ns3::ParetoVariable::ParetoVariable(double m) [constructor] - cls.add_constructor([param('double', 'm')], visibility='public') + cls.add_constructor([param('double', 'm')]) ## random-variable.h: ns3::ParetoVariable::ParetoVariable(double m, double s) [constructor] - cls.add_constructor([param('double', 'm'), param('double', 's')], visibility='public') + cls.add_constructor([param('double', 'm'), param('double', 's')]) ## random-variable.h: ns3::ParetoVariable::ParetoVariable(double m, double s, double b) [constructor] - cls.add_constructor([param('double', 'm'), param('double', 's'), param('double', 'b')], visibility='public') + cls.add_constructor([param('double', 'm'), param('double', 's'), param('double', 'b')]) ## random-variable.h: static double ns3::ParetoVariable::GetSingleValue(double m, double s, double b=0) [member function] - cls.add_method('GetSingleValue', 'double', [param('double', 'm'), param('double', 's'), param('double', 'b', default_value='0')], is_static=True) + cls.add_method('GetSingleValue', + 'double', + [param('double', 'm'), param('double', 's'), param('double', 'b', default_value='0')], + is_static=True) return def register_Ns3ConstantVariable_methods(root_module, cls): ## random-variable.h: ns3::ConstantVariable::ConstantVariable() [constructor] - cls.add_constructor([], visibility='public') + cls.add_constructor([]) ## random-variable.h: ns3::ConstantVariable::ConstantVariable(double c) [constructor] - cls.add_constructor([param('double', 'c')], visibility='public') + cls.add_constructor([param('double', 'c')]) ## random-variable.h: void ns3::ConstantVariable::SetConstant(double c) [member function] - cls.add_method('SetConstant', 'void', [param('double', 'c')]) + cls.add_method('SetConstant', + 'void', + [param('double', 'c')]) return def register_Ns3SystemThread_methods(root_module, cls): ## system-thread.h: ns3::SystemThread::SystemThread(ns3::Callback callback) [constructor] - cls.add_constructor([param('ns3::Callback< void, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty >', 'callback')], visibility='public') + cls.add_constructor([param('ns3::Callback< void, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty >', 'callback')]) ## system-thread.h: void ns3::SystemThread::Ref() const [member function] - cls.add_method('Ref', 'void', [], is_const=True) + cls.add_method('Ref', + 'void', + [], + is_const=True) ## system-thread.h: void ns3::SystemThread::Unref() const [member function] - cls.add_method('Unref', 'void', [], is_const=True) + cls.add_method('Unref', + 'void', + [], + is_const=True) ## system-thread.h: void ns3::SystemThread::Start() [member function] - cls.add_method('Start', 'void', []) + cls.add_method('Start', + 'void', + []) ## system-thread.h: void ns3::SystemThread::Join() [member function] - cls.add_method('Join', 'void', []) + cls.add_method('Join', + 'void', + []) return def register_Ns3EmpiricalVariable_methods(root_module, cls): ## random-variable.h: ns3::EmpiricalVariable::EmpiricalVariable() [constructor] - cls.add_constructor([], visibility='public') + cls.add_constructor([]) ## random-variable.h: void ns3::EmpiricalVariable::CDF(double v, double c) [member function] - cls.add_method('CDF', 'void', [param('double', 'v'), param('double', 'c')]) + cls.add_method('CDF', + 'void', + [param('double', 'v'), param('double', 'c')]) return def register_Ns3EnumChecker_methods(root_module, cls): ## enum.h: ns3::EnumChecker::EnumChecker() [constructor] - cls.add_constructor([], visibility='public') + cls.add_constructor([]) ## enum.h: void ns3::EnumChecker::AddDefault(int v, std::string name) [member function] - cls.add_method('AddDefault', 'void', [param('int', 'v'), param('std::string', 'name')]) + cls.add_method('AddDefault', + 'void', + [param('int', 'v'), param('std::string', 'name')]) ## enum.h: void ns3::EnumChecker::Add(int v, std::string name) [member function] - cls.add_method('Add', 'void', [param('int', 'v'), param('std::string', 'name')]) + cls.add_method('Add', + 'void', + [param('int', 'v'), param('std::string', 'name')]) ## enum.h: bool ns3::EnumChecker::Check(ns3::AttributeValue const & value) const [member function] - cls.add_method('Check', 'bool', [param('ns3::AttributeValue&', 'value', is_const=True)], is_const=True, is_virtual=True) + cls.add_method('Check', + 'bool', + [param('ns3::AttributeValue&', 'value', is_const=True)], + is_const=True, is_virtual=True) ## enum.h: std::string ns3::EnumChecker::GetValueTypeName() const [member function] - cls.add_method('GetValueTypeName', 'std::string', [], is_const=True, is_virtual=True) + cls.add_method('GetValueTypeName', + 'std::string', + [], + is_const=True, is_virtual=True) ## enum.h: bool ns3::EnumChecker::HasUnderlyingTypeInformation() const [member function] - cls.add_method('HasUnderlyingTypeInformation', 'bool', [], is_const=True, is_virtual=True) + cls.add_method('HasUnderlyingTypeInformation', + 'bool', + [], + is_const=True, is_virtual=True) ## enum.h: std::string ns3::EnumChecker::GetUnderlyingTypeInformation() const [member function] - cls.add_method('GetUnderlyingTypeInformation', 'std::string', [], is_const=True, is_virtual=True) + cls.add_method('GetUnderlyingTypeInformation', + 'std::string', + [], + is_const=True, is_virtual=True) ## enum.h: ns3::Ptr ns3::EnumChecker::Create() const [member function] - cls.add_method('Create', 'ns3::Ptr< ns3::AttributeValue >', [], is_const=True, is_virtual=True) + cls.add_method('Create', + 'ns3::Ptr< ns3::AttributeValue >', + [], + is_const=True, is_virtual=True) ## enum.h: bool ns3::EnumChecker::Copy(ns3::AttributeValue const & src, ns3::AttributeValue & dst) const [member function] - cls.add_method('Copy', 'bool', [param('ns3::AttributeValue&', 'src', is_const=True), param('ns3::AttributeValue&', 'dst')], is_const=True, is_virtual=True) + cls.add_method('Copy', + 'bool', + [param('ns3::AttributeValue&', 'src', is_const=True), param('ns3::AttributeValue&', 'dst')], + is_const=True, is_virtual=True) return def register_Ns3Empty_methods(root_module, cls): @@ -628,33 +888,63 @@ def register_Ns3Empty_methods(root_module, cls): def register_Ns3ObjectBase_methods(root_module, cls): ## object-base.h: ns3::ObjectBase::ObjectBase() [constructor] - cls.add_constructor([], visibility='public') + cls.add_constructor([]) ## object-base.h: ns3::ObjectBase::ObjectBase(ns3::ObjectBase const & arg0) [copy constructor] - cls.add_constructor([param('ns3::ObjectBase&', 'arg0', is_const=True)], visibility='public') + cls.add_constructor([param('ns3::ObjectBase&', 'arg0', is_const=True)]) ## object-base.h: static ns3::TypeId ns3::ObjectBase::GetTypeId() [member function] - cls.add_method('GetTypeId', 'ns3::TypeId', [], is_static=True) + cls.add_method('GetTypeId', + 'ns3::TypeId', + [], + is_static=True) ## object-base.h: ns3::TypeId ns3::ObjectBase::GetInstanceTypeId() const [member function] - cls.add_method('GetInstanceTypeId', 'ns3::TypeId', [], is_pure_virtual=True, is_const=True, is_virtual=True) + cls.add_method('GetInstanceTypeId', + 'ns3::TypeId', + [], + is_pure_virtual=True, is_const=True, is_virtual=True) ## object-base.h: void ns3::ObjectBase::SetAttribute(std::string name, ns3::AttributeValue const & value) [member function] - cls.add_method('SetAttribute', 'void', [param('std::string', 'name'), param('ns3::AttributeValue&', 'value', is_const=True)]) + cls.add_method('SetAttribute', + 'void', + [param('std::string', 'name'), param('ns3::AttributeValue&', 'value', is_const=True)]) ## object-base.h: bool ns3::ObjectBase::SetAttributeFailSafe(std::string name, ns3::AttributeValue const & value) [member function] - cls.add_method('SetAttributeFailSafe', 'bool', [param('std::string', 'name'), param('ns3::AttributeValue&', 'value', is_const=True)]) + cls.add_method('SetAttributeFailSafe', + 'bool', + [param('std::string', 'name'), param('ns3::AttributeValue&', 'value', is_const=True)]) ## object-base.h: void ns3::ObjectBase::GetAttribute(std::string name, ns3::AttributeValue & value) const [member function] - cls.add_method('GetAttribute', 'void', [param('std::string', 'name'), param('ns3::AttributeValue&', 'value')], is_const=True) + cls.add_method('GetAttribute', + 'void', + [param('std::string', 'name'), param('ns3::AttributeValue&', 'value')], + is_const=True) ## object-base.h: bool ns3::ObjectBase::GetAttributeFailSafe(std::string name, ns3::AttributeValue & attribute) const [member function] - cls.add_method('GetAttributeFailSafe', 'bool', [param('std::string', 'name'), param('ns3::AttributeValue&', 'attribute')], is_const=True) + cls.add_method('GetAttributeFailSafe', + 'bool', + [param('std::string', 'name'), param('ns3::AttributeValue&', 'attribute')], + is_const=True) ## object-base.h: bool ns3::ObjectBase::TraceConnect(std::string name, std::string context, ns3::CallbackBase const & cb) [member function] - cls.add_method('TraceConnect', 'bool', [param('std::string', 'name'), param('std::string', 'context'), param('ns3::CallbackBase&', 'cb', is_const=True)]) + cls.add_method('TraceConnect', + 'bool', + [param('std::string', 'name'), param('std::string', 'context'), param('ns3::CallbackBase&', 'cb', is_const=True)]) ## object-base.h: bool ns3::ObjectBase::TraceConnectWithoutContext(std::string name, ns3::CallbackBase const & cb) [member function] - cls.add_method('TraceConnectWithoutContext', 'bool', [param('std::string', 'name'), param('ns3::CallbackBase&', 'cb', is_const=True)]) + cls.add_method('TraceConnectWithoutContext', + 'bool', + [param('std::string', 'name'), param('ns3::CallbackBase&', 'cb', is_const=True)]) ## object-base.h: bool ns3::ObjectBase::TraceDisconnect(std::string name, std::string context, ns3::CallbackBase const & cb) [member function] - cls.add_method('TraceDisconnect', 'bool', [param('std::string', 'name'), param('std::string', 'context'), param('ns3::CallbackBase&', 'cb', is_const=True)]) + cls.add_method('TraceDisconnect', + 'bool', + [param('std::string', 'name'), param('std::string', 'context'), param('ns3::CallbackBase&', 'cb', is_const=True)]) ## object-base.h: bool ns3::ObjectBase::TraceDisconnectWithoutContext(std::string name, ns3::CallbackBase const & cb) [member function] - cls.add_method('TraceDisconnectWithoutContext', 'bool', [param('std::string', 'name'), param('ns3::CallbackBase&', 'cb', is_const=True)]) + cls.add_method('TraceDisconnectWithoutContext', + 'bool', + [param('std::string', 'name'), param('ns3::CallbackBase&', 'cb', is_const=True)]) ## object-base.h: void ns3::ObjectBase::NotifyConstructionCompleted() [member function] - cls.add_method('NotifyConstructionCompleted', 'void', [], visibility='protected', is_virtual=True) + cls.add_method('NotifyConstructionCompleted', + 'void', + [], + visibility='protected', is_virtual=True) ## object-base.h: void ns3::ObjectBase::ConstructSelf(ns3::AttributeList const & attributes) [member function] - cls.add_method('ConstructSelf', 'void', [param('ns3::AttributeList&', 'attributes', is_const=True)], visibility='protected') + cls.add_method('ConstructSelf', + 'void', + [param('ns3::AttributeList&', 'attributes', is_const=True)], + visibility='protected') return def register_Ns3CommandLine_methods(root_module, cls): @@ -691,325 +981,520 @@ def register_Ns3IntToType__0_methods(root_module, cls): def register_Ns3RngStream_methods(root_module, cls): ## rng-stream.h: ns3::RngStream::RngStream() [constructor] - cls.add_constructor([], visibility='public') + cls.add_constructor([]) ## rng-stream.h: ns3::RngStream::RngStream(ns3::RngStream const & arg0) [copy constructor] - cls.add_constructor([param('ns3::RngStream&', 'arg0', is_const=True)], visibility='public') + cls.add_constructor([param('ns3::RngStream&', 'arg0', is_const=True)]) ## rng-stream.h: void ns3::RngStream::InitializeStream() [member function] - cls.add_method('InitializeStream', 'void', []) + cls.add_method('InitializeStream', + 'void', + []) ## rng-stream.h: void ns3::RngStream::ResetStartStream() [member function] - cls.add_method('ResetStartStream', 'void', []) + cls.add_method('ResetStartStream', + 'void', + []) ## rng-stream.h: void ns3::RngStream::ResetStartSubstream() [member function] - cls.add_method('ResetStartSubstream', 'void', []) + cls.add_method('ResetStartSubstream', + 'void', + []) ## rng-stream.h: void ns3::RngStream::ResetNextSubstream() [member function] - cls.add_method('ResetNextSubstream', 'void', []) + cls.add_method('ResetNextSubstream', + 'void', + []) ## rng-stream.h: void ns3::RngStream::ResetNthSubstream(uint32_t N) [member function] - cls.add_method('ResetNthSubstream', 'void', [param('uint32_t', 'N')]) + cls.add_method('ResetNthSubstream', + 'void', + [param('uint32_t', 'N')]) ## rng-stream.h: void ns3::RngStream::SetAntithetic(bool a) [member function] - cls.add_method('SetAntithetic', 'void', [param('bool', 'a')]) + cls.add_method('SetAntithetic', + 'void', + [param('bool', 'a')]) ## rng-stream.h: void ns3::RngStream::IncreasedPrecis(bool incp) [member function] - cls.add_method('IncreasedPrecis', 'void', [param('bool', 'incp')]) + cls.add_method('IncreasedPrecis', + 'void', + [param('bool', 'incp')]) ## rng-stream.h: bool ns3::RngStream::SetSeeds(uint32_t const * seed) [member function] - cls.add_method('SetSeeds', 'bool', [param('uint32_t *', 'seed', transfer_ownership=False, is_const=True)]) + cls.add_method('SetSeeds', + 'bool', + [param('uint32_t *', 'seed', transfer_ownership=False, is_const=True)]) ## rng-stream.h: void ns3::RngStream::AdvanceState(int32_t e, int32_t c) [member function] - cls.add_method('AdvanceState', 'void', [param('int32_t', 'e'), param('int32_t', 'c')]) + cls.add_method('AdvanceState', + 'void', + [param('int32_t', 'e'), param('int32_t', 'c')]) ## rng-stream.h: void ns3::RngStream::GetState(uint32_t * seed) const [member function] - cls.add_method('GetState', 'void', [param('uint32_t *', 'seed')], is_const=True) + cls.add_method('GetState', + 'void', + [param('uint32_t *', 'seed')], + is_const=True) ## rng-stream.h: double ns3::RngStream::RandU01() [member function] - cls.add_method('RandU01', 'double', []) + cls.add_method('RandU01', + 'double', + []) ## rng-stream.h: int32_t ns3::RngStream::RandInt(int32_t i, int32_t j) [member function] - cls.add_method('RandInt', 'int32_t', [param('int32_t', 'i'), param('int32_t', 'j')]) + cls.add_method('RandInt', + 'int32_t', + [param('int32_t', 'i'), param('int32_t', 'j')]) ## rng-stream.h: static bool ns3::RngStream::SetPackageSeed(uint32_t const * seed) [member function] - cls.add_method('SetPackageSeed', 'bool', [param('uint32_t *', 'seed', transfer_ownership=False, is_const=True)], is_static=True) + cls.add_method('SetPackageSeed', + 'bool', + [param('uint32_t *', 'seed', transfer_ownership=False, is_const=True)], + is_static=True) ## rng-stream.h: static bool ns3::RngStream::CheckSeed(uint32_t const * seed) [member function] - cls.add_method('CheckSeed', 'bool', [param('uint32_t *', 'seed', transfer_ownership=False, is_const=True)], is_static=True) + cls.add_method('CheckSeed', + 'bool', + [param('uint32_t *', 'seed', transfer_ownership=False, is_const=True)], + is_static=True) return def register_Ns3LogNormalVariable_methods(root_module, cls): ## random-variable.h: ns3::LogNormalVariable::LogNormalVariable(double mu, double sigma) [constructor] - cls.add_constructor([param('double', 'mu'), param('double', 'sigma')], visibility='public') + cls.add_constructor([param('double', 'mu'), param('double', 'sigma')]) ## random-variable.h: static double ns3::LogNormalVariable::GetSingleValue(double mu, double sigma) [member function] - cls.add_method('GetSingleValue', 'double', [param('double', 'mu'), param('double', 'sigma')], is_static=True) + cls.add_method('GetSingleValue', + 'double', + [param('double', 'mu'), param('double', 'sigma')], + is_static=True) return def register_Ns3IntEmpiricalVariable_methods(root_module, cls): ## random-variable.h: ns3::IntEmpiricalVariable::IntEmpiricalVariable() [constructor] - cls.add_constructor([], visibility='public') + cls.add_constructor([]) return def register_Ns3PointerChecker_methods(root_module, cls): ## pointer.h: ns3::TypeId ns3::PointerChecker::GetPointeeTypeId() const [member function] - cls.add_method('GetPointeeTypeId', 'ns3::TypeId', [], is_pure_virtual=True, is_const=True, is_virtual=True) + cls.add_method('GetPointeeTypeId', + 'ns3::TypeId', + [], + is_pure_virtual=True, is_const=True, is_virtual=True) cls.add_constructor([]) return def register_Ns3WeibullVariable_methods(root_module, cls): ## random-variable.h: ns3::WeibullVariable::WeibullVariable() [constructor] - cls.add_constructor([], visibility='public') + cls.add_constructor([]) ## random-variable.h: ns3::WeibullVariable::WeibullVariable(double m) [constructor] - cls.add_constructor([param('double', 'm')], visibility='public') + cls.add_constructor([param('double', 'm')]) ## random-variable.h: ns3::WeibullVariable::WeibullVariable(double m, double s) [constructor] - cls.add_constructor([param('double', 'm'), param('double', 's')], visibility='public') + cls.add_constructor([param('double', 'm'), param('double', 's')]) ## random-variable.h: ns3::WeibullVariable::WeibullVariable(double m, double s, double b) [constructor] - cls.add_constructor([param('double', 'm'), param('double', 's'), param('double', 'b')], visibility='public') + cls.add_constructor([param('double', 'm'), param('double', 's'), param('double', 'b')]) ## random-variable.h: static double ns3::WeibullVariable::GetSingleValue(double m, double s, double b=0) [member function] - cls.add_method('GetSingleValue', 'double', [param('double', 'm'), param('double', 's'), param('double', 'b', default_value='0')], is_static=True) + cls.add_method('GetSingleValue', + 'double', + [param('double', 'm'), param('double', 's'), param('double', 'b', default_value='0')], + is_static=True) return def register_Ns3CallbackBase_methods(root_module, cls): ## callback.h: ns3::CallbackBase::CallbackBase() [constructor] - cls.add_constructor([], visibility='public') + cls.add_constructor([]) ## callback.h: ns3::Ptr ns3::CallbackBase::GetImpl() const [member function] - cls.add_method('GetImpl', 'ns3::Ptr< ns3::CallbackImplBase >', [], is_const=True) + cls.add_method('GetImpl', + 'ns3::Ptr< ns3::CallbackImplBase >', + [], + is_const=True) ## callback.h: ns3::CallbackBase::CallbackBase(ns3::Ptr impl) [constructor] - cls.add_constructor([param('ns3::Ptr< ns3::CallbackImplBase >', 'impl')], visibility='protected') + cls.add_constructor([param('ns3::Ptr< ns3::CallbackImplBase >', 'impl')], + visibility='protected') return def register_Ns3ExponentialVariable_methods(root_module, cls): ## random-variable.h: ns3::ExponentialVariable::ExponentialVariable() [constructor] - cls.add_constructor([], visibility='public') + cls.add_constructor([]) ## random-variable.h: ns3::ExponentialVariable::ExponentialVariable(double m) [constructor] - cls.add_constructor([param('double', 'm')], visibility='public') + cls.add_constructor([param('double', 'm')]) ## random-variable.h: ns3::ExponentialVariable::ExponentialVariable(double m, double b) [constructor] - cls.add_constructor([param('double', 'm'), param('double', 'b')], visibility='public') + cls.add_constructor([param('double', 'm'), param('double', 'b')]) ## random-variable.h: static double ns3::ExponentialVariable::GetSingleValue(double m, double b=0) [member function] - cls.add_method('GetSingleValue', 'double', [param('double', 'm'), param('double', 'b', default_value='0')], is_static=True) + cls.add_method('GetSingleValue', + 'double', + [param('double', 'm'), param('double', 'b', default_value='0')], + is_static=True) return def register_Ns3TracedCallback__Ns3Ptr__lt__ns3Packet_const__gt___Ns3Mac48Address_Ns3Empty_Ns3Empty_methods(root_module, cls): ## traced-callback.h: ns3::TracedCallback, ns3::Mac48Address, ns3::empty, ns3::empty>::TracedCallback() [constructor] - cls.add_constructor([], visibility='public') + cls.add_constructor([]) ## traced-callback.h: void ns3::TracedCallback, ns3::Mac48Address, ns3::empty, ns3::empty>::ConnectWithoutContext(ns3::CallbackBase const & callback) [member function] - cls.add_method('ConnectWithoutContext', 'void', [param('ns3::CallbackBase&', 'callback', is_const=True)]) + cls.add_method('ConnectWithoutContext', + 'void', + [param('ns3::CallbackBase&', 'callback', is_const=True)]) ## traced-callback.h: void ns3::TracedCallback, ns3::Mac48Address, ns3::empty, ns3::empty>::Connect(ns3::CallbackBase const & callback, std::string path) [member function] - cls.add_method('Connect', 'void', [param('ns3::CallbackBase&', 'callback', is_const=True), param('std::string', 'path')]) + cls.add_method('Connect', + 'void', + [param('ns3::CallbackBase&', 'callback', is_const=True), param('std::string', 'path')]) ## traced-callback.h: void ns3::TracedCallback, ns3::Mac48Address, ns3::empty, ns3::empty>::DisconnectWithoutContext(ns3::CallbackBase const & callback) [member function] - cls.add_method('DisconnectWithoutContext', 'void', [param('ns3::CallbackBase&', 'callback', is_const=True)]) + cls.add_method('DisconnectWithoutContext', + 'void', + [param('ns3::CallbackBase&', 'callback', is_const=True)]) ## traced-callback.h: void ns3::TracedCallback, ns3::Mac48Address, ns3::empty, ns3::empty>::Disconnect(ns3::CallbackBase const & callback, std::string path) [member function] - cls.add_method('Disconnect', 'void', [param('ns3::CallbackBase&', 'callback', is_const=True), param('std::string', 'path')]) + cls.add_method('Disconnect', + 'void', + [param('ns3::CallbackBase&', 'callback', is_const=True), param('std::string', 'path')]) return def register_Ns3TracedCallback__Ns3Ptr__lt__ns3Packet_const__gt___Ns3Empty_Ns3Empty_Ns3Empty_methods(root_module, cls): ## traced-callback.h: ns3::TracedCallback, ns3::empty, ns3::empty, ns3::empty>::TracedCallback() [constructor] - cls.add_constructor([], visibility='public') + cls.add_constructor([]) ## traced-callback.h: void ns3::TracedCallback, ns3::empty, ns3::empty, ns3::empty>::ConnectWithoutContext(ns3::CallbackBase const & callback) [member function] - cls.add_method('ConnectWithoutContext', 'void', [param('ns3::CallbackBase&', 'callback', is_const=True)]) + cls.add_method('ConnectWithoutContext', + 'void', + [param('ns3::CallbackBase&', 'callback', is_const=True)]) ## traced-callback.h: void ns3::TracedCallback, ns3::empty, ns3::empty, ns3::empty>::Connect(ns3::CallbackBase const & callback, std::string path) [member function] - cls.add_method('Connect', 'void', [param('ns3::CallbackBase&', 'callback', is_const=True), param('std::string', 'path')]) + cls.add_method('Connect', + 'void', + [param('ns3::CallbackBase&', 'callback', is_const=True), param('std::string', 'path')]) ## traced-callback.h: void ns3::TracedCallback, ns3::empty, ns3::empty, ns3::empty>::DisconnectWithoutContext(ns3::CallbackBase const & callback) [member function] - cls.add_method('DisconnectWithoutContext', 'void', [param('ns3::CallbackBase&', 'callback', is_const=True)]) + cls.add_method('DisconnectWithoutContext', + 'void', + [param('ns3::CallbackBase&', 'callback', is_const=True)]) ## traced-callback.h: void ns3::TracedCallback, ns3::empty, ns3::empty, ns3::empty>::Disconnect(ns3::CallbackBase const & callback, std::string path) [member function] - cls.add_method('Disconnect', 'void', [param('ns3::CallbackBase&', 'callback', is_const=True), param('std::string', 'path')]) + cls.add_method('Disconnect', + 'void', + [param('ns3::CallbackBase&', 'callback', is_const=True), param('std::string', 'path')]) return def register_Ns3TracedCallback__Ns3Ptr__lt__ns3Packet_const__gt___Ns3Address_const__amp___Ns3Empty_Ns3Empty_methods(root_module, cls): ## traced-callback.h: ns3::TracedCallback, ns3::Address const&, ns3::empty, ns3::empty>::TracedCallback() [constructor] - cls.add_constructor([], visibility='public') + cls.add_constructor([]) ## traced-callback.h: void ns3::TracedCallback, ns3::Address const&, ns3::empty, ns3::empty>::ConnectWithoutContext(ns3::CallbackBase const & callback) [member function] - cls.add_method('ConnectWithoutContext', 'void', [param('ns3::CallbackBase&', 'callback', is_const=True)]) + cls.add_method('ConnectWithoutContext', + 'void', + [param('ns3::CallbackBase&', 'callback', is_const=True)]) ## traced-callback.h: void ns3::TracedCallback, ns3::Address const&, ns3::empty, ns3::empty>::Connect(ns3::CallbackBase const & callback, std::string path) [member function] - cls.add_method('Connect', 'void', [param('ns3::CallbackBase&', 'callback', is_const=True), param('std::string', 'path')]) + cls.add_method('Connect', + 'void', + [param('ns3::CallbackBase&', 'callback', is_const=True), param('std::string', 'path')]) ## traced-callback.h: void ns3::TracedCallback, ns3::Address const&, ns3::empty, ns3::empty>::DisconnectWithoutContext(ns3::CallbackBase const & callback) [member function] - cls.add_method('DisconnectWithoutContext', 'void', [param('ns3::CallbackBase&', 'callback', is_const=True)]) + cls.add_method('DisconnectWithoutContext', + 'void', + [param('ns3::CallbackBase&', 'callback', is_const=True)]) ## traced-callback.h: void ns3::TracedCallback, ns3::Address const&, ns3::empty, ns3::empty>::Disconnect(ns3::CallbackBase const & callback, std::string path) [member function] - cls.add_method('Disconnect', 'void', [param('ns3::CallbackBase&', 'callback', is_const=True), param('std::string', 'path')]) + cls.add_method('Disconnect', + 'void', + [param('ns3::CallbackBase&', 'callback', is_const=True), param('std::string', 'path')]) return def register_Ns3TracedCallback__Ns3Ptr__lt__ns3Packet_const__gt___Unsigned_int_Ns3Empty_Ns3Empty_methods(root_module, cls): ## traced-callback.h: ns3::TracedCallback, unsigned int, ns3::empty, ns3::empty>::TracedCallback() [constructor] - cls.add_constructor([], visibility='public') + cls.add_constructor([]) ## traced-callback.h: void ns3::TracedCallback, unsigned int, ns3::empty, ns3::empty>::ConnectWithoutContext(ns3::CallbackBase const & callback) [member function] - cls.add_method('ConnectWithoutContext', 'void', [param('ns3::CallbackBase&', 'callback', is_const=True)]) + cls.add_method('ConnectWithoutContext', + 'void', + [param('ns3::CallbackBase&', 'callback', is_const=True)]) ## traced-callback.h: void ns3::TracedCallback, unsigned int, ns3::empty, ns3::empty>::Connect(ns3::CallbackBase const & callback, std::string path) [member function] - cls.add_method('Connect', 'void', [param('ns3::CallbackBase&', 'callback', is_const=True), param('std::string', 'path')]) + cls.add_method('Connect', + 'void', + [param('ns3::CallbackBase&', 'callback', is_const=True), param('std::string', 'path')]) ## traced-callback.h: void ns3::TracedCallback, unsigned int, ns3::empty, ns3::empty>::DisconnectWithoutContext(ns3::CallbackBase const & callback) [member function] - cls.add_method('DisconnectWithoutContext', 'void', [param('ns3::CallbackBase&', 'callback', is_const=True)]) + cls.add_method('DisconnectWithoutContext', + 'void', + [param('ns3::CallbackBase&', 'callback', is_const=True)]) ## traced-callback.h: void ns3::TracedCallback, unsigned int, ns3::empty, ns3::empty>::Disconnect(ns3::CallbackBase const & callback, std::string path) [member function] - cls.add_method('Disconnect', 'void', [param('ns3::CallbackBase&', 'callback', is_const=True), param('std::string', 'path')]) + cls.add_method('Disconnect', + 'void', + [param('ns3::CallbackBase&', 'callback', is_const=True), param('std::string', 'path')]) return def register_Ns3TracedCallback__Ns3Ptr__lt__ns3MobilityModel_const__gt___Ns3Empty_Ns3Empty_Ns3Empty_methods(root_module, cls): ## traced-callback.h: ns3::TracedCallback, ns3::empty, ns3::empty, ns3::empty>::TracedCallback() [constructor] - cls.add_constructor([], visibility='public') + cls.add_constructor([]) ## traced-callback.h: void ns3::TracedCallback, ns3::empty, ns3::empty, ns3::empty>::ConnectWithoutContext(ns3::CallbackBase const & callback) [member function] - cls.add_method('ConnectWithoutContext', 'void', [param('ns3::CallbackBase&', 'callback', is_const=True)]) + cls.add_method('ConnectWithoutContext', + 'void', + [param('ns3::CallbackBase&', 'callback', is_const=True)]) ## traced-callback.h: void ns3::TracedCallback, ns3::empty, ns3::empty, ns3::empty>::Connect(ns3::CallbackBase const & callback, std::string path) [member function] - cls.add_method('Connect', 'void', [param('ns3::CallbackBase&', 'callback', is_const=True), param('std::string', 'path')]) + cls.add_method('Connect', + 'void', + [param('ns3::CallbackBase&', 'callback', is_const=True), param('std::string', 'path')]) ## traced-callback.h: void ns3::TracedCallback, ns3::empty, ns3::empty, ns3::empty>::DisconnectWithoutContext(ns3::CallbackBase const & callback) [member function] - cls.add_method('DisconnectWithoutContext', 'void', [param('ns3::CallbackBase&', 'callback', is_const=True)]) + cls.add_method('DisconnectWithoutContext', + 'void', + [param('ns3::CallbackBase&', 'callback', is_const=True)]) ## traced-callback.h: void ns3::TracedCallback, ns3::empty, ns3::empty, ns3::empty>::Disconnect(ns3::CallbackBase const & callback, std::string path) [member function] - cls.add_method('Disconnect', 'void', [param('ns3::CallbackBase&', 'callback', is_const=True), param('std::string', 'path')]) + cls.add_method('Disconnect', + 'void', + [param('ns3::CallbackBase&', 'callback', is_const=True), param('std::string', 'path')]) return def register_Ns3TracedCallback__Ns3TimeUnit__lt__1__gt___Ns3TimeUnit__lt__1__gt___Ns3WifiPhyState_Ns3Empty_methods(root_module, cls): ## traced-callback.h: ns3::TracedCallback, ns3::TimeUnit<1>, ns3::WifiPhy::State, ns3::empty>::TracedCallback() [constructor] - cls.add_constructor([], visibility='public') + cls.add_constructor([]) ## traced-callback.h: void ns3::TracedCallback, ns3::TimeUnit<1>, ns3::WifiPhy::State, ns3::empty>::ConnectWithoutContext(ns3::CallbackBase const & callback) [member function] - cls.add_method('ConnectWithoutContext', 'void', [param('ns3::CallbackBase&', 'callback', is_const=True)]) + cls.add_method('ConnectWithoutContext', + 'void', + [param('ns3::CallbackBase&', 'callback', is_const=True)]) ## traced-callback.h: void ns3::TracedCallback, ns3::TimeUnit<1>, ns3::WifiPhy::State, ns3::empty>::Connect(ns3::CallbackBase const & callback, std::string path) [member function] - cls.add_method('Connect', 'void', [param('ns3::CallbackBase&', 'callback', is_const=True), param('std::string', 'path')]) + cls.add_method('Connect', + 'void', + [param('ns3::CallbackBase&', 'callback', is_const=True), param('std::string', 'path')]) ## traced-callback.h: void ns3::TracedCallback, ns3::TimeUnit<1>, ns3::WifiPhy::State, ns3::empty>::DisconnectWithoutContext(ns3::CallbackBase const & callback) [member function] - cls.add_method('DisconnectWithoutContext', 'void', [param('ns3::CallbackBase&', 'callback', is_const=True)]) + cls.add_method('DisconnectWithoutContext', + 'void', + [param('ns3::CallbackBase&', 'callback', is_const=True)]) ## traced-callback.h: void ns3::TracedCallback, ns3::TimeUnit<1>, ns3::WifiPhy::State, ns3::empty>::Disconnect(ns3::CallbackBase const & callback, std::string path) [member function] - cls.add_method('Disconnect', 'void', [param('ns3::CallbackBase&', 'callback', is_const=True), param('std::string', 'path')]) + cls.add_method('Disconnect', + 'void', + [param('ns3::CallbackBase&', 'callback', is_const=True), param('std::string', 'path')]) return def register_Ns3TracedCallback__Ns3Ptr__lt__ns3Packet_const__gt___Ns3WifiMode_Ns3WifiPreamble_Unsigned_char_methods(root_module, cls): ## traced-callback.h: ns3::TracedCallback, ns3::WifiMode, ns3::WifiPreamble, unsigned char>::TracedCallback() [constructor] - cls.add_constructor([], visibility='public') + cls.add_constructor([]) ## traced-callback.h: void ns3::TracedCallback, ns3::WifiMode, ns3::WifiPreamble, unsigned char>::ConnectWithoutContext(ns3::CallbackBase const & callback) [member function] - cls.add_method('ConnectWithoutContext', 'void', [param('ns3::CallbackBase&', 'callback', is_const=True)]) + cls.add_method('ConnectWithoutContext', + 'void', + [param('ns3::CallbackBase&', 'callback', is_const=True)]) ## traced-callback.h: void ns3::TracedCallback, ns3::WifiMode, ns3::WifiPreamble, unsigned char>::Connect(ns3::CallbackBase const & callback, std::string path) [member function] - cls.add_method('Connect', 'void', [param('ns3::CallbackBase&', 'callback', is_const=True), param('std::string', 'path')]) + cls.add_method('Connect', + 'void', + [param('ns3::CallbackBase&', 'callback', is_const=True), param('std::string', 'path')]) ## traced-callback.h: void ns3::TracedCallback, ns3::WifiMode, ns3::WifiPreamble, unsigned char>::DisconnectWithoutContext(ns3::CallbackBase const & callback) [member function] - cls.add_method('DisconnectWithoutContext', 'void', [param('ns3::CallbackBase&', 'callback', is_const=True)]) + cls.add_method('DisconnectWithoutContext', + 'void', + [param('ns3::CallbackBase&', 'callback', is_const=True)]) ## traced-callback.h: void ns3::TracedCallback, ns3::WifiMode, ns3::WifiPreamble, unsigned char>::Disconnect(ns3::CallbackBase const & callback, std::string path) [member function] - cls.add_method('Disconnect', 'void', [param('ns3::CallbackBase&', 'callback', is_const=True), param('std::string', 'path')]) + cls.add_method('Disconnect', + 'void', + [param('ns3::CallbackBase&', 'callback', is_const=True), param('std::string', 'path')]) return def register_Ns3TracedCallback__Ns3Ptr__lt__ns3Packet_const__gt___Double_Ns3Empty_Ns3Empty_methods(root_module, cls): ## traced-callback.h: ns3::TracedCallback, double, ns3::empty, ns3::empty>::TracedCallback() [constructor] - cls.add_constructor([], visibility='public') + cls.add_constructor([]) ## traced-callback.h: void ns3::TracedCallback, double, ns3::empty, ns3::empty>::ConnectWithoutContext(ns3::CallbackBase const & callback) [member function] - cls.add_method('ConnectWithoutContext', 'void', [param('ns3::CallbackBase&', 'callback', is_const=True)]) + cls.add_method('ConnectWithoutContext', + 'void', + [param('ns3::CallbackBase&', 'callback', is_const=True)]) ## traced-callback.h: void ns3::TracedCallback, double, ns3::empty, ns3::empty>::Connect(ns3::CallbackBase const & callback, std::string path) [member function] - cls.add_method('Connect', 'void', [param('ns3::CallbackBase&', 'callback', is_const=True), param('std::string', 'path')]) + cls.add_method('Connect', + 'void', + [param('ns3::CallbackBase&', 'callback', is_const=True), param('std::string', 'path')]) ## traced-callback.h: void ns3::TracedCallback, double, ns3::empty, ns3::empty>::DisconnectWithoutContext(ns3::CallbackBase const & callback) [member function] - cls.add_method('DisconnectWithoutContext', 'void', [param('ns3::CallbackBase&', 'callback', is_const=True)]) + cls.add_method('DisconnectWithoutContext', + 'void', + [param('ns3::CallbackBase&', 'callback', is_const=True)]) ## traced-callback.h: void ns3::TracedCallback, double, ns3::empty, ns3::empty>::Disconnect(ns3::CallbackBase const & callback, std::string path) [member function] - cls.add_method('Disconnect', 'void', [param('ns3::CallbackBase&', 'callback', is_const=True), param('std::string', 'path')]) + cls.add_method('Disconnect', + 'void', + [param('ns3::CallbackBase&', 'callback', is_const=True), param('std::string', 'path')]) return def register_Ns3TracedCallback__Ns3Ptr__lt__ns3Packet_const__gt___Double_Ns3WifiMode_Ns3WifiPreamble_methods(root_module, cls): ## traced-callback.h: ns3::TracedCallback, double, ns3::WifiMode, ns3::WifiPreamble>::TracedCallback() [constructor] - cls.add_constructor([], visibility='public') + cls.add_constructor([]) ## traced-callback.h: void ns3::TracedCallback, double, ns3::WifiMode, ns3::WifiPreamble>::ConnectWithoutContext(ns3::CallbackBase const & callback) [member function] - cls.add_method('ConnectWithoutContext', 'void', [param('ns3::CallbackBase&', 'callback', is_const=True)]) + cls.add_method('ConnectWithoutContext', + 'void', + [param('ns3::CallbackBase&', 'callback', is_const=True)]) ## traced-callback.h: void ns3::TracedCallback, double, ns3::WifiMode, ns3::WifiPreamble>::Connect(ns3::CallbackBase const & callback, std::string path) [member function] - cls.add_method('Connect', 'void', [param('ns3::CallbackBase&', 'callback', is_const=True), param('std::string', 'path')]) + cls.add_method('Connect', + 'void', + [param('ns3::CallbackBase&', 'callback', is_const=True), param('std::string', 'path')]) ## traced-callback.h: void ns3::TracedCallback, double, ns3::WifiMode, ns3::WifiPreamble>::DisconnectWithoutContext(ns3::CallbackBase const & callback) [member function] - cls.add_method('DisconnectWithoutContext', 'void', [param('ns3::CallbackBase&', 'callback', is_const=True)]) + cls.add_method('DisconnectWithoutContext', + 'void', + [param('ns3::CallbackBase&', 'callback', is_const=True)]) ## traced-callback.h: void ns3::TracedCallback, double, ns3::WifiMode, ns3::WifiPreamble>::Disconnect(ns3::CallbackBase const & callback, std::string path) [member function] - cls.add_method('Disconnect', 'void', [param('ns3::CallbackBase&', 'callback', is_const=True), param('std::string', 'path')]) + cls.add_method('Disconnect', + 'void', + [param('ns3::CallbackBase&', 'callback', is_const=True), param('std::string', 'path')]) return def register_Ns3TracedCallback__Unsigned_int_Unsigned_int_Ns3Empty_Ns3Empty_methods(root_module, cls): ## traced-callback.h: ns3::TracedCallback::TracedCallback() [constructor] - cls.add_constructor([], visibility='public') + cls.add_constructor([]) ## traced-callback.h: void ns3::TracedCallback::ConnectWithoutContext(ns3::CallbackBase const & callback) [member function] - cls.add_method('ConnectWithoutContext', 'void', [param('ns3::CallbackBase&', 'callback', is_const=True)]) + cls.add_method('ConnectWithoutContext', + 'void', + [param('ns3::CallbackBase&', 'callback', is_const=True)]) ## traced-callback.h: void ns3::TracedCallback::Connect(ns3::CallbackBase const & callback, std::string path) [member function] - cls.add_method('Connect', 'void', [param('ns3::CallbackBase&', 'callback', is_const=True), param('std::string', 'path')]) + cls.add_method('Connect', + 'void', + [param('ns3::CallbackBase&', 'callback', is_const=True), param('std::string', 'path')]) ## traced-callback.h: void ns3::TracedCallback::DisconnectWithoutContext(ns3::CallbackBase const & callback) [member function] - cls.add_method('DisconnectWithoutContext', 'void', [param('ns3::CallbackBase&', 'callback', is_const=True)]) + cls.add_method('DisconnectWithoutContext', + 'void', + [param('ns3::CallbackBase&', 'callback', is_const=True)]) ## traced-callback.h: void ns3::TracedCallback::Disconnect(ns3::CallbackBase const & callback, std::string path) [member function] - cls.add_method('Disconnect', 'void', [param('ns3::CallbackBase&', 'callback', is_const=True), param('std::string', 'path')]) + cls.add_method('Disconnect', + 'void', + [param('ns3::CallbackBase&', 'callback', is_const=True), param('std::string', 'path')]) return def register_Ns3DeterministicVariable_methods(root_module, cls): ## random-variable.h: ns3::DeterministicVariable::DeterministicVariable(double * d, uint32_t c) [constructor] - cls.add_constructor([param('double *', 'd'), param('uint32_t', 'c')], visibility='public') + cls.add_constructor([param('double *', 'd'), param('uint32_t', 'c')]) return def register_Ns3AttributeList_methods(root_module, cls): ## attribute-list.h: ns3::AttributeList::AttributeList() [constructor] - cls.add_constructor([], visibility='public') + cls.add_constructor([]) ## attribute-list.h: ns3::AttributeList::AttributeList(ns3::AttributeList const & o) [copy constructor] - cls.add_constructor([param('ns3::AttributeList&', 'o', is_const=True)], visibility='public') + cls.add_constructor([param('ns3::AttributeList&', 'o', is_const=True)]) ## attribute-list.h: void ns3::AttributeList::Set(std::string name, ns3::AttributeValue const & value) [member function] - cls.add_method('Set', 'void', [param('std::string', 'name'), param('ns3::AttributeValue&', 'value', is_const=True)]) + cls.add_method('Set', + 'void', + [param('std::string', 'name'), param('ns3::AttributeValue&', 'value', is_const=True)]) ## attribute-list.h: bool ns3::AttributeList::SetFailSafe(std::string name, ns3::AttributeValue const & value) [member function] - cls.add_method('SetFailSafe', 'bool', [param('std::string', 'name'), param('ns3::AttributeValue&', 'value', is_const=True)]) + cls.add_method('SetFailSafe', + 'bool', + [param('std::string', 'name'), param('ns3::AttributeValue&', 'value', is_const=True)]) ## attribute-list.h: void ns3::AttributeList::SetWithTid(ns3::TypeId tid, std::string name, ns3::AttributeValue const & value) [member function] - cls.add_method('SetWithTid', 'void', [param('ns3::TypeId', 'tid'), param('std::string', 'name'), param('ns3::AttributeValue&', 'value', is_const=True)]) + cls.add_method('SetWithTid', + 'void', + [param('ns3::TypeId', 'tid'), param('std::string', 'name'), param('ns3::AttributeValue&', 'value', is_const=True)]) ## attribute-list.h: void ns3::AttributeList::Reset() [member function] - cls.add_method('Reset', 'void', []) + cls.add_method('Reset', + 'void', + []) ## attribute-list.h: static ns3::AttributeList * ns3::AttributeList::GetGlobal() [member function] - cls.add_method('GetGlobal', 'ns3::AttributeList *', [], is_static=True) + cls.add_method('GetGlobal', + 'ns3::AttributeList *', + [], + is_static=True) ## attribute-list.h: std::string ns3::AttributeList::SerializeToString() const [member function] - cls.add_method('SerializeToString', 'std::string', [], is_const=True) + cls.add_method('SerializeToString', + 'std::string', + [], + is_const=True) ## attribute-list.h: bool ns3::AttributeList::DeserializeFromString(std::string value) [member function] - cls.add_method('DeserializeFromString', 'bool', [param('std::string', 'value')]) + cls.add_method('DeserializeFromString', + 'bool', + [param('std::string', 'value')]) return def register_Ns3AttributeValue_methods(root_module, cls): ## attribute.h: ns3::AttributeValue::AttributeValue(ns3::AttributeValue const & arg0) [copy constructor] - cls.add_constructor([param('ns3::AttributeValue&', 'arg0', is_const=True)], visibility='public') + cls.add_constructor([param('ns3::AttributeValue&', 'arg0', is_const=True)]) ## attribute.h: ns3::AttributeValue::AttributeValue() [constructor] - cls.add_constructor([], visibility='public') + cls.add_constructor([]) ## attribute.h: ns3::Ptr ns3::AttributeValue::Copy() const [member function] - cls.add_method('Copy', 'ns3::Ptr< ns3::AttributeValue >', [], is_pure_virtual=True, is_const=True, is_virtual=True) + cls.add_method('Copy', + 'ns3::Ptr< ns3::AttributeValue >', + [], + is_pure_virtual=True, is_const=True, is_virtual=True) ## attribute.h: std::string ns3::AttributeValue::SerializeToString(ns3::Ptr checker) const [member function] - cls.add_method('SerializeToString', 'std::string', [param('ns3::Ptr< ns3::AttributeChecker const >', 'checker')], is_pure_virtual=True, is_const=True, is_virtual=True) + cls.add_method('SerializeToString', + 'std::string', + [param('ns3::Ptr< ns3::AttributeChecker const >', 'checker')], + is_pure_virtual=True, is_const=True, is_virtual=True) ## attribute.h: bool ns3::AttributeValue::DeserializeFromString(std::string value, ns3::Ptr checker) [member function] - cls.add_method('DeserializeFromString', 'bool', [param('std::string', 'value'), param('ns3::Ptr< ns3::AttributeChecker const >', 'checker')], is_pure_virtual=True, is_virtual=True) + cls.add_method('DeserializeFromString', + 'bool', + [param('std::string', 'value'), param('ns3::Ptr< ns3::AttributeChecker const >', 'checker')], + is_pure_virtual=True, is_virtual=True) return def register_Ns3UniformVariable_methods(root_module, cls): ## random-variable.h: ns3::UniformVariable::UniformVariable() [constructor] - cls.add_constructor([], visibility='public') + cls.add_constructor([]) ## random-variable.h: ns3::UniformVariable::UniformVariable(double s, double l) [constructor] - cls.add_constructor([param('double', 's'), param('double', 'l')], visibility='public') + cls.add_constructor([param('double', 's'), param('double', 'l')]) ## random-variable.h: static double ns3::UniformVariable::GetSingleValue(double s, double l) [member function] - cls.add_method('GetSingleValue', 'double', [param('double', 's'), param('double', 'l')], is_static=True) + cls.add_method('GetSingleValue', + 'double', + [param('double', 's'), param('double', 'l')], + is_static=True) return def register_Ns3Object_methods(root_module, cls): ## object.h: static ns3::TypeId ns3::Object::GetTypeId() [member function] - cls.add_method('GetTypeId', 'ns3::TypeId', [], is_static=True) + cls.add_method('GetTypeId', + 'ns3::TypeId', + [], + is_static=True) ## object.h: ns3::Object::Object() [constructor] - cls.add_constructor([], visibility='public') + cls.add_constructor([]) ## object.h: ns3::TypeId ns3::Object::GetInstanceTypeId() const [member function] - cls.add_method('GetInstanceTypeId', 'ns3::TypeId', [], is_const=True, is_virtual=True) + cls.add_method('GetInstanceTypeId', + 'ns3::TypeId', + [], + is_const=True, is_virtual=True) ## object.h: ns3::Ptr ns3::Object::GetObject(ns3::TypeId tid) const [member function] - cls.add_method('GetObject', 'ns3::Ptr< ns3::Object >', [param('ns3::TypeId', 'tid')], is_const=True, template_parameters=['ns3::Object'], custom_template_method_name='GetObject') + cls.add_method('GetObject', + 'ns3::Ptr< ns3::Object >', + [param('ns3::TypeId', 'tid')], + is_const=True, template_parameters=['ns3::Object'], custom_template_method_name='GetObject') ## object.h: void ns3::Object::Dispose() [member function] - cls.add_method('Dispose', 'void', []) + cls.add_method('Dispose', + 'void', + []) ## object.h: void ns3::Object::AggregateObject(ns3::Ptr other) [member function] - cls.add_method('AggregateObject', 'void', [param('ns3::Ptr< ns3::Object >', 'other')]) + cls.add_method('AggregateObject', + 'void', + [param('ns3::Ptr< ns3::Object >', 'other')]) ## object.h: ns3::Object::AggregateIterator ns3::Object::GetAggregateIterator() const [member function] - cls.add_method('GetAggregateIterator', 'ns3::Object::AggregateIterator', [], is_const=True) + cls.add_method('GetAggregateIterator', + 'ns3::Object::AggregateIterator', + [], + is_const=True) ## object.h: void ns3::Object::DoDispose() [member function] - cls.add_method('DoDispose', 'void', [], visibility='protected', is_virtual=True) + cls.add_method('DoDispose', + 'void', + [], + visibility='protected', is_virtual=True) ## object.h: ns3::Object::Object(ns3::Object const & o) [copy constructor] - cls.add_constructor([param('ns3::Object&', 'o', is_const=True)], visibility='protected') + cls.add_constructor([param('ns3::Object&', 'o', is_const=True)], + visibility='protected') return def register_Ns3ObjectAggregateIterator_methods(root_module, cls): ## object.h: ns3::Object::AggregateIterator::AggregateIterator() [constructor] - cls.add_constructor([], visibility='public') + cls.add_constructor([]) ## object.h: bool ns3::Object::AggregateIterator::HasNext() const [member function] - cls.add_method('HasNext', 'bool', [], is_const=True) + cls.add_method('HasNext', + 'bool', + [], + is_const=True) ## object.h: ns3::Ptr ns3::Object::AggregateIterator::Next() [member function] - cls.add_method('Next', 'ns3::Ptr< ns3::Object const >', []) + cls.add_method('Next', + 'ns3::Ptr< ns3::Object const >', + []) return def register_Ns3SystemCondition_methods(root_module, cls): ## system-condition.h: ns3::SystemCondition::SystemCondition() [constructor] - cls.add_constructor([], visibility='public') + cls.add_constructor([]) ## system-condition.h: void ns3::SystemCondition::SetCondition(bool condition) [member function] - cls.add_method('SetCondition', 'void', [param('bool', 'condition')]) + cls.add_method('SetCondition', + 'void', + [param('bool', 'condition')]) ## system-condition.h: bool ns3::SystemCondition::GetCondition() [member function] - cls.add_method('GetCondition', 'bool', []) + cls.add_method('GetCondition', + 'bool', + []) ## system-condition.h: void ns3::SystemCondition::Signal() [member function] - cls.add_method('Signal', 'void', []) + cls.add_method('Signal', + 'void', + []) ## system-condition.h: void ns3::SystemCondition::Broadcast() [member function] - cls.add_method('Broadcast', 'void', []) + cls.add_method('Broadcast', + 'void', + []) ## system-condition.h: void ns3::SystemCondition::Wait() [member function] - cls.add_method('Wait', 'void', []) + cls.add_method('Wait', + 'void', + []) ## system-condition.h: bool ns3::SystemCondition::TimedWait(uint64_t ns) [member function] - cls.add_method('TimedWait', 'bool', [param('uint64_t', 'ns')]) + cls.add_method('TimedWait', + 'bool', + [param('uint64_t', 'ns')]) return def register_Ns3SequentialVariable_methods(root_module, cls): ## random-variable.h: ns3::SequentialVariable::SequentialVariable(double f, double l, double i=1, uint32_t c=1) [constructor] - cls.add_constructor([param('double', 'f'), param('double', 'l'), param('double', 'i', default_value='1'), param('uint32_t', 'c', default_value='1')], visibility='public') + cls.add_constructor([param('double', 'f'), param('double', 'l'), param('double', 'i', default_value='1'), param('uint32_t', 'c', default_value='1')]) ## random-variable.h: ns3::SequentialVariable::SequentialVariable(double f, double l, ns3::RandomVariable const & i, uint32_t c=1) [constructor] - cls.add_constructor([param('double', 'f'), param('double', 'l'), param('ns3::RandomVariable&', 'i', is_const=True), param('uint32_t', 'c', default_value='1')], visibility='public') + cls.add_constructor([param('double', 'f'), param('double', 'l'), param('ns3::RandomVariable&', 'i', is_const=True), param('uint32_t', 'c', default_value='1')]) return def register_Ns3ObjectVectorChecker_methods(root_module, cls): ## object-vector.h: ns3::TypeId ns3::ObjectVectorChecker::GetItemTypeId() const [member function] - cls.add_method('GetItemTypeId', 'ns3::TypeId', [], is_pure_virtual=True, is_const=True, is_virtual=True) + cls.add_method('GetItemTypeId', + 'ns3::TypeId', + [], + is_pure_virtual=True, is_const=True, is_virtual=True) cls.add_constructor([]) return @@ -1019,21 +1504,42 @@ def register_Ns3StringChecker_methods(root_module, cls): def register_Ns3ObjectVectorValue_methods(root_module, cls): ## object-vector.h: ns3::ObjectVectorValue::ObjectVectorValue() [constructor] - cls.add_constructor([], visibility='public') + cls.add_constructor([]) ## object-vector.h: __gnu_cxx::__normal_iterator*,std::vector, std::allocator > > > ns3::ObjectVectorValue::Begin() const [member function] - cls.add_method('Begin', '__gnu_cxx::__normal_iterator< const ns3::Ptr< ns3::Object >, std::vector< ns3::Ptr< ns3::Object >, std::allocator< ns3::Ptr< ns3::Object > > > >', [], is_const=True) + cls.add_method('Begin', + '__gnu_cxx::__normal_iterator< const ns3::Ptr< ns3::Object >, std::vector< ns3::Ptr< ns3::Object >, std::allocator< ns3::Ptr< ns3::Object > > > >', + [], + is_const=True) ## object-vector.h: __gnu_cxx::__normal_iterator*,std::vector, std::allocator > > > ns3::ObjectVectorValue::End() const [member function] - cls.add_method('End', '__gnu_cxx::__normal_iterator< const ns3::Ptr< ns3::Object >, std::vector< ns3::Ptr< ns3::Object >, std::allocator< ns3::Ptr< ns3::Object > > > >', [], is_const=True) + cls.add_method('End', + '__gnu_cxx::__normal_iterator< const ns3::Ptr< ns3::Object >, std::vector< ns3::Ptr< ns3::Object >, std::allocator< ns3::Ptr< ns3::Object > > > >', + [], + is_const=True) ## object-vector.h: uint32_t ns3::ObjectVectorValue::GetN() const [member function] - cls.add_method('GetN', 'uint32_t', [], is_const=True) + cls.add_method('GetN', + 'uint32_t', + [], + is_const=True) ## object-vector.h: ns3::Ptr ns3::ObjectVectorValue::Get(uint32_t i) const [member function] - cls.add_method('Get', 'ns3::Ptr< ns3::Object >', [param('uint32_t', 'i')], is_const=True) + cls.add_method('Get', + 'ns3::Ptr< ns3::Object >', + [param('uint32_t', 'i')], + is_const=True) ## object-vector.h: ns3::Ptr ns3::ObjectVectorValue::Copy() const [member function] - cls.add_method('Copy', 'ns3::Ptr< ns3::AttributeValue >', [], is_const=True, is_virtual=True) + cls.add_method('Copy', + 'ns3::Ptr< ns3::AttributeValue >', + [], + is_const=True, is_virtual=True) ## object-vector.h: std::string ns3::ObjectVectorValue::SerializeToString(ns3::Ptr checker) const [member function] - cls.add_method('SerializeToString', 'std::string', [param('ns3::Ptr< ns3::AttributeChecker const >', 'checker')], is_const=True, is_virtual=True) + cls.add_method('SerializeToString', + 'std::string', + [param('ns3::Ptr< ns3::AttributeChecker const >', 'checker')], + is_const=True, is_virtual=True) ## object-vector.h: bool ns3::ObjectVectorValue::DeserializeFromString(std::string value, ns3::Ptr checker) [member function] - cls.add_method('DeserializeFromString', 'bool', [param('std::string', 'value'), param('ns3::Ptr< ns3::AttributeChecker const >', 'checker')], is_virtual=True) + cls.add_method('DeserializeFromString', + 'bool', + [param('std::string', 'value'), param('ns3::Ptr< ns3::AttributeChecker const >', 'checker')], + is_virtual=True) return def register_Ns3BooleanChecker_methods(root_module, cls): @@ -1042,54 +1548,100 @@ def register_Ns3BooleanChecker_methods(root_module, cls): def register_Ns3UintegerValue_methods(root_module, cls): ## uinteger.h: ns3::UintegerValue::UintegerValue() [constructor] - cls.add_constructor([], visibility='public') + cls.add_constructor([]) ## uinteger.h: ns3::UintegerValue::UintegerValue(uint64_t const & value) [constructor] - cls.add_constructor([param('uint64_t&', 'value', is_const=True)], visibility='public') + cls.add_constructor([param('uint64_t&', 'value', is_const=True)]) ## uinteger.h: void ns3::UintegerValue::Set(uint64_t const & value) [member function] - cls.add_method('Set', 'void', [param('uint64_t&', 'value', is_const=True)]) + cls.add_method('Set', + 'void', + [param('uint64_t&', 'value', is_const=True)]) ## uinteger.h: uint64_t ns3::UintegerValue::Get() const [member function] - cls.add_method('Get', 'uint64_t', [], is_const=True) + cls.add_method('Get', + 'uint64_t', + [], + is_const=True) ## uinteger.h: ns3::Ptr ns3::UintegerValue::Copy() const [member function] - cls.add_method('Copy', 'ns3::Ptr< ns3::AttributeValue >', [], is_const=True, is_virtual=True) + cls.add_method('Copy', + 'ns3::Ptr< ns3::AttributeValue >', + [], + is_const=True, is_virtual=True) ## uinteger.h: std::string ns3::UintegerValue::SerializeToString(ns3::Ptr checker) const [member function] - cls.add_method('SerializeToString', 'std::string', [param('ns3::Ptr< ns3::AttributeChecker const >', 'checker')], is_const=True, is_virtual=True) + cls.add_method('SerializeToString', + 'std::string', + [param('ns3::Ptr< ns3::AttributeChecker const >', 'checker')], + is_const=True, is_virtual=True) ## uinteger.h: bool ns3::UintegerValue::DeserializeFromString(std::string value, ns3::Ptr checker) [member function] - cls.add_method('DeserializeFromString', 'bool', [param('std::string', 'value'), param('ns3::Ptr< ns3::AttributeChecker const >', 'checker')], is_virtual=True) + cls.add_method('DeserializeFromString', + 'bool', + [param('std::string', 'value'), param('ns3::Ptr< ns3::AttributeChecker const >', 'checker')], + is_virtual=True) return def register_Ns3ObjectVectorAccessor_methods(root_module, cls): ## object-vector.h: bool ns3::ObjectVectorAccessor::Set(ns3::ObjectBase * object, ns3::AttributeValue const & value) const [member function] - cls.add_method('Set', 'bool', [param('ns3::ObjectBase *', 'object'), param('ns3::AttributeValue&', 'value', is_const=True)], is_const=True, is_virtual=True) + cls.add_method('Set', + 'bool', + [param('ns3::ObjectBase *', 'object'), param('ns3::AttributeValue&', 'value', is_const=True)], + is_const=True, is_virtual=True) ## object-vector.h: bool ns3::ObjectVectorAccessor::Get(ns3::ObjectBase const * object, ns3::AttributeValue & value) const [member function] - cls.add_method('Get', 'bool', [param('ns3::ObjectBase *', 'object', transfer_ownership=False, is_const=True), param('ns3::AttributeValue&', 'value')], is_const=True, is_virtual=True) + cls.add_method('Get', + 'bool', + [param('ns3::ObjectBase *', 'object', transfer_ownership=False, is_const=True), param('ns3::AttributeValue&', 'value')], + is_const=True, is_virtual=True) ## object-vector.h: bool ns3::ObjectVectorAccessor::HasGetter() const [member function] - cls.add_method('HasGetter', 'bool', [], is_const=True, is_virtual=True) + cls.add_method('HasGetter', + 'bool', + [], + is_const=True, is_virtual=True) ## object-vector.h: bool ns3::ObjectVectorAccessor::HasSetter() const [member function] - cls.add_method('HasSetter', 'bool', [], is_const=True, is_virtual=True) + cls.add_method('HasSetter', + 'bool', + [], + is_const=True, is_virtual=True) ## object-vector.h: bool ns3::ObjectVectorAccessor::DoGetN(ns3::ObjectBase const * object, uint32_t * n) const [member function] - cls.add_method('DoGetN', 'bool', [param('ns3::ObjectBase *', 'object', transfer_ownership=False, is_const=True), param('uint32_t *', 'n')], is_pure_virtual=True, is_const=True, visibility='private', is_virtual=True) + cls.add_method('DoGetN', + 'bool', + [param('ns3::ObjectBase *', 'object', transfer_ownership=False, is_const=True), param('uint32_t *', 'n')], + is_pure_virtual=True, is_const=True, visibility='private', is_virtual=True) ## object-vector.h: ns3::Ptr ns3::ObjectVectorAccessor::DoGet(ns3::ObjectBase const * object, uint32_t i) const [member function] - cls.add_method('DoGet', 'ns3::Ptr< ns3::Object >', [param('ns3::ObjectBase *', 'object', transfer_ownership=False, is_const=True), param('uint32_t', 'i')], is_pure_virtual=True, is_const=True, visibility='private', is_virtual=True) + cls.add_method('DoGet', + 'ns3::Ptr< ns3::Object >', + [param('ns3::ObjectBase *', 'object', transfer_ownership=False, is_const=True), param('uint32_t', 'i')], + is_pure_virtual=True, is_const=True, visibility='private', is_virtual=True) cls.add_constructor([]) return def register_Ns3PointerValue_methods(root_module, cls): ## pointer.h: ns3::PointerValue::PointerValue(ns3::PointerValue const & arg0) [copy constructor] - cls.add_constructor([param('ns3::PointerValue&', 'arg0', is_const=True)], visibility='public') + cls.add_constructor([param('ns3::PointerValue&', 'arg0', is_const=True)]) ## pointer.h: ns3::PointerValue::PointerValue() [constructor] - cls.add_constructor([], visibility='public') + cls.add_constructor([]) ## pointer.h: ns3::PointerValue::PointerValue(ns3::Ptr object) [constructor] - cls.add_constructor([param('ns3::Ptr< ns3::Object >', 'object')], visibility='public') + cls.add_constructor([param('ns3::Ptr< ns3::Object >', 'object')]) ## pointer.h: void ns3::PointerValue::SetObject(ns3::Ptr object) [member function] - cls.add_method('SetObject', 'void', [param('ns3::Ptr< ns3::Object >', 'object')]) + cls.add_method('SetObject', + 'void', + [param('ns3::Ptr< ns3::Object >', 'object')]) ## pointer.h: ns3::Ptr ns3::PointerValue::GetObject() const [member function] - cls.add_method('GetObject', 'ns3::Ptr< ns3::Object >', [], is_const=True) + cls.add_method('GetObject', + 'ns3::Ptr< ns3::Object >', + [], + is_const=True) ## pointer.h: ns3::Ptr ns3::PointerValue::Copy() const [member function] - cls.add_method('Copy', 'ns3::Ptr< ns3::AttributeValue >', [], is_const=True, is_virtual=True) + cls.add_method('Copy', + 'ns3::Ptr< ns3::AttributeValue >', + [], + is_const=True, is_virtual=True) ## pointer.h: std::string ns3::PointerValue::SerializeToString(ns3::Ptr checker) const [member function] - cls.add_method('SerializeToString', 'std::string', [param('ns3::Ptr< ns3::AttributeChecker const >', 'checker')], is_const=True, is_virtual=True) + cls.add_method('SerializeToString', + 'std::string', + [param('ns3::Ptr< ns3::AttributeChecker const >', 'checker')], + is_const=True, is_virtual=True) ## pointer.h: bool ns3::PointerValue::DeserializeFromString(std::string value, ns3::Ptr checker) [member function] - cls.add_method('DeserializeFromString', 'bool', [param('std::string', 'value'), param('ns3::Ptr< ns3::AttributeChecker const >', 'checker')], is_virtual=True) + cls.add_method('DeserializeFromString', + 'bool', + [param('std::string', 'value'), param('ns3::Ptr< ns3::AttributeChecker const >', 'checker')], + is_virtual=True) return def register_Ns3ObjectFactoryChecker_methods(root_module, cls): @@ -1102,225 +1654,409 @@ def register_Ns3TypeIdChecker_methods(root_module, cls): def register_Ns3DoubleValue_methods(root_module, cls): ## double.h: ns3::DoubleValue::DoubleValue() [constructor] - cls.add_constructor([], visibility='public') + cls.add_constructor([]) ## double.h: ns3::DoubleValue::DoubleValue(double const & value) [constructor] - cls.add_constructor([param('double&', 'value', is_const=True)], visibility='public') + cls.add_constructor([param('double&', 'value', is_const=True)]) ## double.h: void ns3::DoubleValue::Set(double const & value) [member function] - cls.add_method('Set', 'void', [param('double&', 'value', is_const=True)]) + cls.add_method('Set', + 'void', + [param('double&', 'value', is_const=True)]) ## double.h: double ns3::DoubleValue::Get() const [member function] - cls.add_method('Get', 'double', [], is_const=True) + cls.add_method('Get', + 'double', + [], + is_const=True) ## double.h: ns3::Ptr ns3::DoubleValue::Copy() const [member function] - cls.add_method('Copy', 'ns3::Ptr< ns3::AttributeValue >', [], is_const=True, is_virtual=True) + cls.add_method('Copy', + 'ns3::Ptr< ns3::AttributeValue >', + [], + is_const=True, is_virtual=True) ## double.h: std::string ns3::DoubleValue::SerializeToString(ns3::Ptr checker) const [member function] - cls.add_method('SerializeToString', 'std::string', [param('ns3::Ptr< ns3::AttributeChecker const >', 'checker')], is_const=True, is_virtual=True) + cls.add_method('SerializeToString', + 'std::string', + [param('ns3::Ptr< ns3::AttributeChecker const >', 'checker')], + is_const=True, is_virtual=True) ## double.h: bool ns3::DoubleValue::DeserializeFromString(std::string value, ns3::Ptr checker) [member function] - cls.add_method('DeserializeFromString', 'bool', [param('std::string', 'value'), param('ns3::Ptr< ns3::AttributeChecker const >', 'checker')], is_virtual=True) + cls.add_method('DeserializeFromString', + 'bool', + [param('std::string', 'value'), param('ns3::Ptr< ns3::AttributeChecker const >', 'checker')], + is_virtual=True) return def register_Ns3TypeIdValue_methods(root_module, cls): ## type-id.h: ns3::TypeIdValue::TypeIdValue() [constructor] - cls.add_constructor([], visibility='public') + cls.add_constructor([]) ## type-id.h: ns3::TypeIdValue::TypeIdValue(ns3::TypeId const & value) [constructor] - cls.add_constructor([param('ns3::TypeId&', 'value', is_const=True)], visibility='public') + cls.add_constructor([param('ns3::TypeId&', 'value', is_const=True)]) ## type-id.h: void ns3::TypeIdValue::Set(ns3::TypeId const & value) [member function] - cls.add_method('Set', 'void', [param('ns3::TypeId&', 'value', is_const=True)]) + cls.add_method('Set', + 'void', + [param('ns3::TypeId&', 'value', is_const=True)]) ## type-id.h: ns3::TypeId ns3::TypeIdValue::Get() const [member function] - cls.add_method('Get', 'ns3::TypeId', [], is_const=True) + cls.add_method('Get', + 'ns3::TypeId', + [], + is_const=True) ## type-id.h: ns3::Ptr ns3::TypeIdValue::Copy() const [member function] - cls.add_method('Copy', 'ns3::Ptr< ns3::AttributeValue >', [], is_const=True, is_virtual=True) + cls.add_method('Copy', + 'ns3::Ptr< ns3::AttributeValue >', + [], + is_const=True, is_virtual=True) ## type-id.h: std::string ns3::TypeIdValue::SerializeToString(ns3::Ptr checker) const [member function] - cls.add_method('SerializeToString', 'std::string', [param('ns3::Ptr< ns3::AttributeChecker const >', 'checker')], is_const=True, is_virtual=True) + cls.add_method('SerializeToString', + 'std::string', + [param('ns3::Ptr< ns3::AttributeChecker const >', 'checker')], + is_const=True, is_virtual=True) ## type-id.h: bool ns3::TypeIdValue::DeserializeFromString(std::string value, ns3::Ptr checker) [member function] - cls.add_method('DeserializeFromString', 'bool', [param('std::string', 'value'), param('ns3::Ptr< ns3::AttributeChecker const >', 'checker')], is_virtual=True) + cls.add_method('DeserializeFromString', + 'bool', + [param('std::string', 'value'), param('ns3::Ptr< ns3::AttributeChecker const >', 'checker')], + is_virtual=True) return def register_Ns3EnumValue_methods(root_module, cls): ## enum.h: ns3::EnumValue::EnumValue() [constructor] - cls.add_constructor([], visibility='public') + cls.add_constructor([]) ## enum.h: ns3::EnumValue::EnumValue(int v) [constructor] - cls.add_constructor([param('int', 'v')], visibility='public') + cls.add_constructor([param('int', 'v')]) ## enum.h: void ns3::EnumValue::Set(int v) [member function] - cls.add_method('Set', 'void', [param('int', 'v')]) + cls.add_method('Set', + 'void', + [param('int', 'v')]) ## enum.h: int ns3::EnumValue::Get() const [member function] - cls.add_method('Get', 'int', [], is_const=True) + cls.add_method('Get', + 'int', + [], + is_const=True) ## enum.h: ns3::Ptr ns3::EnumValue::Copy() const [member function] - cls.add_method('Copy', 'ns3::Ptr< ns3::AttributeValue >', [], is_const=True, is_virtual=True) + cls.add_method('Copy', + 'ns3::Ptr< ns3::AttributeValue >', + [], + is_const=True, is_virtual=True) ## enum.h: std::string ns3::EnumValue::SerializeToString(ns3::Ptr checker) const [member function] - cls.add_method('SerializeToString', 'std::string', [param('ns3::Ptr< ns3::AttributeChecker const >', 'checker')], is_const=True, is_virtual=True) + cls.add_method('SerializeToString', + 'std::string', + [param('ns3::Ptr< ns3::AttributeChecker const >', 'checker')], + is_const=True, is_virtual=True) ## enum.h: bool ns3::EnumValue::DeserializeFromString(std::string value, ns3::Ptr checker) [member function] - cls.add_method('DeserializeFromString', 'bool', [param('std::string', 'value'), param('ns3::Ptr< ns3::AttributeChecker const >', 'checker')], is_virtual=True) + cls.add_method('DeserializeFromString', + 'bool', + [param('std::string', 'value'), param('ns3::Ptr< ns3::AttributeChecker const >', 'checker')], + is_virtual=True) return def register_Ns3RandomVariableValue_methods(root_module, cls): ## random-variable.h: ns3::RandomVariableValue::RandomVariableValue() [constructor] - cls.add_constructor([], visibility='public') + cls.add_constructor([]) ## random-variable.h: ns3::RandomVariableValue::RandomVariableValue(ns3::RandomVariable const & value) [constructor] - cls.add_constructor([param('ns3::RandomVariable&', 'value', is_const=True)], visibility='public') + cls.add_constructor([param('ns3::RandomVariable&', 'value', is_const=True)]) ## random-variable.h: void ns3::RandomVariableValue::Set(ns3::RandomVariable const & value) [member function] - cls.add_method('Set', 'void', [param('ns3::RandomVariable&', 'value', is_const=True)]) + cls.add_method('Set', + 'void', + [param('ns3::RandomVariable&', 'value', is_const=True)]) ## random-variable.h: ns3::RandomVariable ns3::RandomVariableValue::Get() const [member function] - cls.add_method('Get', 'ns3::RandomVariable', [], is_const=True) + cls.add_method('Get', + 'ns3::RandomVariable', + [], + is_const=True) ## random-variable.h: ns3::Ptr ns3::RandomVariableValue::Copy() const [member function] - cls.add_method('Copy', 'ns3::Ptr< ns3::AttributeValue >', [], is_const=True, is_virtual=True) + cls.add_method('Copy', + 'ns3::Ptr< ns3::AttributeValue >', + [], + is_const=True, is_virtual=True) ## random-variable.h: std::string ns3::RandomVariableValue::SerializeToString(ns3::Ptr checker) const [member function] - cls.add_method('SerializeToString', 'std::string', [param('ns3::Ptr< ns3::AttributeChecker const >', 'checker')], is_const=True, is_virtual=True) + cls.add_method('SerializeToString', + 'std::string', + [param('ns3::Ptr< ns3::AttributeChecker const >', 'checker')], + is_const=True, is_virtual=True) ## random-variable.h: bool ns3::RandomVariableValue::DeserializeFromString(std::string value, ns3::Ptr checker) [member function] - cls.add_method('DeserializeFromString', 'bool', [param('std::string', 'value'), param('ns3::Ptr< ns3::AttributeChecker const >', 'checker')], is_virtual=True) + cls.add_method('DeserializeFromString', + 'bool', + [param('std::string', 'value'), param('ns3::Ptr< ns3::AttributeChecker const >', 'checker')], + is_virtual=True) return def register_Ns3ObjectFactoryValue_methods(root_module, cls): ## object-factory.h: ns3::ObjectFactoryValue::ObjectFactoryValue() [constructor] - cls.add_constructor([], visibility='public') + cls.add_constructor([]) ## object-factory.h: ns3::ObjectFactoryValue::ObjectFactoryValue(ns3::ObjectFactory const & value) [constructor] - cls.add_constructor([param('ns3::ObjectFactory&', 'value', is_const=True)], visibility='public') + cls.add_constructor([param('ns3::ObjectFactory&', 'value', is_const=True)]) ## object-factory.h: void ns3::ObjectFactoryValue::Set(ns3::ObjectFactory const & value) [member function] - cls.add_method('Set', 'void', [param('ns3::ObjectFactory&', 'value', is_const=True)]) + cls.add_method('Set', + 'void', + [param('ns3::ObjectFactory&', 'value', is_const=True)]) ## object-factory.h: ns3::ObjectFactory ns3::ObjectFactoryValue::Get() const [member function] - cls.add_method('Get', 'ns3::ObjectFactory', [], is_const=True) + cls.add_method('Get', + 'ns3::ObjectFactory', + [], + is_const=True) ## object-factory.h: ns3::Ptr ns3::ObjectFactoryValue::Copy() const [member function] - cls.add_method('Copy', 'ns3::Ptr< ns3::AttributeValue >', [], is_const=True, is_virtual=True) + cls.add_method('Copy', + 'ns3::Ptr< ns3::AttributeValue >', + [], + is_const=True, is_virtual=True) ## object-factory.h: std::string ns3::ObjectFactoryValue::SerializeToString(ns3::Ptr checker) const [member function] - cls.add_method('SerializeToString', 'std::string', [param('ns3::Ptr< ns3::AttributeChecker const >', 'checker')], is_const=True, is_virtual=True) + cls.add_method('SerializeToString', + 'std::string', + [param('ns3::Ptr< ns3::AttributeChecker const >', 'checker')], + is_const=True, is_virtual=True) ## object-factory.h: bool ns3::ObjectFactoryValue::DeserializeFromString(std::string value, ns3::Ptr checker) [member function] - cls.add_method('DeserializeFromString', 'bool', [param('std::string', 'value'), param('ns3::Ptr< ns3::AttributeChecker const >', 'checker')], is_virtual=True) + cls.add_method('DeserializeFromString', + 'bool', + [param('std::string', 'value'), param('ns3::Ptr< ns3::AttributeChecker const >', 'checker')], + is_virtual=True) return def register_Ns3IntegerValue_methods(root_module, cls): ## integer.h: ns3::IntegerValue::IntegerValue() [constructor] - cls.add_constructor([], visibility='public') + cls.add_constructor([]) ## integer.h: ns3::IntegerValue::IntegerValue(int64_t const & value) [constructor] - cls.add_constructor([param('int64_t&', 'value', is_const=True)], visibility='public') + cls.add_constructor([param('int64_t&', 'value', is_const=True)]) ## integer.h: void ns3::IntegerValue::Set(int64_t const & value) [member function] - cls.add_method('Set', 'void', [param('int64_t&', 'value', is_const=True)]) + cls.add_method('Set', + 'void', + [param('int64_t&', 'value', is_const=True)]) ## integer.h: int64_t ns3::IntegerValue::Get() const [member function] - cls.add_method('Get', 'int64_t', [], is_const=True) + cls.add_method('Get', + 'int64_t', + [], + is_const=True) ## integer.h: ns3::Ptr ns3::IntegerValue::Copy() const [member function] - cls.add_method('Copy', 'ns3::Ptr< ns3::AttributeValue >', [], is_const=True, is_virtual=True) + cls.add_method('Copy', + 'ns3::Ptr< ns3::AttributeValue >', + [], + is_const=True, is_virtual=True) ## integer.h: std::string ns3::IntegerValue::SerializeToString(ns3::Ptr checker) const [member function] - cls.add_method('SerializeToString', 'std::string', [param('ns3::Ptr< ns3::AttributeChecker const >', 'checker')], is_const=True, is_virtual=True) + cls.add_method('SerializeToString', + 'std::string', + [param('ns3::Ptr< ns3::AttributeChecker const >', 'checker')], + is_const=True, is_virtual=True) ## integer.h: bool ns3::IntegerValue::DeserializeFromString(std::string value, ns3::Ptr checker) [member function] - cls.add_method('DeserializeFromString', 'bool', [param('std::string', 'value'), param('ns3::Ptr< ns3::AttributeChecker const >', 'checker')], is_virtual=True) + cls.add_method('DeserializeFromString', + 'bool', + [param('std::string', 'value'), param('ns3::Ptr< ns3::AttributeChecker const >', 'checker')], + is_virtual=True) return def register_Ns3BooleanValue_methods(root_module, cls): ## boolean.h: ns3::BooleanValue::BooleanValue(ns3::BooleanValue const & arg0) [copy constructor] - cls.add_constructor([param('ns3::BooleanValue&', 'arg0', is_const=True)], visibility='public') + cls.add_constructor([param('ns3::BooleanValue&', 'arg0', is_const=True)]) ## boolean.h: ns3::BooleanValue::BooleanValue() [constructor] - cls.add_constructor([], visibility='public') + cls.add_constructor([]) ## boolean.h: ns3::BooleanValue::BooleanValue(bool value) [constructor] - cls.add_constructor([param('bool', 'value')], visibility='public') + cls.add_constructor([param('bool', 'value')]) ## boolean.h: ns3::Ptr ns3::BooleanValue::Copy() const [member function] - cls.add_method('Copy', 'ns3::Ptr< ns3::AttributeValue >', [], is_const=True, is_virtual=True) + cls.add_method('Copy', + 'ns3::Ptr< ns3::AttributeValue >', + [], + is_const=True, is_virtual=True) ## boolean.h: bool ns3::BooleanValue::DeserializeFromString(std::string value, ns3::Ptr checker) [member function] - cls.add_method('DeserializeFromString', 'bool', [param('std::string', 'value'), param('ns3::Ptr< ns3::AttributeChecker const >', 'checker')], is_virtual=True) + cls.add_method('DeserializeFromString', + 'bool', + [param('std::string', 'value'), param('ns3::Ptr< ns3::AttributeChecker const >', 'checker')], + is_virtual=True) ## boolean.h: bool ns3::BooleanValue::Get() const [member function] - cls.add_method('Get', 'bool', [], is_const=True) + cls.add_method('Get', + 'bool', + [], + is_const=True) ## boolean.h: std::string ns3::BooleanValue::SerializeToString(ns3::Ptr checker) const [member function] - cls.add_method('SerializeToString', 'std::string', [param('ns3::Ptr< ns3::AttributeChecker const >', 'checker')], is_const=True, is_virtual=True) + cls.add_method('SerializeToString', + 'std::string', + [param('ns3::Ptr< ns3::AttributeChecker const >', 'checker')], + is_const=True, is_virtual=True) ## boolean.h: void ns3::BooleanValue::Set(bool value) [member function] - cls.add_method('Set', 'void', [param('bool', 'value')]) + cls.add_method('Set', + 'void', + [param('bool', 'value')]) cls.add_output_stream_operator() return def register_Ns3StringValue_methods(root_module, cls): ## string.h: ns3::StringValue::StringValue() [constructor] - cls.add_constructor([], visibility='public') + cls.add_constructor([]) ## string.h: ns3::StringValue::StringValue(std::string const & value) [constructor] - cls.add_constructor([param('std::string&', 'value', is_const=True)], visibility='public') + cls.add_constructor([param('std::string&', 'value', is_const=True)]) ## string.h: void ns3::StringValue::Set(std::string const & value) [member function] - cls.add_method('Set', 'void', [param('std::string&', 'value', is_const=True)]) + cls.add_method('Set', + 'void', + [param('std::string&', 'value', is_const=True)]) ## string.h: std::string ns3::StringValue::Get() const [member function] - cls.add_method('Get', 'std::string', [], is_const=True) + cls.add_method('Get', + 'std::string', + [], + is_const=True) ## string.h: ns3::Ptr ns3::StringValue::Copy() const [member function] - cls.add_method('Copy', 'ns3::Ptr< ns3::AttributeValue >', [], is_const=True, is_virtual=True) + cls.add_method('Copy', + 'ns3::Ptr< ns3::AttributeValue >', + [], + is_const=True, is_virtual=True) ## string.h: std::string ns3::StringValue::SerializeToString(ns3::Ptr checker) const [member function] - cls.add_method('SerializeToString', 'std::string', [param('ns3::Ptr< ns3::AttributeChecker const >', 'checker')], is_const=True, is_virtual=True) + cls.add_method('SerializeToString', + 'std::string', + [param('ns3::Ptr< ns3::AttributeChecker const >', 'checker')], + is_const=True, is_virtual=True) ## string.h: bool ns3::StringValue::DeserializeFromString(std::string value, ns3::Ptr checker) [member function] - cls.add_method('DeserializeFromString', 'bool', [param('std::string', 'value'), param('ns3::Ptr< ns3::AttributeChecker const >', 'checker')], is_virtual=True) + cls.add_method('DeserializeFromString', + 'bool', + [param('std::string', 'value'), param('ns3::Ptr< ns3::AttributeChecker const >', 'checker')], + is_virtual=True) return def register_Ns3EmptyAttributeValue_methods(root_module, cls): ## attribute.h: ns3::EmptyAttributeValue::EmptyAttributeValue(ns3::EmptyAttributeValue const & arg0) [copy constructor] - cls.add_constructor([param('ns3::EmptyAttributeValue&', 'arg0', is_const=True)], visibility='public') + cls.add_constructor([param('ns3::EmptyAttributeValue&', 'arg0', is_const=True)]) ## attribute.h: ns3::EmptyAttributeValue::EmptyAttributeValue() [constructor] - cls.add_constructor([], visibility='public') + cls.add_constructor([]) ## attribute.h: ns3::Ptr ns3::EmptyAttributeValue::Copy() const [member function] - cls.add_method('Copy', 'ns3::Ptr< ns3::AttributeValue >', [], is_const=True, visibility='private', is_virtual=True) + cls.add_method('Copy', + 'ns3::Ptr< ns3::AttributeValue >', + [], + is_const=True, visibility='private', is_virtual=True) ## attribute.h: std::string ns3::EmptyAttributeValue::SerializeToString(ns3::Ptr checker) const [member function] - cls.add_method('SerializeToString', 'std::string', [param('ns3::Ptr< ns3::AttributeChecker const >', 'checker')], is_const=True, visibility='private', is_virtual=True) + cls.add_method('SerializeToString', + 'std::string', + [param('ns3::Ptr< ns3::AttributeChecker const >', 'checker')], + is_const=True, visibility='private', is_virtual=True) ## attribute.h: bool ns3::EmptyAttributeValue::DeserializeFromString(std::string value, ns3::Ptr checker) [member function] - cls.add_method('DeserializeFromString', 'bool', [param('std::string', 'value'), param('ns3::Ptr< ns3::AttributeChecker const >', 'checker')], visibility='private', is_virtual=True) + cls.add_method('DeserializeFromString', + 'bool', + [param('std::string', 'value'), param('ns3::Ptr< ns3::AttributeChecker const >', 'checker')], + visibility='private', is_virtual=True) return def register_Ns3TracedValue__Unsigned_int_methods(root_module, cls): ## traced-value.h: ns3::TracedValue::TracedValue() [constructor] - cls.add_constructor([], visibility='public') + cls.add_constructor([]) ## traced-value.h: ns3::TracedValue::TracedValue(ns3::TracedValue const & o) [copy constructor] - cls.add_constructor([param('ns3::TracedValue< unsigned int >&', 'o', is_const=True)], visibility='public') + cls.add_constructor([param('ns3::TracedValue< unsigned int >&', 'o', is_const=True)]) ## traced-value.h: ns3::TracedValue::TracedValue(unsigned int const & v) [constructor] - cls.add_constructor([param('unsigned int&', 'v', is_const=True)], visibility='public') + cls.add_constructor([param('unsigned int&', 'v', is_const=True)]) ## traced-value.h: ns3::TracedValue::TracedValue(ns3::IntegerValue const & value) [constructor] - cls.add_constructor([param('ns3::IntegerValue&', 'value', is_const=True)], visibility='public') + cls.add_constructor([param('ns3::IntegerValue&', 'value', is_const=True)]) ## traced-value.h: ns3::TracedValue::TracedValue(ns3::UintegerValue const & value) [constructor] - cls.add_constructor([param('ns3::UintegerValue&', 'value', is_const=True)], visibility='public') + cls.add_constructor([param('ns3::UintegerValue&', 'value', is_const=True)]) ## traced-value.h: ns3::TracedValue::TracedValue(ns3::BooleanValue const & value) [constructor] - cls.add_constructor([param('ns3::BooleanValue&', 'value', is_const=True)], visibility='public') + cls.add_constructor([param('ns3::BooleanValue&', 'value', is_const=True)]) ## traced-value.h: ns3::TracedValue::TracedValue(ns3::EnumValue const & value) [constructor] - cls.add_constructor([param('ns3::EnumValue&', 'value', is_const=True)], visibility='public') + cls.add_constructor([param('ns3::EnumValue&', 'value', is_const=True)]) ## traced-value.h: void ns3::TracedValue::ConnectWithoutContext(ns3::CallbackBase const & cb) [member function] - cls.add_method('ConnectWithoutContext', 'void', [param('ns3::CallbackBase&', 'cb', is_const=True)]) + cls.add_method('ConnectWithoutContext', + 'void', + [param('ns3::CallbackBase&', 'cb', is_const=True)]) ## traced-value.h: void ns3::TracedValue::Connect(ns3::CallbackBase const & cb, std::string path) [member function] - cls.add_method('Connect', 'void', [param('ns3::CallbackBase&', 'cb', is_const=True), param('std::string', 'path')]) + cls.add_method('Connect', + 'void', + [param('ns3::CallbackBase&', 'cb', is_const=True), param('std::string', 'path')]) ## traced-value.h: void ns3::TracedValue::DisconnectWithoutContext(ns3::CallbackBase const & cb) [member function] - cls.add_method('DisconnectWithoutContext', 'void', [param('ns3::CallbackBase&', 'cb', is_const=True)]) + cls.add_method('DisconnectWithoutContext', + 'void', + [param('ns3::CallbackBase&', 'cb', is_const=True)]) ## traced-value.h: void ns3::TracedValue::Disconnect(ns3::CallbackBase const & cb, std::string path) [member function] - cls.add_method('Disconnect', 'void', [param('ns3::CallbackBase&', 'cb', is_const=True), param('std::string', 'path')]) + cls.add_method('Disconnect', + 'void', + [param('ns3::CallbackBase&', 'cb', is_const=True), param('std::string', 'path')]) ## traced-value.h: void ns3::TracedValue::Set(unsigned int const & v) [member function] - cls.add_method('Set', 'void', [param('unsigned int&', 'v', is_const=True)]) + cls.add_method('Set', + 'void', + [param('unsigned int&', 'v', is_const=True)]) ## traced-value.h: unsigned int ns3::TracedValue::Get() const [member function] - cls.add_method('Get', 'unsigned int', [], is_const=True) + cls.add_method('Get', + 'unsigned int', + [], + is_const=True) return def register_functions(root_module): module = root_module ## boolean.h: extern ns3::Ptr ns3::MakeBooleanChecker() [free function] - module.add_function('MakeBooleanChecker', 'ns3::Ptr< ns3::AttributeChecker const >', []) + module.add_function('MakeBooleanChecker', + 'ns3::Ptr< ns3::AttributeChecker const >', + []) ## type-name.h: extern std::string ns3::TypeNameGet() [free function] - module.add_function('TypeNameGet', 'std::string', [], template_parameters=['double']) + module.add_function('TypeNameGet', + 'std::string', + [], + template_parameters=['double']) ## type-name.h: extern std::string ns3::TypeNameGet() [free function] - module.add_function('TypeNameGet', 'std::string', [], template_parameters=['float']) + module.add_function('TypeNameGet', + 'std::string', + [], + template_parameters=['float']) ## type-name.h: extern std::string ns3::TypeNameGet() [free function] - module.add_function('TypeNameGet', 'std::string', [], template_parameters=['long']) + module.add_function('TypeNameGet', + 'std::string', + [], + template_parameters=['long']) ## type-name.h: extern std::string ns3::TypeNameGet() [free function] - module.add_function('TypeNameGet', 'std::string', [], template_parameters=['int']) + module.add_function('TypeNameGet', + 'std::string', + [], + template_parameters=['int']) ## type-name.h: extern std::string ns3::TypeNameGet() [free function] - module.add_function('TypeNameGet', 'std::string', [], template_parameters=['short']) + module.add_function('TypeNameGet', + 'std::string', + [], + template_parameters=['short']) ## type-name.h: extern std::string ns3::TypeNameGet() [free function] - module.add_function('TypeNameGet', 'std::string', [], template_parameters=['signed char']) + module.add_function('TypeNameGet', + 'std::string', + [], + template_parameters=['signed char']) ## type-name.h: extern std::string ns3::TypeNameGet() [free function] - module.add_function('TypeNameGet', 'std::string', [], template_parameters=['unsigned long']) + module.add_function('TypeNameGet', + 'std::string', + [], + template_parameters=['unsigned long']) ## type-name.h: extern std::string ns3::TypeNameGet() [free function] - module.add_function('TypeNameGet', 'std::string', [], template_parameters=['unsigned int']) + module.add_function('TypeNameGet', + 'std::string', + [], + template_parameters=['unsigned int']) ## type-name.h: extern std::string ns3::TypeNameGet() [free function] - module.add_function('TypeNameGet', 'std::string', [], template_parameters=['unsigned short']) + module.add_function('TypeNameGet', + 'std::string', + [], + template_parameters=['unsigned short']) ## type-name.h: extern std::string ns3::TypeNameGet() [free function] - module.add_function('TypeNameGet', 'std::string', [], template_parameters=['unsigned char']) + module.add_function('TypeNameGet', + 'std::string', + [], + template_parameters=['unsigned char']) ## string.h: extern ns3::Ptr ns3::MakeStringChecker() [free function] - module.add_function('MakeStringChecker', 'ns3::Ptr< ns3::AttributeChecker const >', []) + module.add_function('MakeStringChecker', + 'ns3::Ptr< ns3::AttributeChecker const >', + []) ## enum.h: extern ns3::Ptr ns3::MakeEnumChecker(int v1, std::string n1, int v2=0, std::string n2="", int v3=0, std::string n3="", int v4=0, std::string n4="", int v5=0, std::string n5="", int v6=0, std::string n6="", int v7=0, std::string n7="", int v8=0, std::string n8="", int v9=0, std::string n9="", int v10=0, std::string n10="", int v11=0, std::string n11="", int v12=0, std::string n12="") [free function] - module.add_function('MakeEnumChecker', 'ns3::Ptr< ns3::AttributeChecker const >', [param('int', 'v1'), param('std::string', 'n1'), param('int', 'v2', default_value='0'), param('std::string', 'n2', default_value='""'), param('int', 'v3', default_value='0'), param('std::string', 'n3', default_value='""'), param('int', 'v4', default_value='0'), param('std::string', 'n4', default_value='""'), param('int', 'v5', default_value='0'), param('std::string', 'n5', default_value='""'), param('int', 'v6', default_value='0'), param('std::string', 'n6', default_value='""'), param('int', 'v7', default_value='0'), param('std::string', 'n7', default_value='""'), param('int', 'v8', default_value='0'), param('std::string', 'n8', default_value='""'), param('int', 'v9', default_value='0'), param('std::string', 'n9', default_value='""'), param('int', 'v10', default_value='0'), param('std::string', 'n10', default_value='""'), param('int', 'v11', default_value='0'), param('std::string', 'n11', default_value='""'), param('int', 'v12', default_value='0'), param('std::string', 'n12', default_value='""')]) + module.add_function('MakeEnumChecker', + 'ns3::Ptr< ns3::AttributeChecker const >', + [param('int', 'v1'), param('std::string', 'n1'), param('int', 'v2', default_value='0'), param('std::string', 'n2', default_value='""'), param('int', 'v3', default_value='0'), param('std::string', 'n3', default_value='""'), param('int', 'v4', default_value='0'), param('std::string', 'n4', default_value='""'), param('int', 'v5', default_value='0'), param('std::string', 'n5', default_value='""'), param('int', 'v6', default_value='0'), param('std::string', 'n6', default_value='""'), param('int', 'v7', default_value='0'), param('std::string', 'n7', default_value='""'), param('int', 'v8', default_value='0'), param('std::string', 'n8', default_value='""'), param('int', 'v9', default_value='0'), param('std::string', 'n9', default_value='""'), param('int', 'v10', default_value='0'), param('std::string', 'n10', default_value='""'), param('int', 'v11', default_value='0'), param('std::string', 'n11', default_value='""'), param('int', 'v12', default_value='0'), param('std::string', 'n12', default_value='""')]) ## type-id.h: extern ns3::Ptr ns3::MakeTypeIdChecker() [free function] - module.add_function('MakeTypeIdChecker', 'ns3::Ptr< ns3::AttributeChecker const >', []) + module.add_function('MakeTypeIdChecker', + 'ns3::Ptr< ns3::AttributeChecker const >', + []) ## ptr.h: extern ns3::Ptr ns3::Create() [free function] - module.add_function('Create', 'ns3::Ptr< ns3::PointerValue >', [], template_parameters=['ns3::PointerValue']) + module.add_function('Create', + 'ns3::Ptr< ns3::PointerValue >', + [], + template_parameters=['ns3::PointerValue']) ## ptr.h: extern ns3::Ptr ns3::Create() [free function] - module.add_function('Create', 'ns3::Ptr< ns3::ObjectVectorValue >', [], template_parameters=['ns3::ObjectVectorValue']) + module.add_function('Create', + 'ns3::Ptr< ns3::ObjectVectorValue >', + [], + template_parameters=['ns3::ObjectVectorValue']) ## object-factory.h: extern ns3::Ptr ns3::MakeObjectFactoryChecker() [free function] - module.add_function('MakeObjectFactoryChecker', 'ns3::Ptr< ns3::AttributeChecker const >', []) + module.add_function('MakeObjectFactoryChecker', + 'ns3::Ptr< ns3::AttributeChecker const >', + []) ## breakpoint.h: extern void ns3::BreakpointFallback() [free function] - module.add_function('BreakpointFallback', 'void', []) + module.add_function('BreakpointFallback', + 'void', + []) ## random-variable.h: extern ns3::Ptr ns3::MakeRandomVariableChecker() [free function] - module.add_function('MakeRandomVariableChecker', 'ns3::Ptr< ns3::AttributeChecker const >', []) + module.add_function('MakeRandomVariableChecker', + 'ns3::Ptr< ns3::AttributeChecker const >', + []) register_functions_ns3_internal(module.get_submodule('internal'), root_module) register_functions_ns3_TimeStepPrecision(module.get_submodule('TimeStepPrecision'), root_module) register_functions_ns3_Config(module.get_submodule('Config'), root_module) @@ -1329,11 +2065,17 @@ def register_functions(root_module): def register_functions_ns3_internal(module, root_module): ## uinteger.h: extern ns3::Ptr ns3::internal::MakeUintegerChecker(uint64_t min, uint64_t max, std::string name) [free function] - module.add_function('MakeUintegerChecker', 'ns3::Ptr< ns3::AttributeChecker const >', [param('uint64_t', 'min'), param('uint64_t', 'max'), param('std::string', 'name')]) + module.add_function('MakeUintegerChecker', + 'ns3::Ptr< ns3::AttributeChecker const >', + [param('uint64_t', 'min'), param('uint64_t', 'max'), param('std::string', 'name')]) ## integer.h: extern ns3::Ptr ns3::internal::MakeIntegerChecker(int64_t min, int64_t max, std::string name) [free function] - module.add_function('MakeIntegerChecker', 'ns3::Ptr< ns3::AttributeChecker const >', [param('int64_t', 'min'), param('int64_t', 'max'), param('std::string', 'name')]) + module.add_function('MakeIntegerChecker', + 'ns3::Ptr< ns3::AttributeChecker const >', + [param('int64_t', 'min'), param('int64_t', 'max'), param('std::string', 'name')]) ## double.h: extern ns3::Ptr ns3::internal::MakeDoubleChecker(double min, double max, std::string name) [free function] - module.add_function('MakeDoubleChecker', 'ns3::Ptr< ns3::AttributeChecker const >', [param('double', 'min'), param('double', 'max'), param('std::string', 'name')]) + module.add_function('MakeDoubleChecker', + 'ns3::Ptr< ns3::AttributeChecker const >', + [param('double', 'min'), param('double', 'max'), param('std::string', 'name')]) return def register_functions_ns3_TimeStepPrecision(module, root_module): @@ -1341,31 +2083,57 @@ def register_functions_ns3_TimeStepPrecision(module, root_module): def register_functions_ns3_Config(module, root_module): ## config.h: extern bool ns3::Config::SetDefaultFailSafe(std::string name, ns3::AttributeValue const & value) [free function] - module.add_function('SetDefaultFailSafe', 'bool', [param('std::string', 'name'), param('ns3::AttributeValue&', 'value', is_const=True)]) + module.add_function('SetDefaultFailSafe', + 'bool', + [param('std::string', 'name'), param('ns3::AttributeValue&', 'value', is_const=True)]) ## config.h: extern void ns3::Config::DisconnectWithoutContext(std::string path, ns3::CallbackBase const & cb) [free function] - module.add_function('DisconnectWithoutContext', 'void', [param('std::string', 'path'), param('ns3::CallbackBase&', 'cb', is_const=True)]) + module.add_function('DisconnectWithoutContext', + 'void', + [param('std::string', 'path'), param('ns3::CallbackBase&', 'cb', is_const=True)]) ## config.h: extern void ns3::Config::SetDefault(std::string name, ns3::AttributeValue const & value) [free function] - module.add_function('SetDefault', 'void', [param('std::string', 'name'), param('ns3::AttributeValue&', 'value', is_const=True)]) + module.add_function('SetDefault', + 'void', + [param('std::string', 'name'), param('ns3::AttributeValue&', 'value', is_const=True)]) ## config.h: extern void ns3::Config::Connect(std::string path, ns3::CallbackBase const & cb) [free function] - module.add_function('Connect', 'void', [param('std::string', 'path'), param('ns3::CallbackBase&', 'cb', is_const=True)]) + module.add_function('Connect', + 'void', + [param('std::string', 'path'), param('ns3::CallbackBase&', 'cb', is_const=True)]) ## config.h: extern ns3::Ptr ns3::Config::GetRootNamespaceObject(uint32_t i) [free function] - module.add_function('GetRootNamespaceObject', 'ns3::Ptr< ns3::Object >', [param('uint32_t', 'i')]) + module.add_function('GetRootNamespaceObject', + 'ns3::Ptr< ns3::Object >', + [param('uint32_t', 'i')]) ## config.h: extern void ns3::Config::ConnectWithoutContext(std::string path, ns3::CallbackBase const & cb) [free function] - module.add_function('ConnectWithoutContext', 'void', [param('std::string', 'path'), param('ns3::CallbackBase&', 'cb', is_const=True)]) + module.add_function('ConnectWithoutContext', + 'void', + [param('std::string', 'path'), param('ns3::CallbackBase&', 'cb', is_const=True)]) ## config.h: extern void ns3::Config::UnregisterRootNamespaceObject(ns3::Ptr obj) [free function] - module.add_function('UnregisterRootNamespaceObject', 'void', [param('ns3::Ptr< ns3::Object >', 'obj')]) + module.add_function('UnregisterRootNamespaceObject', + 'void', + [param('ns3::Ptr< ns3::Object >', 'obj')]) ## config.h: extern bool ns3::Config::SetGlobalFailSafe(std::string name, ns3::AttributeValue const & value) [free function] - module.add_function('SetGlobalFailSafe', 'bool', [param('std::string', 'name'), param('ns3::AttributeValue&', 'value', is_const=True)]) + module.add_function('SetGlobalFailSafe', + 'bool', + [param('std::string', 'name'), param('ns3::AttributeValue&', 'value', is_const=True)]) ## config.h: extern uint32_t ns3::Config::GetRootNamespaceObjectN() [free function] - module.add_function('GetRootNamespaceObjectN', 'uint32_t', []) + module.add_function('GetRootNamespaceObjectN', + 'uint32_t', + []) ## config.h: extern void ns3::Config::Set(std::string path, ns3::AttributeValue const & value) [free function] - module.add_function('Set', 'void', [param('std::string', 'path'), param('ns3::AttributeValue&', 'value', is_const=True)]) + module.add_function('Set', + 'void', + [param('std::string', 'path'), param('ns3::AttributeValue&', 'value', is_const=True)]) ## config.h: extern void ns3::Config::SetGlobal(std::string name, ns3::AttributeValue const & value) [free function] - module.add_function('SetGlobal', 'void', [param('std::string', 'name'), param('ns3::AttributeValue&', 'value', is_const=True)]) + module.add_function('SetGlobal', + 'void', + [param('std::string', 'name'), param('ns3::AttributeValue&', 'value', is_const=True)]) ## config.h: extern void ns3::Config::RegisterRootNamespaceObject(ns3::Ptr obj) [free function] - module.add_function('RegisterRootNamespaceObject', 'void', [param('ns3::Ptr< ns3::Object >', 'obj')]) + module.add_function('RegisterRootNamespaceObject', + 'void', + [param('ns3::Ptr< ns3::Object >', 'obj')]) ## config.h: extern void ns3::Config::Disconnect(std::string path, ns3::CallbackBase const & cb) [free function] - module.add_function('Disconnect', 'void', [param('std::string', 'path'), param('ns3::CallbackBase&', 'cb', is_const=True)]) + module.add_function('Disconnect', + 'void', + [param('std::string', 'path'), param('ns3::CallbackBase&', 'cb', is_const=True)]) return def register_functions_ns3_olsr(module, root_module): diff --git a/bindings/python/ns3_module_csma.py b/bindings/python/ns3_module_csma.py index a8a00d525..9488dc9b8 100644 --- a/bindings/python/ns3_module_csma.py +++ b/bindings/python/ns3_module_csma.py @@ -1,4 +1,4 @@ -from pybindgen import Module, FileCodeSink, write_preamble, param, retval +from pybindgen import Module, FileCodeSink, param, retval, cppclass def register_types(module): root_module = module.get_root() @@ -69,11 +69,13 @@ def register_Ns3CsmaDeviceRec_methods(root_module, cls): ## csma-channel.h: ns3::CsmaDeviceRec::active [variable] cls.add_instance_attribute('active', 'bool', is_const=False) ## csma-channel.h: ns3::CsmaDeviceRec::CsmaDeviceRec() [constructor] - cls.add_constructor([], visibility='public') + cls.add_constructor([]) ## csma-channel.h: ns3::CsmaDeviceRec::CsmaDeviceRec(ns3::Ptr device) [constructor] - cls.add_constructor([param('ns3::Ptr< ns3::CsmaNetDevice >', 'device')], visibility='public') + cls.add_constructor([param('ns3::Ptr< ns3::CsmaNetDevice >', 'device')]) ## csma-channel.h: bool ns3::CsmaDeviceRec::IsActive() [member function] - cls.add_method('IsActive', 'bool', []) + cls.add_method('IsActive', + 'bool', + []) return def register_Ns3Backoff_methods(root_module, cls): @@ -88,145 +90,306 @@ def register_Ns3Backoff_methods(root_module, cls): ## backoff.h: ns3::Backoff::m_slotTime [variable] cls.add_instance_attribute('m_slotTime', 'ns3::Time', is_const=False) ## backoff.h: ns3::Backoff::Backoff() [constructor] - cls.add_constructor([], visibility='public') + cls.add_constructor([]) ## backoff.h: ns3::Backoff::Backoff(ns3::Time slotTime, uint32_t minSlots, uint32_t maxSlots, uint32_t ceiling, uint32_t maxRetries) [constructor] - cls.add_constructor([param('ns3::Time', 'slotTime'), param('uint32_t', 'minSlots'), param('uint32_t', 'maxSlots'), param('uint32_t', 'ceiling'), param('uint32_t', 'maxRetries')], visibility='public') + cls.add_constructor([param('ns3::Time', 'slotTime'), param('uint32_t', 'minSlots'), param('uint32_t', 'maxSlots'), param('uint32_t', 'ceiling'), param('uint32_t', 'maxRetries')]) ## backoff.h: ns3::Time ns3::Backoff::GetBackoffTime() [member function] - cls.add_method('GetBackoffTime', 'ns3::Time', []) + cls.add_method('GetBackoffTime', + 'ns3::Time', + []) ## backoff.h: void ns3::Backoff::ResetBackoffTime() [member function] - cls.add_method('ResetBackoffTime', 'void', []) + cls.add_method('ResetBackoffTime', + 'void', + []) ## backoff.h: bool ns3::Backoff::MaxRetriesReached() [member function] - cls.add_method('MaxRetriesReached', 'bool', []) + cls.add_method('MaxRetriesReached', + 'bool', + []) ## backoff.h: void ns3::Backoff::IncrNumRetries() [member function] - cls.add_method('IncrNumRetries', 'void', []) + cls.add_method('IncrNumRetries', + 'void', + []) return def register_Ns3CsmaChannel_methods(root_module, cls): ## csma-channel.h: static ns3::TypeId ns3::CsmaChannel::GetTypeId() [member function] - cls.add_method('GetTypeId', 'ns3::TypeId', [], is_static=True) + cls.add_method('GetTypeId', + 'ns3::TypeId', + [], + is_static=True) ## csma-channel.h: ns3::CsmaChannel::CsmaChannel() [constructor] - cls.add_constructor([], visibility='public') + cls.add_constructor([]) ## csma-channel.h: int32_t ns3::CsmaChannel::Attach(ns3::Ptr device) [member function] - cls.add_method('Attach', 'int32_t', [param('ns3::Ptr< ns3::CsmaNetDevice >', 'device')]) + cls.add_method('Attach', + 'int32_t', + [param('ns3::Ptr< ns3::CsmaNetDevice >', 'device')]) ## csma-channel.h: bool ns3::CsmaChannel::Detach(ns3::Ptr device) [member function] - cls.add_method('Detach', 'bool', [param('ns3::Ptr< ns3::CsmaNetDevice >', 'device')]) + cls.add_method('Detach', + 'bool', + [param('ns3::Ptr< ns3::CsmaNetDevice >', 'device')]) ## csma-channel.h: bool ns3::CsmaChannel::Detach(uint32_t deviceId) [member function] - cls.add_method('Detach', 'bool', [param('uint32_t', 'deviceId')]) + cls.add_method('Detach', + 'bool', + [param('uint32_t', 'deviceId')]) ## csma-channel.h: bool ns3::CsmaChannel::Reattach(uint32_t deviceId) [member function] - cls.add_method('Reattach', 'bool', [param('uint32_t', 'deviceId')]) + cls.add_method('Reattach', + 'bool', + [param('uint32_t', 'deviceId')]) ## csma-channel.h: bool ns3::CsmaChannel::Reattach(ns3::Ptr device) [member function] - cls.add_method('Reattach', 'bool', [param('ns3::Ptr< ns3::CsmaNetDevice >', 'device')]) + cls.add_method('Reattach', + 'bool', + [param('ns3::Ptr< ns3::CsmaNetDevice >', 'device')]) ## csma-channel.h: bool ns3::CsmaChannel::TransmitStart(ns3::Ptr p, uint32_t srcId) [member function] - cls.add_method('TransmitStart', 'bool', [param('ns3::Ptr< ns3::Packet >', 'p'), param('uint32_t', 'srcId')]) + cls.add_method('TransmitStart', + 'bool', + [param('ns3::Ptr< ns3::Packet >', 'p'), param('uint32_t', 'srcId')]) ## csma-channel.h: bool ns3::CsmaChannel::TransmitEnd() [member function] - cls.add_method('TransmitEnd', 'bool', []) + cls.add_method('TransmitEnd', + 'bool', + []) ## csma-channel.h: void ns3::CsmaChannel::PropagationCompleteEvent() [member function] - cls.add_method('PropagationCompleteEvent', 'void', []) + cls.add_method('PropagationCompleteEvent', + 'void', + []) ## csma-channel.h: int32_t ns3::CsmaChannel::GetDeviceNum(ns3::Ptr device) [member function] - cls.add_method('GetDeviceNum', 'int32_t', [param('ns3::Ptr< ns3::CsmaNetDevice >', 'device')]) + cls.add_method('GetDeviceNum', + 'int32_t', + [param('ns3::Ptr< ns3::CsmaNetDevice >', 'device')]) ## csma-channel.h: ns3::WireState ns3::CsmaChannel::GetState() [member function] - cls.add_method('GetState', 'ns3::WireState', []) + cls.add_method('GetState', + 'ns3::WireState', + []) ## csma-channel.h: bool ns3::CsmaChannel::IsBusy() [member function] - cls.add_method('IsBusy', 'bool', []) + cls.add_method('IsBusy', + 'bool', + []) ## csma-channel.h: bool ns3::CsmaChannel::IsActive(uint32_t deviceId) [member function] - cls.add_method('IsActive', 'bool', [param('uint32_t', 'deviceId')]) + cls.add_method('IsActive', + 'bool', + [param('uint32_t', 'deviceId')]) ## csma-channel.h: uint32_t ns3::CsmaChannel::GetNumActDevices() [member function] - cls.add_method('GetNumActDevices', 'uint32_t', []) + cls.add_method('GetNumActDevices', + 'uint32_t', + []) ## csma-channel.h: uint32_t ns3::CsmaChannel::GetNDevices() const [member function] - cls.add_method('GetNDevices', 'uint32_t', [], is_const=True, is_virtual=True) + cls.add_method('GetNDevices', + 'uint32_t', + [], + is_const=True, is_virtual=True) ## csma-channel.h: ns3::Ptr ns3::CsmaChannel::GetDevice(uint32_t i) const [member function] - cls.add_method('GetDevice', 'ns3::Ptr< ns3::NetDevice >', [param('uint32_t', 'i')], is_const=True, is_virtual=True) + cls.add_method('GetDevice', + 'ns3::Ptr< ns3::NetDevice >', + [param('uint32_t', 'i')], + is_const=True, is_virtual=True) ## csma-channel.h: ns3::Ptr ns3::CsmaChannel::GetCsmaDevice(uint32_t i) const [member function] - cls.add_method('GetCsmaDevice', 'ns3::Ptr< ns3::CsmaNetDevice >', [param('uint32_t', 'i')], is_const=True) + cls.add_method('GetCsmaDevice', + 'ns3::Ptr< ns3::CsmaNetDevice >', + [param('uint32_t', 'i')], + is_const=True) ## csma-channel.h: ns3::DataRate ns3::CsmaChannel::GetDataRate() [member function] - cls.add_method('GetDataRate', 'ns3::DataRate', [], is_virtual=True) + cls.add_method('GetDataRate', + 'ns3::DataRate', + [], + is_virtual=True) ## csma-channel.h: ns3::Time ns3::CsmaChannel::GetDelay() [member function] - cls.add_method('GetDelay', 'ns3::Time', [], is_virtual=True) + cls.add_method('GetDelay', + 'ns3::Time', + [], + is_virtual=True) return def register_Ns3CsmaNetDevice_methods(root_module, cls): ## csma-net-device.h: static ns3::TypeId ns3::CsmaNetDevice::GetTypeId() [member function] - cls.add_method('GetTypeId', 'ns3::TypeId', [], is_static=True) + cls.add_method('GetTypeId', + 'ns3::TypeId', + [], + is_static=True) ## csma-net-device.h: ns3::CsmaNetDevice::CsmaNetDevice() [constructor] - cls.add_constructor([], visibility='public') + cls.add_constructor([]) ## csma-net-device.h: void ns3::CsmaNetDevice::SetInterframeGap(ns3::Time t) [member function] - cls.add_method('SetInterframeGap', 'void', [param('ns3::Time', 't')]) + cls.add_method('SetInterframeGap', + 'void', + [param('ns3::Time', 't')]) ## csma-net-device.h: void ns3::CsmaNetDevice::SetBackoffParams(ns3::Time slotTime, uint32_t minSlots, uint32_t maxSlots, uint32_t maxRetries, uint32_t ceiling) [member function] - cls.add_method('SetBackoffParams', 'void', [param('ns3::Time', 'slotTime'), param('uint32_t', 'minSlots'), param('uint32_t', 'maxSlots'), param('uint32_t', 'maxRetries'), param('uint32_t', 'ceiling')]) + cls.add_method('SetBackoffParams', + 'void', + [param('ns3::Time', 'slotTime'), param('uint32_t', 'minSlots'), param('uint32_t', 'maxSlots'), param('uint32_t', 'maxRetries'), param('uint32_t', 'ceiling')]) ## csma-net-device.h: bool ns3::CsmaNetDevice::Attach(ns3::Ptr ch) [member function] - cls.add_method('Attach', 'bool', [param('ns3::Ptr< ns3::CsmaChannel >', 'ch')]) + cls.add_method('Attach', + 'bool', + [param('ns3::Ptr< ns3::CsmaChannel >', 'ch')]) ## csma-net-device.h: void ns3::CsmaNetDevice::SetQueue(ns3::Ptr queue) [member function] - cls.add_method('SetQueue', 'void', [param('ns3::Ptr< ns3::Queue >', 'queue')]) + cls.add_method('SetQueue', + 'void', + [param('ns3::Ptr< ns3::Queue >', 'queue')]) ## csma-net-device.h: void ns3::CsmaNetDevice::SetReceiveErrorModel(ns3::Ptr em) [member function] - cls.add_method('SetReceiveErrorModel', 'void', [param('ns3::Ptr< ns3::ErrorModel >', 'em')]) + cls.add_method('SetReceiveErrorModel', + 'void', + [param('ns3::Ptr< ns3::ErrorModel >', 'em')]) ## csma-net-device.h: void ns3::CsmaNetDevice::Receive(ns3::Ptr p, ns3::Ptr sender) [member function] - cls.add_method('Receive', 'void', [param('ns3::Ptr< ns3::Packet >', 'p'), param('ns3::Ptr< ns3::CsmaNetDevice >', 'sender')]) + cls.add_method('Receive', + 'void', + [param('ns3::Ptr< ns3::Packet >', 'p'), param('ns3::Ptr< ns3::CsmaNetDevice >', 'sender')]) ## csma-net-device.h: bool ns3::CsmaNetDevice::IsSendEnabled() [member function] - cls.add_method('IsSendEnabled', 'bool', []) + cls.add_method('IsSendEnabled', + 'bool', + []) ## csma-net-device.h: void ns3::CsmaNetDevice::SetSendEnable(bool enable) [member function] - cls.add_method('SetSendEnable', 'void', [param('bool', 'enable')]) + cls.add_method('SetSendEnable', + 'void', + [param('bool', 'enable')]) ## csma-net-device.h: bool ns3::CsmaNetDevice::IsReceiveEnabled() [member function] - cls.add_method('IsReceiveEnabled', 'bool', []) + cls.add_method('IsReceiveEnabled', + 'bool', + []) ## csma-net-device.h: void ns3::CsmaNetDevice::SetReceiveEnable(bool enable) [member function] - cls.add_method('SetReceiveEnable', 'void', [param('bool', 'enable')]) + cls.add_method('SetReceiveEnable', + 'void', + [param('bool', 'enable')]) ## csma-net-device.h: void ns3::CsmaNetDevice::SetAddress(ns3::Mac48Address addr) [member function] - cls.add_method('SetAddress', 'void', [param('ns3::Mac48Address', 'addr')]) + cls.add_method('SetAddress', + 'void', + [param('ns3::Mac48Address', 'addr')]) ## csma-net-device.h: void ns3::CsmaNetDevice::SetName(std::string const name) [member function] - cls.add_method('SetName', 'void', [param('std::string', 'name', is_const=True)], is_virtual=True) + cls.add_method('SetName', + 'void', + [param('std::string', 'name', is_const=True)], + is_virtual=True) ## csma-net-device.h: std::string ns3::CsmaNetDevice::GetName() const [member function] - cls.add_method('GetName', 'std::string', [], is_const=True, is_virtual=True) + cls.add_method('GetName', + 'std::string', + [], + is_const=True, is_virtual=True) ## csma-net-device.h: void ns3::CsmaNetDevice::SetIfIndex(uint32_t const index) [member function] - cls.add_method('SetIfIndex', 'void', [param('uint32_t', 'index', is_const=True)], is_virtual=True) + cls.add_method('SetIfIndex', + 'void', + [param('uint32_t', 'index', is_const=True)], + is_virtual=True) ## csma-net-device.h: uint32_t ns3::CsmaNetDevice::GetIfIndex() const [member function] - cls.add_method('GetIfIndex', 'uint32_t', [], is_const=True, is_virtual=True) + cls.add_method('GetIfIndex', + 'uint32_t', + [], + is_const=True, is_virtual=True) ## csma-net-device.h: ns3::Ptr ns3::CsmaNetDevice::GetChannel() const [member function] - cls.add_method('GetChannel', 'ns3::Ptr< ns3::Channel >', [], is_const=True, is_virtual=True) + cls.add_method('GetChannel', + 'ns3::Ptr< ns3::Channel >', + [], + is_const=True, is_virtual=True) ## csma-net-device.h: ns3::Address ns3::CsmaNetDevice::GetAddress() const [member function] - cls.add_method('GetAddress', 'ns3::Address', [], is_const=True, is_virtual=True) + cls.add_method('GetAddress', + 'ns3::Address', + [], + is_const=True, is_virtual=True) ## csma-net-device.h: bool ns3::CsmaNetDevice::SetMtu(uint16_t const mtu) [member function] - cls.add_method('SetMtu', 'bool', [param('uint16_t', 'mtu', is_const=True)], is_virtual=True) + cls.add_method('SetMtu', + 'bool', + [param('uint16_t', 'mtu', is_const=True)], + is_virtual=True) ## csma-net-device.h: uint16_t ns3::CsmaNetDevice::GetMtu() const [member function] - cls.add_method('GetMtu', 'uint16_t', [], is_const=True, is_virtual=True) + cls.add_method('GetMtu', + 'uint16_t', + [], + is_const=True, is_virtual=True) ## csma-net-device.h: bool ns3::CsmaNetDevice::IsLinkUp() const [member function] - cls.add_method('IsLinkUp', 'bool', [], is_const=True, is_virtual=True) + cls.add_method('IsLinkUp', + 'bool', + [], + is_const=True, is_virtual=True) ## csma-net-device.h: void ns3::CsmaNetDevice::SetLinkChangeCallback(ns3::Callback callback) [member function] - cls.add_method('SetLinkChangeCallback', 'void', [param('ns3::Callback< void, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty >', 'callback')], is_virtual=True) + cls.add_method('SetLinkChangeCallback', + 'void', + [param('ns3::Callback< void, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty >', 'callback')], + is_virtual=True) ## csma-net-device.h: bool ns3::CsmaNetDevice::IsBroadcast() const [member function] - cls.add_method('IsBroadcast', 'bool', [], is_const=True, is_virtual=True) + cls.add_method('IsBroadcast', + 'bool', + [], + is_const=True, is_virtual=True) ## csma-net-device.h: ns3::Address ns3::CsmaNetDevice::GetBroadcast() const [member function] - cls.add_method('GetBroadcast', 'ns3::Address', [], is_const=True, is_virtual=True) + cls.add_method('GetBroadcast', + 'ns3::Address', + [], + is_const=True, is_virtual=True) ## csma-net-device.h: bool ns3::CsmaNetDevice::IsMulticast() const [member function] - cls.add_method('IsMulticast', 'bool', [], is_const=True, is_virtual=True) + cls.add_method('IsMulticast', + 'bool', + [], + is_const=True, is_virtual=True) ## csma-net-device.h: ns3::Address ns3::CsmaNetDevice::GetMulticast() const [member function] - cls.add_method('GetMulticast', 'ns3::Address', [], is_const=True, is_virtual=True) + cls.add_method('GetMulticast', + 'ns3::Address', + [], + is_const=True, is_virtual=True) ## csma-net-device.h: ns3::Address ns3::CsmaNetDevice::MakeMulticastAddress(ns3::Ipv4Address multicastGroup) const [member function] - cls.add_method('MakeMulticastAddress', 'ns3::Address', [param('ns3::Ipv4Address', 'multicastGroup')], is_const=True, is_virtual=True) + cls.add_method('MakeMulticastAddress', + 'ns3::Address', + [param('ns3::Ipv4Address', 'multicastGroup')], + is_const=True, is_virtual=True) ## csma-net-device.h: bool ns3::CsmaNetDevice::IsPointToPoint() const [member function] - cls.add_method('IsPointToPoint', 'bool', [], is_const=True, is_virtual=True) + cls.add_method('IsPointToPoint', + 'bool', + [], + is_const=True, is_virtual=True) ## csma-net-device.h: bool ns3::CsmaNetDevice::Send(ns3::Ptr packet, ns3::Address const & dest, uint16_t protocolNumber) [member function] - cls.add_method('Send', 'bool', [param('ns3::Ptr< ns3::Packet >', 'packet'), param('ns3::Address&', 'dest', is_const=True), param('uint16_t', 'protocolNumber')], is_virtual=True) + cls.add_method('Send', + 'bool', + [param('ns3::Ptr< ns3::Packet >', 'packet'), param('ns3::Address&', 'dest', is_const=True), param('uint16_t', 'protocolNumber')], + is_virtual=True) ## csma-net-device.h: bool ns3::CsmaNetDevice::SendFrom(ns3::Ptr packet, ns3::Address const & source, ns3::Address const & dest, uint16_t protocolNumber) [member function] - cls.add_method('SendFrom', 'bool', [param('ns3::Ptr< ns3::Packet >', 'packet'), param('ns3::Address&', 'source', is_const=True), param('ns3::Address&', 'dest', is_const=True), param('uint16_t', 'protocolNumber')], is_virtual=True) + cls.add_method('SendFrom', + 'bool', + [param('ns3::Ptr< ns3::Packet >', 'packet'), param('ns3::Address&', 'source', is_const=True), param('ns3::Address&', 'dest', is_const=True), param('uint16_t', 'protocolNumber')], + is_virtual=True) ## csma-net-device.h: ns3::Ptr ns3::CsmaNetDevice::GetNode() const [member function] - cls.add_method('GetNode', 'ns3::Ptr< ns3::Node >', [], is_const=True, is_virtual=True) + cls.add_method('GetNode', + 'ns3::Ptr< ns3::Node >', + [], + is_const=True, is_virtual=True) ## csma-net-device.h: void ns3::CsmaNetDevice::SetNode(ns3::Ptr node) [member function] - cls.add_method('SetNode', 'void', [param('ns3::Ptr< ns3::Node >', 'node')], is_virtual=True) + cls.add_method('SetNode', + 'void', + [param('ns3::Ptr< ns3::Node >', 'node')], + is_virtual=True) ## csma-net-device.h: bool ns3::CsmaNetDevice::NeedsArp() const [member function] - cls.add_method('NeedsArp', 'bool', [], is_const=True, is_virtual=True) + cls.add_method('NeedsArp', + 'bool', + [], + is_const=True, is_virtual=True) ## csma-net-device.h: void ns3::CsmaNetDevice::SetReceiveCallback(ns3::Callback, ns3::Ptr, unsigned short, ns3::Address const&, ns3::empty, ns3::empty> cb) [member function] - cls.add_method('SetReceiveCallback', 'void', [param('ns3::Callback< bool, ns3::Ptr< ns3::NetDevice >, ns3::Ptr< ns3::Packet >, unsigned short, ns3::Address const&, ns3::empty, ns3::empty >', 'cb')], is_virtual=True) + cls.add_method('SetReceiveCallback', + 'void', + [param('ns3::Callback< bool, ns3::Ptr< ns3::NetDevice >, ns3::Ptr< ns3::Packet >, unsigned short, ns3::Address const&, ns3::empty, ns3::empty >', 'cb')], + is_virtual=True) ## csma-net-device.h: void ns3::CsmaNetDevice::SetPromiscReceiveCallback(ns3::Callback, ns3::Ptr, unsigned short, ns3::Address const&, ns3::Address const&, ns3::NetDevice::PacketType> cb) [member function] - cls.add_method('SetPromiscReceiveCallback', 'void', [param('ns3::Callback< bool, ns3::Ptr< ns3::NetDevice >, ns3::Ptr< ns3::Packet >, unsigned short, ns3::Address const&, ns3::Address const&, ns3::NetDevice::PacketType >', 'cb')], is_virtual=True) + cls.add_method('SetPromiscReceiveCallback', + 'void', + [param('ns3::Callback< bool, ns3::Ptr< ns3::NetDevice >, ns3::Ptr< ns3::Packet >, unsigned short, ns3::Address const&, ns3::Address const&, ns3::NetDevice::PacketType >', 'cb')], + is_virtual=True) ## csma-net-device.h: bool ns3::CsmaNetDevice::SupportsPromiscuous() const [member function] - cls.add_method('SupportsPromiscuous', 'bool', [], is_const=True, is_virtual=True) + cls.add_method('SupportsPromiscuous', + 'bool', + [], + is_const=True, is_virtual=True) ## csma-net-device.h: void ns3::CsmaNetDevice::DoDispose() [member function] - cls.add_method('DoDispose', 'void', [], visibility='protected', is_virtual=True) + cls.add_method('DoDispose', + 'void', + [], + visibility='protected', is_virtual=True) ## csma-net-device.h: ns3::Ptr ns3::CsmaNetDevice::GetQueue() const [member function] - cls.add_method('GetQueue', 'ns3::Ptr< ns3::Queue >', [], is_const=True, visibility='protected') + cls.add_method('GetQueue', + 'ns3::Ptr< ns3::Queue >', + [], + is_const=True, visibility='protected') ## csma-net-device.h: void ns3::CsmaNetDevice::AddHeader(ns3::Ptr p, ns3::Mac48Address source, ns3::Mac48Address dest, uint16_t protocolNumber) [member function] - cls.add_method('AddHeader', 'void', [param('ns3::Ptr< ns3::Packet >', 'p'), param('ns3::Mac48Address', 'source'), param('ns3::Mac48Address', 'dest'), param('uint16_t', 'protocolNumber')], visibility='protected') + cls.add_method('AddHeader', + 'void', + [param('ns3::Ptr< ns3::Packet >', 'p'), param('ns3::Mac48Address', 'source'), param('ns3::Mac48Address', 'dest'), param('uint16_t', 'protocolNumber')], + visibility='protected') ## csma-net-device.h: bool ns3::CsmaNetDevice::ProcessHeader(ns3::Ptr p, uint16_t & param) [member function] - cls.add_method('ProcessHeader', 'bool', [param('ns3::Ptr< ns3::Packet >', 'p'), param('uint16_t&', 'param')], visibility='protected') + cls.add_method('ProcessHeader', + 'bool', + [param('ns3::Ptr< ns3::Packet >', 'p'), param('uint16_t&', 'param')], + visibility='protected') return def register_functions(root_module): diff --git a/bindings/python/ns3_module_global_routing.py b/bindings/python/ns3_module_global_routing.py index 6a80d9623..563852dc8 100644 --- a/bindings/python/ns3_module_global_routing.py +++ b/bindings/python/ns3_module_global_routing.py @@ -1,4 +1,4 @@ -from pybindgen import Module, FileCodeSink, write_preamble, param, retval +from pybindgen import Module, FileCodeSink, param, retval, cppclass def register_types(module): root_module = module.get_root() @@ -67,99 +67,193 @@ def register_methods(root_module): def register_Ns3GlobalRouteManager_methods(root_module, cls): ## global-route-manager.h: static void ns3::GlobalRouteManager::PopulateRoutingTables() [member function] - cls.add_method('PopulateRoutingTables', 'void', [], is_static=True) + cls.add_method('PopulateRoutingTables', + 'void', + [], + is_static=True) ## global-route-manager.h: static uint32_t ns3::GlobalRouteManager::AllocateRouterId() [member function] - cls.add_method('AllocateRouterId', 'uint32_t', [], is_static=True) + cls.add_method('AllocateRouterId', + 'uint32_t', + [], + is_static=True) return def register_Ns3GlobalRoutingLSA_methods(root_module, cls): ## global-router-interface.h: ns3::GlobalRoutingLSA::GlobalRoutingLSA() [constructor] - cls.add_constructor([], visibility='public') + cls.add_constructor([]) ## global-router-interface.h: ns3::GlobalRoutingLSA::GlobalRoutingLSA(ns3::GlobalRoutingLSA::SPFStatus status, ns3::Ipv4Address linkStateId, ns3::Ipv4Address advertisingRtr) [constructor] - cls.add_constructor([param('ns3::GlobalRoutingLSA::SPFStatus', 'status'), param('ns3::Ipv4Address', 'linkStateId'), param('ns3::Ipv4Address', 'advertisingRtr')], visibility='public') + cls.add_constructor([param('ns3::GlobalRoutingLSA::SPFStatus', 'status'), param('ns3::Ipv4Address', 'linkStateId'), param('ns3::Ipv4Address', 'advertisingRtr')]) ## global-router-interface.h: ns3::GlobalRoutingLSA::GlobalRoutingLSA(ns3::GlobalRoutingLSA & lsa) [constructor] - cls.add_constructor([param('ns3::GlobalRoutingLSA&', 'lsa')], visibility='public') + cls.add_constructor([param('ns3::GlobalRoutingLSA&', 'lsa')]) ## global-router-interface.h: uint32_t ns3::GlobalRoutingLSA::AddAttachedRouter(ns3::Ipv4Address addr) [member function] - cls.add_method('AddAttachedRouter', 'uint32_t', [param('ns3::Ipv4Address', 'addr')]) + cls.add_method('AddAttachedRouter', + 'uint32_t', + [param('ns3::Ipv4Address', 'addr')]) ## global-router-interface.h: uint32_t ns3::GlobalRoutingLSA::AddLinkRecord(ns3::GlobalRoutingLinkRecord * lr) [member function] - cls.add_method('AddLinkRecord', 'uint32_t', [param('ns3::GlobalRoutingLinkRecord *', 'lr')]) + cls.add_method('AddLinkRecord', + 'uint32_t', + [param('ns3::GlobalRoutingLinkRecord *', 'lr')]) ## global-router-interface.h: void ns3::GlobalRoutingLSA::ClearLinkRecords() [member function] - cls.add_method('ClearLinkRecords', 'void', []) + cls.add_method('ClearLinkRecords', + 'void', + []) ## global-router-interface.h: void ns3::GlobalRoutingLSA::CopyLinkRecords(ns3::GlobalRoutingLSA const & lsa) [member function] - cls.add_method('CopyLinkRecords', 'void', [param('ns3::GlobalRoutingLSA&', 'lsa', is_const=True)]) + cls.add_method('CopyLinkRecords', + 'void', + [param('ns3::GlobalRoutingLSA&', 'lsa', is_const=True)]) ## global-router-interface.h: ns3::Ipv4Address ns3::GlobalRoutingLSA::GetAdvertisingRouter() const [member function] - cls.add_method('GetAdvertisingRouter', 'ns3::Ipv4Address', [], is_const=True) + cls.add_method('GetAdvertisingRouter', + 'ns3::Ipv4Address', + [], + is_const=True) ## global-router-interface.h: ns3::Ipv4Address ns3::GlobalRoutingLSA::GetAttachedRouter(uint32_t n) const [member function] - cls.add_method('GetAttachedRouter', 'ns3::Ipv4Address', [param('uint32_t', 'n')], is_const=True) + cls.add_method('GetAttachedRouter', + 'ns3::Ipv4Address', + [param('uint32_t', 'n')], + is_const=True) ## global-router-interface.h: ns3::GlobalRoutingLSA::LSType ns3::GlobalRoutingLSA::GetLSType() const [member function] - cls.add_method('GetLSType', 'ns3::GlobalRoutingLSA::LSType', [], is_const=True) + cls.add_method('GetLSType', + 'ns3::GlobalRoutingLSA::LSType', + [], + is_const=True) ## global-router-interface.h: ns3::GlobalRoutingLinkRecord * ns3::GlobalRoutingLSA::GetLinkRecord(uint32_t n) const [member function] - cls.add_method('GetLinkRecord', 'ns3::GlobalRoutingLinkRecord *', [param('uint32_t', 'n')], is_const=True) + cls.add_method('GetLinkRecord', + 'ns3::GlobalRoutingLinkRecord *', + [param('uint32_t', 'n')], + is_const=True) ## global-router-interface.h: ns3::Ipv4Address ns3::GlobalRoutingLSA::GetLinkStateId() const [member function] - cls.add_method('GetLinkStateId', 'ns3::Ipv4Address', [], is_const=True) + cls.add_method('GetLinkStateId', + 'ns3::Ipv4Address', + [], + is_const=True) ## global-router-interface.h: uint32_t ns3::GlobalRoutingLSA::GetNAttachedRouters() const [member function] - cls.add_method('GetNAttachedRouters', 'uint32_t', [], is_const=True) + cls.add_method('GetNAttachedRouters', + 'uint32_t', + [], + is_const=True) ## global-router-interface.h: uint32_t ns3::GlobalRoutingLSA::GetNLinkRecords() const [member function] - cls.add_method('GetNLinkRecords', 'uint32_t', [], is_const=True) + cls.add_method('GetNLinkRecords', + 'uint32_t', + [], + is_const=True) ## global-router-interface.h: ns3::Ipv4Mask ns3::GlobalRoutingLSA::GetNetworkLSANetworkMask() const [member function] - cls.add_method('GetNetworkLSANetworkMask', 'ns3::Ipv4Mask', [], is_const=True) + cls.add_method('GetNetworkLSANetworkMask', + 'ns3::Ipv4Mask', + [], + is_const=True) ## global-router-interface.h: ns3::GlobalRoutingLSA::SPFStatus ns3::GlobalRoutingLSA::GetStatus() const [member function] - cls.add_method('GetStatus', 'ns3::GlobalRoutingLSA::SPFStatus', [], is_const=True) + cls.add_method('GetStatus', + 'ns3::GlobalRoutingLSA::SPFStatus', + [], + is_const=True) ## global-router-interface.h: bool ns3::GlobalRoutingLSA::IsEmpty() const [member function] - cls.add_method('IsEmpty', 'bool', [], is_const=True) + cls.add_method('IsEmpty', + 'bool', + [], + is_const=True) ## global-router-interface.h: void ns3::GlobalRoutingLSA::Print(std::ostream & os) const [member function] - cls.add_method('Print', 'void', [param('std::ostream&', 'os')], is_const=True) + cls.add_method('Print', + 'void', + [param('std::ostream&', 'os')], + is_const=True) ## global-router-interface.h: void ns3::GlobalRoutingLSA::SetAdvertisingRouter(ns3::Ipv4Address rtr) [member function] - cls.add_method('SetAdvertisingRouter', 'void', [param('ns3::Ipv4Address', 'rtr')]) + cls.add_method('SetAdvertisingRouter', + 'void', + [param('ns3::Ipv4Address', 'rtr')]) ## global-router-interface.h: void ns3::GlobalRoutingLSA::SetLSType(ns3::GlobalRoutingLSA::LSType typ) [member function] - cls.add_method('SetLSType', 'void', [param('ns3::GlobalRoutingLSA::LSType', 'typ')]) + cls.add_method('SetLSType', + 'void', + [param('ns3::GlobalRoutingLSA::LSType', 'typ')]) ## global-router-interface.h: void ns3::GlobalRoutingLSA::SetLinkStateId(ns3::Ipv4Address addr) [member function] - cls.add_method('SetLinkStateId', 'void', [param('ns3::Ipv4Address', 'addr')]) + cls.add_method('SetLinkStateId', + 'void', + [param('ns3::Ipv4Address', 'addr')]) ## global-router-interface.h: void ns3::GlobalRoutingLSA::SetNetworkLSANetworkMask(ns3::Ipv4Mask mask) [member function] - cls.add_method('SetNetworkLSANetworkMask', 'void', [param('ns3::Ipv4Mask', 'mask')]) + cls.add_method('SetNetworkLSANetworkMask', + 'void', + [param('ns3::Ipv4Mask', 'mask')]) ## global-router-interface.h: void ns3::GlobalRoutingLSA::SetStatus(ns3::GlobalRoutingLSA::SPFStatus status) [member function] - cls.add_method('SetStatus', 'void', [param('ns3::GlobalRoutingLSA::SPFStatus', 'status')]) + cls.add_method('SetStatus', + 'void', + [param('ns3::GlobalRoutingLSA::SPFStatus', 'status')]) cls.add_output_stream_operator() return def register_Ns3GlobalRoutingLinkRecord_methods(root_module, cls): ## global-router-interface.h: ns3::GlobalRoutingLinkRecord::GlobalRoutingLinkRecord() [constructor] - cls.add_constructor([], visibility='public') + cls.add_constructor([]) ## global-router-interface.h: ns3::GlobalRoutingLinkRecord::GlobalRoutingLinkRecord(ns3::GlobalRoutingLinkRecord::LinkType linkType, ns3::Ipv4Address linkId, ns3::Ipv4Address linkData, uint16_t metric) [constructor] - cls.add_constructor([param('ns3::GlobalRoutingLinkRecord::LinkType', 'linkType'), param('ns3::Ipv4Address', 'linkId'), param('ns3::Ipv4Address', 'linkData'), param('uint16_t', 'metric')], visibility='public') + cls.add_constructor([param('ns3::GlobalRoutingLinkRecord::LinkType', 'linkType'), param('ns3::Ipv4Address', 'linkId'), param('ns3::Ipv4Address', 'linkData'), param('uint16_t', 'metric')]) ## global-router-interface.h: ns3::Ipv4Address ns3::GlobalRoutingLinkRecord::GetLinkId() const [member function] - cls.add_method('GetLinkId', 'ns3::Ipv4Address', [], is_const=True) + cls.add_method('GetLinkId', + 'ns3::Ipv4Address', + [], + is_const=True) ## global-router-interface.h: void ns3::GlobalRoutingLinkRecord::SetLinkId(ns3::Ipv4Address addr) [member function] - cls.add_method('SetLinkId', 'void', [param('ns3::Ipv4Address', 'addr')]) + cls.add_method('SetLinkId', + 'void', + [param('ns3::Ipv4Address', 'addr')]) ## global-router-interface.h: ns3::Ipv4Address ns3::GlobalRoutingLinkRecord::GetLinkData() const [member function] - cls.add_method('GetLinkData', 'ns3::Ipv4Address', [], is_const=True) + cls.add_method('GetLinkData', + 'ns3::Ipv4Address', + [], + is_const=True) ## global-router-interface.h: void ns3::GlobalRoutingLinkRecord::SetLinkData(ns3::Ipv4Address addr) [member function] - cls.add_method('SetLinkData', 'void', [param('ns3::Ipv4Address', 'addr')]) + cls.add_method('SetLinkData', + 'void', + [param('ns3::Ipv4Address', 'addr')]) ## global-router-interface.h: ns3::GlobalRoutingLinkRecord::LinkType ns3::GlobalRoutingLinkRecord::GetLinkType() const [member function] - cls.add_method('GetLinkType', 'ns3::GlobalRoutingLinkRecord::LinkType', [], is_const=True) + cls.add_method('GetLinkType', + 'ns3::GlobalRoutingLinkRecord::LinkType', + [], + is_const=True) ## global-router-interface.h: void ns3::GlobalRoutingLinkRecord::SetLinkType(ns3::GlobalRoutingLinkRecord::LinkType linkType) [member function] - cls.add_method('SetLinkType', 'void', [param('ns3::GlobalRoutingLinkRecord::LinkType', 'linkType')]) + cls.add_method('SetLinkType', + 'void', + [param('ns3::GlobalRoutingLinkRecord::LinkType', 'linkType')]) ## global-router-interface.h: uint16_t ns3::GlobalRoutingLinkRecord::GetMetric() const [member function] - cls.add_method('GetMetric', 'uint16_t', [], is_const=True) + cls.add_method('GetMetric', + 'uint16_t', + [], + is_const=True) ## global-router-interface.h: void ns3::GlobalRoutingLinkRecord::SetMetric(uint16_t metric) [member function] - cls.add_method('SetMetric', 'void', [param('uint16_t', 'metric')]) + cls.add_method('SetMetric', + 'void', + [param('uint16_t', 'metric')]) return def register_Ns3GlobalRouter_methods(root_module, cls): ## global-router-interface.h: static ns3::TypeId ns3::GlobalRouter::GetTypeId() [member function] - cls.add_method('GetTypeId', 'ns3::TypeId', [], is_static=True) + cls.add_method('GetTypeId', + 'ns3::TypeId', + [], + is_static=True) ## global-router-interface.h: ns3::GlobalRouter::GlobalRouter() [constructor] - cls.add_constructor([], visibility='public') + cls.add_constructor([]) ## global-router-interface.h: ns3::Ipv4Address ns3::GlobalRouter::GetRouterId() const [member function] - cls.add_method('GetRouterId', 'ns3::Ipv4Address', [], is_const=True) + cls.add_method('GetRouterId', + 'ns3::Ipv4Address', + [], + is_const=True) ## global-router-interface.h: uint32_t ns3::GlobalRouter::DiscoverLSAs() [member function] - cls.add_method('DiscoverLSAs', 'uint32_t', []) + cls.add_method('DiscoverLSAs', + 'uint32_t', + []) ## global-router-interface.h: uint32_t ns3::GlobalRouter::GetNumLSAs() const [member function] - cls.add_method('GetNumLSAs', 'uint32_t', [], is_const=True) + cls.add_method('GetNumLSAs', + 'uint32_t', + [], + is_const=True) ## global-router-interface.h: bool ns3::GlobalRouter::GetLSA(uint32_t n, ns3::GlobalRoutingLSA & lsa) const [member function] - cls.add_method('GetLSA', 'bool', [param('uint32_t', 'n'), param('ns3::GlobalRoutingLSA&', 'lsa')], is_const=True) + cls.add_method('GetLSA', + 'bool', + [param('uint32_t', 'n'), param('ns3::GlobalRoutingLSA&', 'lsa')], + is_const=True) ## global-router-interface.h: void ns3::GlobalRouter::DoDispose() [member function] - cls.add_method('DoDispose', 'void', [], visibility='private', is_virtual=True) + cls.add_method('DoDispose', + 'void', + [], + visibility='private', is_virtual=True) return def register_functions(root_module): diff --git a/bindings/python/ns3_module_helper.py b/bindings/python/ns3_module_helper.py index 99b4fa564..38945199d 100644 --- a/bindings/python/ns3_module_helper.py +++ b/bindings/python/ns3_module_helper.py @@ -1,4 +1,4 @@ -from pybindgen import Module, FileCodeSink, write_preamble, param, retval +from pybindgen import Module, FileCodeSink, param, retval, cppclass def register_types(module): root_module = module.get_root() @@ -103,296 +103,544 @@ def register_methods(root_module): def register_Ns3MobilityHelper_methods(root_module, cls): ## mobility-helper.h: ns3::MobilityHelper::MobilityHelper() [constructor] - cls.add_constructor([], visibility='public') + cls.add_constructor([]) ## mobility-helper.h: void ns3::MobilityHelper::SetPositionAllocator(ns3::Ptr allocator) [member function] - cls.add_method('SetPositionAllocator', 'void', [param('ns3::Ptr< ns3::PositionAllocator >', 'allocator')]) + cls.add_method('SetPositionAllocator', + 'void', + [param('ns3::Ptr< ns3::PositionAllocator >', 'allocator')]) ## mobility-helper.h: void ns3::MobilityHelper::SetPositionAllocator(std::string type, std::string n1="", ns3::AttributeValue const & v1=ns3::EmptyAttributeValue(), std::string n2="", ns3::AttributeValue const & v2=ns3::EmptyAttributeValue(), std::string n3="", ns3::AttributeValue const & v3=ns3::EmptyAttributeValue(), std::string n4="", ns3::AttributeValue const & v4=ns3::EmptyAttributeValue(), std::string n5="", ns3::AttributeValue const & v5=ns3::EmptyAttributeValue(), std::string n6="", ns3::AttributeValue const & v6=ns3::EmptyAttributeValue(), std::string n7="", ns3::AttributeValue const & v7=ns3::EmptyAttributeValue(), std::string n8="", ns3::AttributeValue const & v8=ns3::EmptyAttributeValue(), std::string n9="", ns3::AttributeValue const & v9=ns3::EmptyAttributeValue()) [member function] - cls.add_method('SetPositionAllocator', 'void', [param('std::string', 'type'), param('std::string', 'n1', default_value='""'), param('ns3::AttributeValue&', 'v1', default_value='ns3::EmptyAttributeValue()', is_const=True), param('std::string', 'n2', default_value='""'), param('ns3::AttributeValue&', 'v2', default_value='ns3::EmptyAttributeValue()', is_const=True), param('std::string', 'n3', default_value='""'), param('ns3::AttributeValue&', 'v3', default_value='ns3::EmptyAttributeValue()', is_const=True), param('std::string', 'n4', default_value='""'), param('ns3::AttributeValue&', 'v4', default_value='ns3::EmptyAttributeValue()', is_const=True), param('std::string', 'n5', default_value='""'), param('ns3::AttributeValue&', 'v5', default_value='ns3::EmptyAttributeValue()', is_const=True), param('std::string', 'n6', default_value='""'), param('ns3::AttributeValue&', 'v6', default_value='ns3::EmptyAttributeValue()', is_const=True), param('std::string', 'n7', default_value='""'), param('ns3::AttributeValue&', 'v7', default_value='ns3::EmptyAttributeValue()', is_const=True), param('std::string', 'n8', default_value='""'), param('ns3::AttributeValue&', 'v8', default_value='ns3::EmptyAttributeValue()', is_const=True), param('std::string', 'n9', default_value='""'), param('ns3::AttributeValue&', 'v9', default_value='ns3::EmptyAttributeValue()', is_const=True)]) + cls.add_method('SetPositionAllocator', + 'void', + [param('std::string', 'type'), param('std::string', 'n1', default_value='""'), param('ns3::AttributeValue&', 'v1', default_value='ns3::EmptyAttributeValue()', is_const=True), param('std::string', 'n2', default_value='""'), param('ns3::AttributeValue&', 'v2', default_value='ns3::EmptyAttributeValue()', is_const=True), param('std::string', 'n3', default_value='""'), param('ns3::AttributeValue&', 'v3', default_value='ns3::EmptyAttributeValue()', is_const=True), param('std::string', 'n4', default_value='""'), param('ns3::AttributeValue&', 'v4', default_value='ns3::EmptyAttributeValue()', is_const=True), param('std::string', 'n5', default_value='""'), param('ns3::AttributeValue&', 'v5', default_value='ns3::EmptyAttributeValue()', is_const=True), param('std::string', 'n6', default_value='""'), param('ns3::AttributeValue&', 'v6', default_value='ns3::EmptyAttributeValue()', is_const=True), param('std::string', 'n7', default_value='""'), param('ns3::AttributeValue&', 'v7', default_value='ns3::EmptyAttributeValue()', is_const=True), param('std::string', 'n8', default_value='""'), param('ns3::AttributeValue&', 'v8', default_value='ns3::EmptyAttributeValue()', is_const=True), param('std::string', 'n9', default_value='""'), param('ns3::AttributeValue&', 'v9', default_value='ns3::EmptyAttributeValue()', is_const=True)]) ## mobility-helper.h: void ns3::MobilityHelper::SetMobilityModel(std::string type, std::string n1="", ns3::AttributeValue const & v1=ns3::EmptyAttributeValue(), std::string n2="", ns3::AttributeValue const & v2=ns3::EmptyAttributeValue(), std::string n3="", ns3::AttributeValue const & v3=ns3::EmptyAttributeValue(), std::string n4="", ns3::AttributeValue const & v4=ns3::EmptyAttributeValue(), std::string n5="", ns3::AttributeValue const & v5=ns3::EmptyAttributeValue(), std::string n6="", ns3::AttributeValue const & v6=ns3::EmptyAttributeValue(), std::string n7="", ns3::AttributeValue const & v7=ns3::EmptyAttributeValue(), std::string n8="", ns3::AttributeValue const & v8=ns3::EmptyAttributeValue(), std::string n9="", ns3::AttributeValue const & v9=ns3::EmptyAttributeValue()) [member function] - cls.add_method('SetMobilityModel', 'void', [param('std::string', 'type'), param('std::string', 'n1', default_value='""'), param('ns3::AttributeValue&', 'v1', default_value='ns3::EmptyAttributeValue()', is_const=True), param('std::string', 'n2', default_value='""'), param('ns3::AttributeValue&', 'v2', default_value='ns3::EmptyAttributeValue()', is_const=True), param('std::string', 'n3', default_value='""'), param('ns3::AttributeValue&', 'v3', default_value='ns3::EmptyAttributeValue()', is_const=True), param('std::string', 'n4', default_value='""'), param('ns3::AttributeValue&', 'v4', default_value='ns3::EmptyAttributeValue()', is_const=True), param('std::string', 'n5', default_value='""'), param('ns3::AttributeValue&', 'v5', default_value='ns3::EmptyAttributeValue()', is_const=True), param('std::string', 'n6', default_value='""'), param('ns3::AttributeValue&', 'v6', default_value='ns3::EmptyAttributeValue()', is_const=True), param('std::string', 'n7', default_value='""'), param('ns3::AttributeValue&', 'v7', default_value='ns3::EmptyAttributeValue()', is_const=True), param('std::string', 'n8', default_value='""'), param('ns3::AttributeValue&', 'v8', default_value='ns3::EmptyAttributeValue()', is_const=True), param('std::string', 'n9', default_value='""'), param('ns3::AttributeValue&', 'v9', default_value='ns3::EmptyAttributeValue()', is_const=True)]) + cls.add_method('SetMobilityModel', + 'void', + [param('std::string', 'type'), param('std::string', 'n1', default_value='""'), param('ns3::AttributeValue&', 'v1', default_value='ns3::EmptyAttributeValue()', is_const=True), param('std::string', 'n2', default_value='""'), param('ns3::AttributeValue&', 'v2', default_value='ns3::EmptyAttributeValue()', is_const=True), param('std::string', 'n3', default_value='""'), param('ns3::AttributeValue&', 'v3', default_value='ns3::EmptyAttributeValue()', is_const=True), param('std::string', 'n4', default_value='""'), param('ns3::AttributeValue&', 'v4', default_value='ns3::EmptyAttributeValue()', is_const=True), param('std::string', 'n5', default_value='""'), param('ns3::AttributeValue&', 'v5', default_value='ns3::EmptyAttributeValue()', is_const=True), param('std::string', 'n6', default_value='""'), param('ns3::AttributeValue&', 'v6', default_value='ns3::EmptyAttributeValue()', is_const=True), param('std::string', 'n7', default_value='""'), param('ns3::AttributeValue&', 'v7', default_value='ns3::EmptyAttributeValue()', is_const=True), param('std::string', 'n8', default_value='""'), param('ns3::AttributeValue&', 'v8', default_value='ns3::EmptyAttributeValue()', is_const=True), param('std::string', 'n9', default_value='""'), param('ns3::AttributeValue&', 'v9', default_value='ns3::EmptyAttributeValue()', is_const=True)]) ## mobility-helper.h: void ns3::MobilityHelper::PushReferenceMobilityModel(ns3::Ptr reference) [member function] - cls.add_method('PushReferenceMobilityModel', 'void', [param('ns3::Ptr< ns3::Object >', 'reference')]) + cls.add_method('PushReferenceMobilityModel', + 'void', + [param('ns3::Ptr< ns3::Object >', 'reference')]) ## mobility-helper.h: void ns3::MobilityHelper::PopReferenceMobilityModel() [member function] - cls.add_method('PopReferenceMobilityModel', 'void', []) + cls.add_method('PopReferenceMobilityModel', + 'void', + []) ## mobility-helper.h: std::string ns3::MobilityHelper::GetMobilityModelType() const [member function] - cls.add_method('GetMobilityModelType', 'std::string', [], is_const=True) + cls.add_method('GetMobilityModelType', + 'std::string', + [], + is_const=True) ## mobility-helper.h: void ns3::MobilityHelper::Install(ns3::NodeContainer container) [member function] - cls.add_method('Install', 'void', [param('ns3::NodeContainer', 'container')]) + cls.add_method('Install', + 'void', + [param('ns3::NodeContainer', 'container')]) ## mobility-helper.h: void ns3::MobilityHelper::InstallAll() [member function] - cls.add_method('InstallAll', 'void', []) + cls.add_method('InstallAll', + 'void', + []) return def register_Ns3InternetStackHelper_methods(root_module, cls): ## internet-stack-helper.h: void ns3::InternetStackHelper::Install(ns3::NodeContainer c) [member function] - cls.add_method('Install', 'void', [param('ns3::NodeContainer', 'c')]) + cls.add_method('Install', + 'void', + [param('ns3::NodeContainer', 'c')]) ## internet-stack-helper.h: static void ns3::InternetStackHelper::EnablePcapAll(std::string filename) [member function] - cls.add_method('EnablePcapAll', 'void', [param('std::string', 'filename')], is_static=True) + cls.add_method('EnablePcapAll', + 'void', + [param('std::string', 'filename')], + is_static=True) cls.add_constructor([]) return def register_Ns3NodeContainer_methods(root_module, cls): ## node-container.h: ns3::NodeContainer::NodeContainer() [constructor] - cls.add_constructor([], visibility='public') + cls.add_constructor([]) ## node-container.h: ns3::NodeContainer::NodeContainer(ns3::Ptr node) [constructor] - cls.add_constructor([param('ns3::Ptr< ns3::Node >', 'node')], visibility='public') + cls.add_constructor([param('ns3::Ptr< ns3::Node >', 'node')]) ## node-container.h: ns3::NodeContainer::NodeContainer(ns3::NodeContainer const & a, ns3::NodeContainer const & b) [constructor] - cls.add_constructor([param('ns3::NodeContainer&', 'a', is_const=True), param('ns3::NodeContainer&', 'b', is_const=True)], visibility='public') + cls.add_constructor([param('ns3::NodeContainer&', 'a', is_const=True), param('ns3::NodeContainer&', 'b', is_const=True)]) ## node-container.h: ns3::NodeContainer::NodeContainer(ns3::NodeContainer const & a, ns3::NodeContainer const & b, ns3::NodeContainer const & c) [constructor] - cls.add_constructor([param('ns3::NodeContainer&', 'a', is_const=True), param('ns3::NodeContainer&', 'b', is_const=True), param('ns3::NodeContainer&', 'c', is_const=True)], visibility='public') + cls.add_constructor([param('ns3::NodeContainer&', 'a', is_const=True), param('ns3::NodeContainer&', 'b', is_const=True), param('ns3::NodeContainer&', 'c', is_const=True)]) ## node-container.h: ns3::NodeContainer::NodeContainer(ns3::NodeContainer const & a, ns3::NodeContainer const & b, ns3::NodeContainer const & c, ns3::NodeContainer const & d) [constructor] - cls.add_constructor([param('ns3::NodeContainer&', 'a', is_const=True), param('ns3::NodeContainer&', 'b', is_const=True), param('ns3::NodeContainer&', 'c', is_const=True), param('ns3::NodeContainer&', 'd', is_const=True)], visibility='public') + cls.add_constructor([param('ns3::NodeContainer&', 'a', is_const=True), param('ns3::NodeContainer&', 'b', is_const=True), param('ns3::NodeContainer&', 'c', is_const=True), param('ns3::NodeContainer&', 'd', is_const=True)]) ## node-container.h: __gnu_cxx::__normal_iterator*,std::vector, std::allocator > > > ns3::NodeContainer::Begin() const [member function] - cls.add_method('Begin', '__gnu_cxx::__normal_iterator< const ns3::Ptr< ns3::Node >, std::vector< ns3::Ptr< ns3::Node >, std::allocator< ns3::Ptr< ns3::Node > > > >', [], is_const=True) + cls.add_method('Begin', + '__gnu_cxx::__normal_iterator< const ns3::Ptr< ns3::Node >, std::vector< ns3::Ptr< ns3::Node >, std::allocator< ns3::Ptr< ns3::Node > > > >', + [], + is_const=True) ## node-container.h: __gnu_cxx::__normal_iterator*,std::vector, std::allocator > > > ns3::NodeContainer::End() const [member function] - cls.add_method('End', '__gnu_cxx::__normal_iterator< const ns3::Ptr< ns3::Node >, std::vector< ns3::Ptr< ns3::Node >, std::allocator< ns3::Ptr< ns3::Node > > > >', [], is_const=True) + cls.add_method('End', + '__gnu_cxx::__normal_iterator< const ns3::Ptr< ns3::Node >, std::vector< ns3::Ptr< ns3::Node >, std::allocator< ns3::Ptr< ns3::Node > > > >', + [], + is_const=True) ## node-container.h: uint32_t ns3::NodeContainer::GetN() const [member function] - cls.add_method('GetN', 'uint32_t', [], is_const=True) + cls.add_method('GetN', + 'uint32_t', + [], + is_const=True) ## node-container.h: ns3::Ptr ns3::NodeContainer::Get(uint32_t i) const [member function] - cls.add_method('Get', 'ns3::Ptr< ns3::Node >', [param('uint32_t', 'i')], is_const=True) + cls.add_method('Get', + 'ns3::Ptr< ns3::Node >', + [param('uint32_t', 'i')], + is_const=True) ## node-container.h: void ns3::NodeContainer::Create(uint32_t n) [member function] - cls.add_method('Create', 'void', [param('uint32_t', 'n')]) + cls.add_method('Create', + 'void', + [param('uint32_t', 'n')]) ## node-container.h: void ns3::NodeContainer::Add(ns3::NodeContainer other) [member function] - cls.add_method('Add', 'void', [param('ns3::NodeContainer', 'other')]) + cls.add_method('Add', + 'void', + [param('ns3::NodeContainer', 'other')]) ## node-container.h: void ns3::NodeContainer::Add(ns3::Ptr node) [member function] - cls.add_method('Add', 'void', [param('ns3::Ptr< ns3::Node >', 'node')]) + cls.add_method('Add', + 'void', + [param('ns3::Ptr< ns3::Node >', 'node')]) ## node-container.h: static ns3::NodeContainer ns3::NodeContainer::GetGlobal() [member function] - cls.add_method('GetGlobal', 'ns3::NodeContainer', [], is_static=True) + cls.add_method('GetGlobal', + 'ns3::NodeContainer', + [], + is_static=True) return def register_Ns3PointToPointHelper_methods(root_module, cls): ## point-to-point-helper.h: ns3::PointToPointHelper::PointToPointHelper() [constructor] - cls.add_constructor([], visibility='public') + cls.add_constructor([]) ## point-to-point-helper.h: void ns3::PointToPointHelper::SetQueue(std::string type, std::string n1="", ns3::AttributeValue const & v1=ns3::EmptyAttributeValue(), std::string n2="", ns3::AttributeValue const & v2=ns3::EmptyAttributeValue(), std::string n3="", ns3::AttributeValue const & v3=ns3::EmptyAttributeValue(), std::string n4="", ns3::AttributeValue const & v4=ns3::EmptyAttributeValue()) [member function] - cls.add_method('SetQueue', 'void', [param('std::string', 'type'), param('std::string', 'n1', default_value='""'), param('ns3::AttributeValue&', 'v1', default_value='ns3::EmptyAttributeValue()', is_const=True), param('std::string', 'n2', default_value='""'), param('ns3::AttributeValue&', 'v2', default_value='ns3::EmptyAttributeValue()', is_const=True), param('std::string', 'n3', default_value='""'), param('ns3::AttributeValue&', 'v3', default_value='ns3::EmptyAttributeValue()', is_const=True), param('std::string', 'n4', default_value='""'), param('ns3::AttributeValue&', 'v4', default_value='ns3::EmptyAttributeValue()', is_const=True)]) + cls.add_method('SetQueue', + 'void', + [param('std::string', 'type'), param('std::string', 'n1', default_value='""'), param('ns3::AttributeValue&', 'v1', default_value='ns3::EmptyAttributeValue()', is_const=True), param('std::string', 'n2', default_value='""'), param('ns3::AttributeValue&', 'v2', default_value='ns3::EmptyAttributeValue()', is_const=True), param('std::string', 'n3', default_value='""'), param('ns3::AttributeValue&', 'v3', default_value='ns3::EmptyAttributeValue()', is_const=True), param('std::string', 'n4', default_value='""'), param('ns3::AttributeValue&', 'v4', default_value='ns3::EmptyAttributeValue()', is_const=True)]) ## point-to-point-helper.h: void ns3::PointToPointHelper::SetDeviceAttribute(std::string name, ns3::AttributeValue const & value) [member function] - cls.add_method('SetDeviceAttribute', 'void', [param('std::string', 'name'), param('ns3::AttributeValue&', 'value', is_const=True)]) + cls.add_method('SetDeviceAttribute', + 'void', + [param('std::string', 'name'), param('ns3::AttributeValue&', 'value', is_const=True)]) ## point-to-point-helper.h: void ns3::PointToPointHelper::SetChannelAttribute(std::string name, ns3::AttributeValue const & value) [member function] - cls.add_method('SetChannelAttribute', 'void', [param('std::string', 'name'), param('ns3::AttributeValue&', 'value', is_const=True)]) + cls.add_method('SetChannelAttribute', + 'void', + [param('std::string', 'name'), param('ns3::AttributeValue&', 'value', is_const=True)]) ## point-to-point-helper.h: void ns3::PointToPointHelper::SetDeviceParameter(std::string name, ns3::AttributeValue const & value) [member function] - cls.add_method('SetDeviceParameter', 'void', [param('std::string', 'name'), param('ns3::AttributeValue&', 'value', is_const=True)]) + cls.add_method('SetDeviceParameter', + 'void', + [param('std::string', 'name'), param('ns3::AttributeValue&', 'value', is_const=True)], + deprecated=True) ## point-to-point-helper.h: void ns3::PointToPointHelper::SetChannelParameter(std::string name, ns3::AttributeValue const & value) [member function] - cls.add_method('SetChannelParameter', 'void', [param('std::string', 'name'), param('ns3::AttributeValue&', 'value', is_const=True)]) + cls.add_method('SetChannelParameter', + 'void', + [param('std::string', 'name'), param('ns3::AttributeValue&', 'value', is_const=True)], + deprecated=True) ## point-to-point-helper.h: static void ns3::PointToPointHelper::EnablePcap(std::string filename, uint32_t nodeid, uint32_t deviceid) [member function] - cls.add_method('EnablePcap', 'void', [param('std::string', 'filename'), param('uint32_t', 'nodeid'), param('uint32_t', 'deviceid')], is_static=True) + cls.add_method('EnablePcap', + 'void', + [param('std::string', 'filename'), param('uint32_t', 'nodeid'), param('uint32_t', 'deviceid')], + is_static=True) ## point-to-point-helper.h: static void ns3::PointToPointHelper::EnablePcap(std::string filename, ns3::NetDeviceContainer d) [member function] - cls.add_method('EnablePcap', 'void', [param('std::string', 'filename'), param('ns3::NetDeviceContainer', 'd')], is_static=True) + cls.add_method('EnablePcap', + 'void', + [param('std::string', 'filename'), param('ns3::NetDeviceContainer', 'd')], + is_static=True) ## point-to-point-helper.h: static void ns3::PointToPointHelper::EnablePcap(std::string filename, ns3::NodeContainer n) [member function] - cls.add_method('EnablePcap', 'void', [param('std::string', 'filename'), param('ns3::NodeContainer', 'n')], is_static=True) + cls.add_method('EnablePcap', + 'void', + [param('std::string', 'filename'), param('ns3::NodeContainer', 'n')], + is_static=True) ## point-to-point-helper.h: static void ns3::PointToPointHelper::EnablePcapAll(std::string filename) [member function] - cls.add_method('EnablePcapAll', 'void', [param('std::string', 'filename')], is_static=True) + cls.add_method('EnablePcapAll', + 'void', + [param('std::string', 'filename')], + is_static=True) ## point-to-point-helper.h: static void ns3::PointToPointHelper::EnableAscii(std::ostream & os, uint32_t nodeid, uint32_t deviceid) [member function] - cls.add_method('EnableAscii', 'void', [param('std::ostream&', 'os'), param('uint32_t', 'nodeid'), param('uint32_t', 'deviceid')], is_static=True) + cls.add_method('EnableAscii', + 'void', + [param('std::ostream&', 'os'), param('uint32_t', 'nodeid'), param('uint32_t', 'deviceid')], + is_static=True) ## point-to-point-helper.h: static void ns3::PointToPointHelper::EnableAscii(std::ostream & os, ns3::NetDeviceContainer d) [member function] - cls.add_method('EnableAscii', 'void', [param('std::ostream&', 'os'), param('ns3::NetDeviceContainer', 'd')], is_static=True) + cls.add_method('EnableAscii', + 'void', + [param('std::ostream&', 'os'), param('ns3::NetDeviceContainer', 'd')], + is_static=True) ## point-to-point-helper.h: static void ns3::PointToPointHelper::EnableAscii(std::ostream & os, ns3::NodeContainer n) [member function] - cls.add_method('EnableAscii', 'void', [param('std::ostream&', 'os'), param('ns3::NodeContainer', 'n')], is_static=True) + cls.add_method('EnableAscii', + 'void', + [param('std::ostream&', 'os'), param('ns3::NodeContainer', 'n')], + is_static=True) ## point-to-point-helper.h: static void ns3::PointToPointHelper::EnableAsciiAll(std::ostream & os) [member function] - cls.add_method('EnableAsciiAll', 'void', [param('std::ostream&', 'os')], is_static=True) + cls.add_method('EnableAsciiAll', + 'void', + [param('std::ostream&', 'os')], + is_static=True) ## point-to-point-helper.h: ns3::NetDeviceContainer ns3::PointToPointHelper::Install(ns3::NodeContainer c) [member function] - cls.add_method('Install', 'ns3::NetDeviceContainer', [param('ns3::NodeContainer', 'c')]) + cls.add_method('Install', + 'ns3::NetDeviceContainer', + [param('ns3::NodeContainer', 'c')]) ## point-to-point-helper.h: ns3::NetDeviceContainer ns3::PointToPointHelper::Install(ns3::Ptr a, ns3::Ptr b) [member function] - cls.add_method('Install', 'ns3::NetDeviceContainer', [param('ns3::Ptr< ns3::Node >', 'a'), param('ns3::Ptr< ns3::Node >', 'b')]) + cls.add_method('Install', + 'ns3::NetDeviceContainer', + [param('ns3::Ptr< ns3::Node >', 'a'), param('ns3::Ptr< ns3::Node >', 'b')]) return def register_Ns3NetDeviceContainer_methods(root_module, cls): ## net-device-container.h: __gnu_cxx::__normal_iterator*,std::vector, std::allocator > > > ns3::NetDeviceContainer::Begin() const [member function] - cls.add_method('Begin', '__gnu_cxx::__normal_iterator< const ns3::Ptr< ns3::NetDevice >, std::vector< ns3::Ptr< ns3::NetDevice >, std::allocator< ns3::Ptr< ns3::NetDevice > > > >', [], is_const=True) + cls.add_method('Begin', + '__gnu_cxx::__normal_iterator< const ns3::Ptr< ns3::NetDevice >, std::vector< ns3::Ptr< ns3::NetDevice >, std::allocator< ns3::Ptr< ns3::NetDevice > > > >', + [], + is_const=True) ## net-device-container.h: __gnu_cxx::__normal_iterator*,std::vector, std::allocator > > > ns3::NetDeviceContainer::End() const [member function] - cls.add_method('End', '__gnu_cxx::__normal_iterator< const ns3::Ptr< ns3::NetDevice >, std::vector< ns3::Ptr< ns3::NetDevice >, std::allocator< ns3::Ptr< ns3::NetDevice > > > >', [], is_const=True) + cls.add_method('End', + '__gnu_cxx::__normal_iterator< const ns3::Ptr< ns3::NetDevice >, std::vector< ns3::Ptr< ns3::NetDevice >, std::allocator< ns3::Ptr< ns3::NetDevice > > > >', + [], + is_const=True) ## net-device-container.h: uint32_t ns3::NetDeviceContainer::GetN() const [member function] - cls.add_method('GetN', 'uint32_t', [], is_const=True) + cls.add_method('GetN', + 'uint32_t', + [], + is_const=True) ## net-device-container.h: ns3::Ptr ns3::NetDeviceContainer::Get(uint32_t i) const [member function] - cls.add_method('Get', 'ns3::Ptr< ns3::NetDevice >', [param('uint32_t', 'i')], is_const=True) + cls.add_method('Get', + 'ns3::Ptr< ns3::NetDevice >', + [param('uint32_t', 'i')], + is_const=True) ## net-device-container.h: void ns3::NetDeviceContainer::Add(ns3::NetDeviceContainer other) [member function] - cls.add_method('Add', 'void', [param('ns3::NetDeviceContainer', 'other')]) + cls.add_method('Add', + 'void', + [param('ns3::NetDeviceContainer', 'other')]) ## net-device-container.h: void ns3::NetDeviceContainer::Add(ns3::Ptr device) [member function] - cls.add_method('Add', 'void', [param('ns3::Ptr< ns3::NetDevice >', 'device')]) + cls.add_method('Add', + 'void', + [param('ns3::Ptr< ns3::NetDevice >', 'device')]) cls.add_constructor([]) return def register_Ns3CsmaHelper_methods(root_module, cls): ## csma-helper.h: ns3::CsmaHelper::CsmaHelper() [constructor] - cls.add_constructor([], visibility='public') + cls.add_constructor([]) ## csma-helper.h: void ns3::CsmaHelper::SetQueue(std::string type, std::string n1="", ns3::AttributeValue const & v1=ns3::EmptyAttributeValue(), std::string n2="", ns3::AttributeValue const & v2=ns3::EmptyAttributeValue(), std::string n3="", ns3::AttributeValue const & v3=ns3::EmptyAttributeValue(), std::string n4="", ns3::AttributeValue const & v4=ns3::EmptyAttributeValue()) [member function] - cls.add_method('SetQueue', 'void', [param('std::string', 'type'), param('std::string', 'n1', default_value='""'), param('ns3::AttributeValue&', 'v1', default_value='ns3::EmptyAttributeValue()', is_const=True), param('std::string', 'n2', default_value='""'), param('ns3::AttributeValue&', 'v2', default_value='ns3::EmptyAttributeValue()', is_const=True), param('std::string', 'n3', default_value='""'), param('ns3::AttributeValue&', 'v3', default_value='ns3::EmptyAttributeValue()', is_const=True), param('std::string', 'n4', default_value='""'), param('ns3::AttributeValue&', 'v4', default_value='ns3::EmptyAttributeValue()', is_const=True)]) + cls.add_method('SetQueue', + 'void', + [param('std::string', 'type'), param('std::string', 'n1', default_value='""'), param('ns3::AttributeValue&', 'v1', default_value='ns3::EmptyAttributeValue()', is_const=True), param('std::string', 'n2', default_value='""'), param('ns3::AttributeValue&', 'v2', default_value='ns3::EmptyAttributeValue()', is_const=True), param('std::string', 'n3', default_value='""'), param('ns3::AttributeValue&', 'v3', default_value='ns3::EmptyAttributeValue()', is_const=True), param('std::string', 'n4', default_value='""'), param('ns3::AttributeValue&', 'v4', default_value='ns3::EmptyAttributeValue()', is_const=True)]) ## csma-helper.h: void ns3::CsmaHelper::SetDeviceAttribute(std::string n1, ns3::AttributeValue const & v1) [member function] - cls.add_method('SetDeviceAttribute', 'void', [param('std::string', 'n1'), param('ns3::AttributeValue&', 'v1', is_const=True)]) + cls.add_method('SetDeviceAttribute', + 'void', + [param('std::string', 'n1'), param('ns3::AttributeValue&', 'v1', is_const=True)]) ## csma-helper.h: void ns3::CsmaHelper::SetChannelAttribute(std::string n1, ns3::AttributeValue const & v1) [member function] - cls.add_method('SetChannelAttribute', 'void', [param('std::string', 'n1'), param('ns3::AttributeValue&', 'v1', is_const=True)]) + cls.add_method('SetChannelAttribute', + 'void', + [param('std::string', 'n1'), param('ns3::AttributeValue&', 'v1', is_const=True)]) ## csma-helper.h: void ns3::CsmaHelper::SetDeviceParameter(std::string n1, ns3::AttributeValue const & v1) [member function] - cls.add_method('SetDeviceParameter', 'void', [param('std::string', 'n1'), param('ns3::AttributeValue&', 'v1', is_const=True)]) + cls.add_method('SetDeviceParameter', + 'void', + [param('std::string', 'n1'), param('ns3::AttributeValue&', 'v1', is_const=True)], + deprecated=True) ## csma-helper.h: void ns3::CsmaHelper::SetChannelParameter(std::string n1, ns3::AttributeValue const & v1) [member function] - cls.add_method('SetChannelParameter', 'void', [param('std::string', 'n1'), param('ns3::AttributeValue&', 'v1', is_const=True)]) + cls.add_method('SetChannelParameter', + 'void', + [param('std::string', 'n1'), param('ns3::AttributeValue&', 'v1', is_const=True)], + deprecated=True) ## csma-helper.h: static void ns3::CsmaHelper::EnablePcap(std::string filename, uint32_t nodeid, uint32_t deviceid) [member function] - cls.add_method('EnablePcap', 'void', [param('std::string', 'filename'), param('uint32_t', 'nodeid'), param('uint32_t', 'deviceid')], is_static=True) + cls.add_method('EnablePcap', + 'void', + [param('std::string', 'filename'), param('uint32_t', 'nodeid'), param('uint32_t', 'deviceid')], + is_static=True) ## csma-helper.h: static void ns3::CsmaHelper::EnablePcap(std::string filename, ns3::NetDeviceContainer d) [member function] - cls.add_method('EnablePcap', 'void', [param('std::string', 'filename'), param('ns3::NetDeviceContainer', 'd')], is_static=True) + cls.add_method('EnablePcap', + 'void', + [param('std::string', 'filename'), param('ns3::NetDeviceContainer', 'd')], + is_static=True) ## csma-helper.h: static void ns3::CsmaHelper::EnablePcap(std::string filename, ns3::NodeContainer n) [member function] - cls.add_method('EnablePcap', 'void', [param('std::string', 'filename'), param('ns3::NodeContainer', 'n')], is_static=True) + cls.add_method('EnablePcap', + 'void', + [param('std::string', 'filename'), param('ns3::NodeContainer', 'n')], + is_static=True) ## csma-helper.h: static void ns3::CsmaHelper::EnablePcapAll(std::string filename) [member function] - cls.add_method('EnablePcapAll', 'void', [param('std::string', 'filename')], is_static=True) + cls.add_method('EnablePcapAll', + 'void', + [param('std::string', 'filename')], + is_static=True) ## csma-helper.h: static void ns3::CsmaHelper::EnableAscii(std::ostream & os, uint32_t nodeid, uint32_t deviceid) [member function] - cls.add_method('EnableAscii', 'void', [param('std::ostream&', 'os'), param('uint32_t', 'nodeid'), param('uint32_t', 'deviceid')], is_static=True) + cls.add_method('EnableAscii', + 'void', + [param('std::ostream&', 'os'), param('uint32_t', 'nodeid'), param('uint32_t', 'deviceid')], + is_static=True) ## csma-helper.h: static void ns3::CsmaHelper::EnableAscii(std::ostream & os, ns3::NetDeviceContainer d) [member function] - cls.add_method('EnableAscii', 'void', [param('std::ostream&', 'os'), param('ns3::NetDeviceContainer', 'd')], is_static=True) + cls.add_method('EnableAscii', + 'void', + [param('std::ostream&', 'os'), param('ns3::NetDeviceContainer', 'd')], + is_static=True) ## csma-helper.h: static void ns3::CsmaHelper::EnableAscii(std::ostream & os, ns3::NodeContainer n) [member function] - cls.add_method('EnableAscii', 'void', [param('std::ostream&', 'os'), param('ns3::NodeContainer', 'n')], is_static=True) + cls.add_method('EnableAscii', + 'void', + [param('std::ostream&', 'os'), param('ns3::NodeContainer', 'n')], + is_static=True) ## csma-helper.h: static void ns3::CsmaHelper::EnableAsciiAll(std::ostream & os) [member function] - cls.add_method('EnableAsciiAll', 'void', [param('std::ostream&', 'os')], is_static=True) + cls.add_method('EnableAsciiAll', + 'void', + [param('std::ostream&', 'os')], + is_static=True) ## csma-helper.h: ns3::NetDeviceContainer ns3::CsmaHelper::Install(ns3::NodeContainer const & c) [member function] - cls.add_method('Install', 'ns3::NetDeviceContainer', [param('ns3::NodeContainer&', 'c', is_const=True)]) + cls.add_method('Install', + 'ns3::NetDeviceContainer', + [param('ns3::NodeContainer&', 'c', is_const=True)]) ## csma-helper.h: ns3::NetDeviceContainer ns3::CsmaHelper::Install(ns3::NodeContainer const & c, ns3::Ptr channel) [member function] - cls.add_method('Install', 'ns3::NetDeviceContainer', [param('ns3::NodeContainer&', 'c', is_const=True), param('ns3::Ptr< ns3::CsmaChannel >', 'channel')]) + cls.add_method('Install', + 'ns3::NetDeviceContainer', + [param('ns3::NodeContainer&', 'c', is_const=True), param('ns3::Ptr< ns3::CsmaChannel >', 'channel')]) return def register_Ns3UdpEchoServerHelper_methods(root_module, cls): ## udp-echo-helper.h: ns3::UdpEchoServerHelper::UdpEchoServerHelper(uint16_t port) [constructor] - cls.add_constructor([param('uint16_t', 'port')], visibility='public') + cls.add_constructor([param('uint16_t', 'port')]) ## udp-echo-helper.h: void ns3::UdpEchoServerHelper::SetAttribute(std::string name, ns3::AttributeValue const & value) [member function] - cls.add_method('SetAttribute', 'void', [param('std::string', 'name'), param('ns3::AttributeValue&', 'value', is_const=True)]) + cls.add_method('SetAttribute', + 'void', + [param('std::string', 'name'), param('ns3::AttributeValue&', 'value', is_const=True)]) ## udp-echo-helper.h: ns3::ApplicationContainer ns3::UdpEchoServerHelper::Install(ns3::NodeContainer c) [member function] - cls.add_method('Install', 'ns3::ApplicationContainer', [param('ns3::NodeContainer', 'c')]) + cls.add_method('Install', + 'ns3::ApplicationContainer', + [param('ns3::NodeContainer', 'c')]) return def register_Ns3OlsrHelper_methods(root_module, cls): ## olsr-helper.h: ns3::OlsrHelper::OlsrHelper() [constructor] - cls.add_constructor([], visibility='public') + cls.add_constructor([]) ## olsr-helper.h: void ns3::OlsrHelper::SetAgent(std::string tid, std::string n0="", ns3::AttributeValue const & v0=ns3::EmptyAttributeValue(), std::string n1="", ns3::AttributeValue const & v1=ns3::EmptyAttributeValue(), std::string n2="", ns3::AttributeValue const & v2=ns3::EmptyAttributeValue(), std::string n3="", ns3::AttributeValue const & v3=ns3::EmptyAttributeValue(), std::string n4="", ns3::AttributeValue const & v4=ns3::EmptyAttributeValue(), std::string n5="", ns3::AttributeValue const & v5=ns3::EmptyAttributeValue(), std::string n6="", ns3::AttributeValue const & v6=ns3::EmptyAttributeValue(), std::string n7="", ns3::AttributeValue const & v7=ns3::EmptyAttributeValue()) [member function] - cls.add_method('SetAgent', 'void', [param('std::string', 'tid'), param('std::string', 'n0', default_value='""'), param('ns3::AttributeValue&', 'v0', default_value='ns3::EmptyAttributeValue()', is_const=True), param('std::string', 'n1', default_value='""'), param('ns3::AttributeValue&', 'v1', default_value='ns3::EmptyAttributeValue()', is_const=True), param('std::string', 'n2', default_value='""'), param('ns3::AttributeValue&', 'v2', default_value='ns3::EmptyAttributeValue()', is_const=True), param('std::string', 'n3', default_value='""'), param('ns3::AttributeValue&', 'v3', default_value='ns3::EmptyAttributeValue()', is_const=True), param('std::string', 'n4', default_value='""'), param('ns3::AttributeValue&', 'v4', default_value='ns3::EmptyAttributeValue()', is_const=True), param('std::string', 'n5', default_value='""'), param('ns3::AttributeValue&', 'v5', default_value='ns3::EmptyAttributeValue()', is_const=True), param('std::string', 'n6', default_value='""'), param('ns3::AttributeValue&', 'v6', default_value='ns3::EmptyAttributeValue()', is_const=True), param('std::string', 'n7', default_value='""'), param('ns3::AttributeValue&', 'v7', default_value='ns3::EmptyAttributeValue()', is_const=True)]) + cls.add_method('SetAgent', + 'void', + [param('std::string', 'tid'), param('std::string', 'n0', default_value='""'), param('ns3::AttributeValue&', 'v0', default_value='ns3::EmptyAttributeValue()', is_const=True), param('std::string', 'n1', default_value='""'), param('ns3::AttributeValue&', 'v1', default_value='ns3::EmptyAttributeValue()', is_const=True), param('std::string', 'n2', default_value='""'), param('ns3::AttributeValue&', 'v2', default_value='ns3::EmptyAttributeValue()', is_const=True), param('std::string', 'n3', default_value='""'), param('ns3::AttributeValue&', 'v3', default_value='ns3::EmptyAttributeValue()', is_const=True), param('std::string', 'n4', default_value='""'), param('ns3::AttributeValue&', 'v4', default_value='ns3::EmptyAttributeValue()', is_const=True), param('std::string', 'n5', default_value='""'), param('ns3::AttributeValue&', 'v5', default_value='ns3::EmptyAttributeValue()', is_const=True), param('std::string', 'n6', default_value='""'), param('ns3::AttributeValue&', 'v6', default_value='ns3::EmptyAttributeValue()', is_const=True), param('std::string', 'n7', default_value='""'), param('ns3::AttributeValue&', 'v7', default_value='ns3::EmptyAttributeValue()', is_const=True)]) ## olsr-helper.h: void ns3::OlsrHelper::Install(ns3::NodeContainer container) [member function] - cls.add_method('Install', 'void', [param('ns3::NodeContainer', 'container')]) + cls.add_method('Install', + 'void', + [param('ns3::NodeContainer', 'container')]) ## olsr-helper.h: void ns3::OlsrHelper::Install(ns3::Ptr node) [member function] - cls.add_method('Install', 'void', [param('ns3::Ptr< ns3::Node >', 'node')]) + cls.add_method('Install', + 'void', + [param('ns3::Ptr< ns3::Node >', 'node')]) ## olsr-helper.h: void ns3::OlsrHelper::InstallAll() [member function] - cls.add_method('InstallAll', 'void', []) + cls.add_method('InstallAll', + 'void', + []) return def register_Ns3PacketSocketHelper_methods(root_module, cls): ## packet-socket-helper.h: void ns3::PacketSocketHelper::Install(ns3::NodeContainer c) [member function] - cls.add_method('Install', 'void', [param('ns3::NodeContainer', 'c')]) + cls.add_method('Install', + 'void', + [param('ns3::NodeContainer', 'c')]) cls.add_constructor([]) return def register_Ns3OnOffHelper_methods(root_module, cls): ## on-off-helper.h: ns3::OnOffHelper::OnOffHelper(std::string protocol, ns3::Address address) [constructor] - cls.add_constructor([param('std::string', 'protocol'), param('ns3::Address', 'address')], visibility='public') + cls.add_constructor([param('std::string', 'protocol'), param('ns3::Address', 'address')]) ## on-off-helper.h: void ns3::OnOffHelper::SetAttribute(std::string name, ns3::AttributeValue const & value) [member function] - cls.add_method('SetAttribute', 'void', [param('std::string', 'name'), param('ns3::AttributeValue&', 'value', is_const=True)]) + cls.add_method('SetAttribute', + 'void', + [param('std::string', 'name'), param('ns3::AttributeValue&', 'value', is_const=True)]) ## on-off-helper.h: ns3::ApplicationContainer ns3::OnOffHelper::Install(ns3::NodeContainer c) [member function] - cls.add_method('Install', 'ns3::ApplicationContainer', [param('ns3::NodeContainer', 'c')]) + cls.add_method('Install', + 'ns3::ApplicationContainer', + [param('ns3::NodeContainer', 'c')]) return def register_Ns3UdpEchoClientHelper_methods(root_module, cls): ## udp-echo-helper.h: ns3::UdpEchoClientHelper::UdpEchoClientHelper(ns3::Ipv4Address ip, uint16_t port) [constructor] - cls.add_constructor([param('ns3::Ipv4Address', 'ip'), param('uint16_t', 'port')], visibility='public') + cls.add_constructor([param('ns3::Ipv4Address', 'ip'), param('uint16_t', 'port')]) ## udp-echo-helper.h: void ns3::UdpEchoClientHelper::SetAttribute(std::string name, ns3::AttributeValue const & value) [member function] - cls.add_method('SetAttribute', 'void', [param('std::string', 'name'), param('ns3::AttributeValue&', 'value', is_const=True)]) + cls.add_method('SetAttribute', + 'void', + [param('std::string', 'name'), param('ns3::AttributeValue&', 'value', is_const=True)]) ## udp-echo-helper.h: ns3::ApplicationContainer ns3::UdpEchoClientHelper::Install(ns3::NodeContainer c) [member function] - cls.add_method('Install', 'ns3::ApplicationContainer', [param('ns3::NodeContainer', 'c')]) + cls.add_method('Install', + 'ns3::ApplicationContainer', + [param('ns3::NodeContainer', 'c')]) return def register_Ns3StaticMulticastRouteHelper_methods(root_module, cls): ## static-multicast-route-helper.h: ns3::StaticMulticastRouteHelper::StaticMulticastRouteHelper() [constructor] - cls.add_constructor([], visibility='public') + cls.add_constructor([]) ## static-multicast-route-helper.h: void ns3::StaticMulticastRouteHelper::AddMulticastRoute(ns3::Ptr arg0, ns3::Ipv4Address source, ns3::Ipv4Address group, ns3::Ptr input, ns3::NetDeviceContainer output) [member function] - cls.add_method('AddMulticastRoute', 'void', [param('ns3::Ptr< ns3::Node >', 'arg0'), param('ns3::Ipv4Address', 'source'), param('ns3::Ipv4Address', 'group'), param('ns3::Ptr< ns3::NetDevice >', 'input'), param('ns3::NetDeviceContainer', 'output')]) + cls.add_method('AddMulticastRoute', + 'void', + [param('ns3::Ptr< ns3::Node >', 'arg0'), param('ns3::Ipv4Address', 'source'), param('ns3::Ipv4Address', 'group'), param('ns3::Ptr< ns3::NetDevice >', 'input'), param('ns3::NetDeviceContainer', 'output')]) ## static-multicast-route-helper.h: void ns3::StaticMulticastRouteHelper::SetDefaultMulticastRoute(ns3::Ptr n, ns3::Ptr nd) [member function] - cls.add_method('SetDefaultMulticastRoute', 'void', [param('ns3::Ptr< ns3::Node >', 'n'), param('ns3::Ptr< ns3::NetDevice >', 'nd')]) + cls.add_method('SetDefaultMulticastRoute', + 'void', + [param('ns3::Ptr< ns3::Node >', 'n'), param('ns3::Ptr< ns3::NetDevice >', 'nd')]) ## static-multicast-route-helper.h: void ns3::StaticMulticastRouteHelper::JoinMulticastGroup(ns3::Ptr n, ns3::Ipv4Address source, ns3::Ipv4Address group) [member function] - cls.add_method('JoinMulticastGroup', 'void', [param('ns3::Ptr< ns3::Node >', 'n'), param('ns3::Ipv4Address', 'source'), param('ns3::Ipv4Address', 'group')]) + cls.add_method('JoinMulticastGroup', + 'void', + [param('ns3::Ptr< ns3::Node >', 'n'), param('ns3::Ipv4Address', 'source'), param('ns3::Ipv4Address', 'group')]) return def register_Ns3Ipv4InterfaceContainer_methods(root_module, cls): ## ipv4-interface-container.h: ns3::Ipv4InterfaceContainer::Ipv4InterfaceContainer() [constructor] - cls.add_constructor([], visibility='public') + cls.add_constructor([]) ## ipv4-interface-container.h: uint32_t ns3::Ipv4InterfaceContainer::GetN() const [member function] - cls.add_method('GetN', 'uint32_t', [], is_const=True) + cls.add_method('GetN', + 'uint32_t', + [], + is_const=True) ## ipv4-interface-container.h: ns3::Ipv4Address ns3::Ipv4InterfaceContainer::GetAddress(uint32_t i) const [member function] - cls.add_method('GetAddress', 'ns3::Ipv4Address', [param('uint32_t', 'i')], is_const=True) + cls.add_method('GetAddress', + 'ns3::Ipv4Address', + [param('uint32_t', 'i')], + is_const=True) ## ipv4-interface-container.h: void ns3::Ipv4InterfaceContainer::SetMetric(uint32_t i, uint16_t metric) [member function] - cls.add_method('SetMetric', 'void', [param('uint32_t', 'i'), param('uint16_t', 'metric')]) + cls.add_method('SetMetric', + 'void', + [param('uint32_t', 'i'), param('uint16_t', 'metric')]) ## ipv4-interface-container.h: void ns3::Ipv4InterfaceContainer::Add(ns3::Ptr ipv4, uint32_t interface) [member function] - cls.add_method('Add', 'void', [param('ns3::Ptr< ns3::Ipv4 >', 'ipv4'), param('uint32_t', 'interface')]) + cls.add_method('Add', + 'void', + [param('ns3::Ptr< ns3::Ipv4 >', 'ipv4'), param('uint32_t', 'interface')]) return def register_Ns3ApplicationContainer_methods(root_module, cls): ## application-container.h: __gnu_cxx::__normal_iterator*,std::vector, std::allocator > > > ns3::ApplicationContainer::Begin() const [member function] - cls.add_method('Begin', '__gnu_cxx::__normal_iterator< const ns3::Ptr< ns3::Application >, std::vector< ns3::Ptr< ns3::Application >, std::allocator< ns3::Ptr< ns3::Application > > > >', [], is_const=True) + cls.add_method('Begin', + '__gnu_cxx::__normal_iterator< const ns3::Ptr< ns3::Application >, std::vector< ns3::Ptr< ns3::Application >, std::allocator< ns3::Ptr< ns3::Application > > > >', + [], + is_const=True) ## application-container.h: __gnu_cxx::__normal_iterator*,std::vector, std::allocator > > > ns3::ApplicationContainer::End() const [member function] - cls.add_method('End', '__gnu_cxx::__normal_iterator< const ns3::Ptr< ns3::Application >, std::vector< ns3::Ptr< ns3::Application >, std::allocator< ns3::Ptr< ns3::Application > > > >', [], is_const=True) + cls.add_method('End', + '__gnu_cxx::__normal_iterator< const ns3::Ptr< ns3::Application >, std::vector< ns3::Ptr< ns3::Application >, std::allocator< ns3::Ptr< ns3::Application > > > >', + [], + is_const=True) ## application-container.h: uint32_t ns3::ApplicationContainer::GetN() const [member function] - cls.add_method('GetN', 'uint32_t', [], is_const=True) + cls.add_method('GetN', + 'uint32_t', + [], + is_const=True) ## application-container.h: ns3::Ptr ns3::ApplicationContainer::Get(uint32_t i) const [member function] - cls.add_method('Get', 'ns3::Ptr< ns3::Application >', [param('uint32_t', 'i')], is_const=True) + cls.add_method('Get', + 'ns3::Ptr< ns3::Application >', + [param('uint32_t', 'i')], + is_const=True) ## application-container.h: void ns3::ApplicationContainer::Add(ns3::ApplicationContainer other) [member function] - cls.add_method('Add', 'void', [param('ns3::ApplicationContainer', 'other')]) + cls.add_method('Add', + 'void', + [param('ns3::ApplicationContainer', 'other')]) ## application-container.h: void ns3::ApplicationContainer::Add(ns3::Ptr application) [member function] - cls.add_method('Add', 'void', [param('ns3::Ptr< ns3::Application >', 'application')]) + cls.add_method('Add', + 'void', + [param('ns3::Ptr< ns3::Application >', 'application')]) ## application-container.h: void ns3::ApplicationContainer::Start(ns3::Time start) [member function] - cls.add_method('Start', 'void', [param('ns3::Time', 'start')]) + cls.add_method('Start', + 'void', + [param('ns3::Time', 'start')]) ## application-container.h: void ns3::ApplicationContainer::Stop(ns3::Time stop) [member function] - cls.add_method('Stop', 'void', [param('ns3::Time', 'stop')]) + cls.add_method('Stop', + 'void', + [param('ns3::Time', 'stop')]) cls.add_constructor([]) return def register_Ns3WifiHelper_methods(root_module, cls): ## wifi-helper.h: ns3::WifiHelper::WifiHelper() [constructor] - cls.add_constructor([], visibility='public') + cls.add_constructor([]) ## wifi-helper.h: void ns3::WifiHelper::SetRemoteStationManager(std::string type, std::string n0="", ns3::AttributeValue const & v0=ns3::EmptyAttributeValue(), std::string n1="", ns3::AttributeValue const & v1=ns3::EmptyAttributeValue(), std::string n2="", ns3::AttributeValue const & v2=ns3::EmptyAttributeValue(), std::string n3="", ns3::AttributeValue const & v3=ns3::EmptyAttributeValue(), std::string n4="", ns3::AttributeValue const & v4=ns3::EmptyAttributeValue(), std::string n5="", ns3::AttributeValue const & v5=ns3::EmptyAttributeValue(), std::string n6="", ns3::AttributeValue const & v6=ns3::EmptyAttributeValue(), std::string n7="", ns3::AttributeValue const & v7=ns3::EmptyAttributeValue()) [member function] - cls.add_method('SetRemoteStationManager', 'void', [param('std::string', 'type'), param('std::string', 'n0', default_value='""'), param('ns3::AttributeValue&', 'v0', default_value='ns3::EmptyAttributeValue()', is_const=True), param('std::string', 'n1', default_value='""'), param('ns3::AttributeValue&', 'v1', default_value='ns3::EmptyAttributeValue()', is_const=True), param('std::string', 'n2', default_value='""'), param('ns3::AttributeValue&', 'v2', default_value='ns3::EmptyAttributeValue()', is_const=True), param('std::string', 'n3', default_value='""'), param('ns3::AttributeValue&', 'v3', default_value='ns3::EmptyAttributeValue()', is_const=True), param('std::string', 'n4', default_value='""'), param('ns3::AttributeValue&', 'v4', default_value='ns3::EmptyAttributeValue()', is_const=True), param('std::string', 'n5', default_value='""'), param('ns3::AttributeValue&', 'v5', default_value='ns3::EmptyAttributeValue()', is_const=True), param('std::string', 'n6', default_value='""'), param('ns3::AttributeValue&', 'v6', default_value='ns3::EmptyAttributeValue()', is_const=True), param('std::string', 'n7', default_value='""'), param('ns3::AttributeValue&', 'v7', default_value='ns3::EmptyAttributeValue()', is_const=True)]) + cls.add_method('SetRemoteStationManager', + 'void', + [param('std::string', 'type'), param('std::string', 'n0', default_value='""'), param('ns3::AttributeValue&', 'v0', default_value='ns3::EmptyAttributeValue()', is_const=True), param('std::string', 'n1', default_value='""'), param('ns3::AttributeValue&', 'v1', default_value='ns3::EmptyAttributeValue()', is_const=True), param('std::string', 'n2', default_value='""'), param('ns3::AttributeValue&', 'v2', default_value='ns3::EmptyAttributeValue()', is_const=True), param('std::string', 'n3', default_value='""'), param('ns3::AttributeValue&', 'v3', default_value='ns3::EmptyAttributeValue()', is_const=True), param('std::string', 'n4', default_value='""'), param('ns3::AttributeValue&', 'v4', default_value='ns3::EmptyAttributeValue()', is_const=True), param('std::string', 'n5', default_value='""'), param('ns3::AttributeValue&', 'v5', default_value='ns3::EmptyAttributeValue()', is_const=True), param('std::string', 'n6', default_value='""'), param('ns3::AttributeValue&', 'v6', default_value='ns3::EmptyAttributeValue()', is_const=True), param('std::string', 'n7', default_value='""'), param('ns3::AttributeValue&', 'v7', default_value='ns3::EmptyAttributeValue()', is_const=True)]) ## wifi-helper.h: void ns3::WifiHelper::SetMac(std::string type, std::string n0="", ns3::AttributeValue const & v0=ns3::EmptyAttributeValue(), std::string n1="", ns3::AttributeValue const & v1=ns3::EmptyAttributeValue(), std::string n2="", ns3::AttributeValue const & v2=ns3::EmptyAttributeValue(), std::string n3="", ns3::AttributeValue const & v3=ns3::EmptyAttributeValue(), std::string n4="", ns3::AttributeValue const & v4=ns3::EmptyAttributeValue(), std::string n5="", ns3::AttributeValue const & v5=ns3::EmptyAttributeValue(), std::string n6="", ns3::AttributeValue const & v6=ns3::EmptyAttributeValue(), std::string n7="", ns3::AttributeValue const & v7=ns3::EmptyAttributeValue()) [member function] - cls.add_method('SetMac', 'void', [param('std::string', 'type'), param('std::string', 'n0', default_value='""'), param('ns3::AttributeValue&', 'v0', default_value='ns3::EmptyAttributeValue()', is_const=True), param('std::string', 'n1', default_value='""'), param('ns3::AttributeValue&', 'v1', default_value='ns3::EmptyAttributeValue()', is_const=True), param('std::string', 'n2', default_value='""'), param('ns3::AttributeValue&', 'v2', default_value='ns3::EmptyAttributeValue()', is_const=True), param('std::string', 'n3', default_value='""'), param('ns3::AttributeValue&', 'v3', default_value='ns3::EmptyAttributeValue()', is_const=True), param('std::string', 'n4', default_value='""'), param('ns3::AttributeValue&', 'v4', default_value='ns3::EmptyAttributeValue()', is_const=True), param('std::string', 'n5', default_value='""'), param('ns3::AttributeValue&', 'v5', default_value='ns3::EmptyAttributeValue()', is_const=True), param('std::string', 'n6', default_value='""'), param('ns3::AttributeValue&', 'v6', default_value='ns3::EmptyAttributeValue()', is_const=True), param('std::string', 'n7', default_value='""'), param('ns3::AttributeValue&', 'v7', default_value='ns3::EmptyAttributeValue()', is_const=True)]) + cls.add_method('SetMac', + 'void', + [param('std::string', 'type'), param('std::string', 'n0', default_value='""'), param('ns3::AttributeValue&', 'v0', default_value='ns3::EmptyAttributeValue()', is_const=True), param('std::string', 'n1', default_value='""'), param('ns3::AttributeValue&', 'v1', default_value='ns3::EmptyAttributeValue()', is_const=True), param('std::string', 'n2', default_value='""'), param('ns3::AttributeValue&', 'v2', default_value='ns3::EmptyAttributeValue()', is_const=True), param('std::string', 'n3', default_value='""'), param('ns3::AttributeValue&', 'v3', default_value='ns3::EmptyAttributeValue()', is_const=True), param('std::string', 'n4', default_value='""'), param('ns3::AttributeValue&', 'v4', default_value='ns3::EmptyAttributeValue()', is_const=True), param('std::string', 'n5', default_value='""'), param('ns3::AttributeValue&', 'v5', default_value='ns3::EmptyAttributeValue()', is_const=True), param('std::string', 'n6', default_value='""'), param('ns3::AttributeValue&', 'v6', default_value='ns3::EmptyAttributeValue()', is_const=True), param('std::string', 'n7', default_value='""'), param('ns3::AttributeValue&', 'v7', default_value='ns3::EmptyAttributeValue()', is_const=True)]) ## wifi-helper.h: void ns3::WifiHelper::SetPhy(std::string phyType, std::string n0="", ns3::AttributeValue const & v0=ns3::EmptyAttributeValue(), std::string n1="", ns3::AttributeValue const & v1=ns3::EmptyAttributeValue(), std::string n2="", ns3::AttributeValue const & v2=ns3::EmptyAttributeValue(), std::string n3="", ns3::AttributeValue const & v3=ns3::EmptyAttributeValue(), std::string n4="", ns3::AttributeValue const & v4=ns3::EmptyAttributeValue(), std::string n5="", ns3::AttributeValue const & v5=ns3::EmptyAttributeValue(), std::string n6="", ns3::AttributeValue const & v6=ns3::EmptyAttributeValue(), std::string n7="", ns3::AttributeValue const & v7=ns3::EmptyAttributeValue()) [member function] - cls.add_method('SetPhy', 'void', [param('std::string', 'phyType'), param('std::string', 'n0', default_value='""'), param('ns3::AttributeValue&', 'v0', default_value='ns3::EmptyAttributeValue()', is_const=True), param('std::string', 'n1', default_value='""'), param('ns3::AttributeValue&', 'v1', default_value='ns3::EmptyAttributeValue()', is_const=True), param('std::string', 'n2', default_value='""'), param('ns3::AttributeValue&', 'v2', default_value='ns3::EmptyAttributeValue()', is_const=True), param('std::string', 'n3', default_value='""'), param('ns3::AttributeValue&', 'v3', default_value='ns3::EmptyAttributeValue()', is_const=True), param('std::string', 'n4', default_value='""'), param('ns3::AttributeValue&', 'v4', default_value='ns3::EmptyAttributeValue()', is_const=True), param('std::string', 'n5', default_value='""'), param('ns3::AttributeValue&', 'v5', default_value='ns3::EmptyAttributeValue()', is_const=True), param('std::string', 'n6', default_value='""'), param('ns3::AttributeValue&', 'v6', default_value='ns3::EmptyAttributeValue()', is_const=True), param('std::string', 'n7', default_value='""'), param('ns3::AttributeValue&', 'v7', default_value='ns3::EmptyAttributeValue()', is_const=True)]) + cls.add_method('SetPhy', + 'void', + [param('std::string', 'phyType'), param('std::string', 'n0', default_value='""'), param('ns3::AttributeValue&', 'v0', default_value='ns3::EmptyAttributeValue()', is_const=True), param('std::string', 'n1', default_value='""'), param('ns3::AttributeValue&', 'v1', default_value='ns3::EmptyAttributeValue()', is_const=True), param('std::string', 'n2', default_value='""'), param('ns3::AttributeValue&', 'v2', default_value='ns3::EmptyAttributeValue()', is_const=True), param('std::string', 'n3', default_value='""'), param('ns3::AttributeValue&', 'v3', default_value='ns3::EmptyAttributeValue()', is_const=True), param('std::string', 'n4', default_value='""'), param('ns3::AttributeValue&', 'v4', default_value='ns3::EmptyAttributeValue()', is_const=True), param('std::string', 'n5', default_value='""'), param('ns3::AttributeValue&', 'v5', default_value='ns3::EmptyAttributeValue()', is_const=True), param('std::string', 'n6', default_value='""'), param('ns3::AttributeValue&', 'v6', default_value='ns3::EmptyAttributeValue()', is_const=True), param('std::string', 'n7', default_value='""'), param('ns3::AttributeValue&', 'v7', default_value='ns3::EmptyAttributeValue()', is_const=True)]) ## wifi-helper.h: static void ns3::WifiHelper::EnablePcap(std::string filename, uint32_t nodeid, uint32_t deviceid) [member function] - cls.add_method('EnablePcap', 'void', [param('std::string', 'filename'), param('uint32_t', 'nodeid'), param('uint32_t', 'deviceid')], is_static=True) + cls.add_method('EnablePcap', + 'void', + [param('std::string', 'filename'), param('uint32_t', 'nodeid'), param('uint32_t', 'deviceid')], + is_static=True) ## wifi-helper.h: static void ns3::WifiHelper::EnablePcap(std::string filename, ns3::NetDeviceContainer d) [member function] - cls.add_method('EnablePcap', 'void', [param('std::string', 'filename'), param('ns3::NetDeviceContainer', 'd')], is_static=True) + cls.add_method('EnablePcap', + 'void', + [param('std::string', 'filename'), param('ns3::NetDeviceContainer', 'd')], + is_static=True) ## wifi-helper.h: static void ns3::WifiHelper::EnablePcap(std::string filename, ns3::NodeContainer n) [member function] - cls.add_method('EnablePcap', 'void', [param('std::string', 'filename'), param('ns3::NodeContainer', 'n')], is_static=True) + cls.add_method('EnablePcap', + 'void', + [param('std::string', 'filename'), param('ns3::NodeContainer', 'n')], + is_static=True) ## wifi-helper.h: static void ns3::WifiHelper::EnablePcapAll(std::string filename) [member function] - cls.add_method('EnablePcapAll', 'void', [param('std::string', 'filename')], is_static=True) + cls.add_method('EnablePcapAll', + 'void', + [param('std::string', 'filename')], + is_static=True) ## wifi-helper.h: static void ns3::WifiHelper::EnableAscii(std::ostream & os, uint32_t nodeid, uint32_t deviceid) [member function] - cls.add_method('EnableAscii', 'void', [param('std::ostream&', 'os'), param('uint32_t', 'nodeid'), param('uint32_t', 'deviceid')], is_static=True) + cls.add_method('EnableAscii', + 'void', + [param('std::ostream&', 'os'), param('uint32_t', 'nodeid'), param('uint32_t', 'deviceid')], + is_static=True) ## wifi-helper.h: static void ns3::WifiHelper::EnableAscii(std::ostream & os, ns3::NetDeviceContainer d) [member function] - cls.add_method('EnableAscii', 'void', [param('std::ostream&', 'os'), param('ns3::NetDeviceContainer', 'd')], is_static=True) + cls.add_method('EnableAscii', + 'void', + [param('std::ostream&', 'os'), param('ns3::NetDeviceContainer', 'd')], + is_static=True) ## wifi-helper.h: static void ns3::WifiHelper::EnableAscii(std::ostream & os, ns3::NodeContainer n) [member function] - cls.add_method('EnableAscii', 'void', [param('std::ostream&', 'os'), param('ns3::NodeContainer', 'n')], is_static=True) + cls.add_method('EnableAscii', + 'void', + [param('std::ostream&', 'os'), param('ns3::NodeContainer', 'n')], + is_static=True) ## wifi-helper.h: static void ns3::WifiHelper::EnableAsciiAll(std::ostream & os) [member function] - cls.add_method('EnableAsciiAll', 'void', [param('std::ostream&', 'os')], is_static=True) + cls.add_method('EnableAsciiAll', + 'void', + [param('std::ostream&', 'os')], + is_static=True) ## wifi-helper.h: ns3::NetDeviceContainer ns3::WifiHelper::Install(ns3::NodeContainer c) const [member function] - cls.add_method('Install', 'ns3::NetDeviceContainer', [param('ns3::NodeContainer', 'c')], is_const=True) + cls.add_method('Install', + 'ns3::NetDeviceContainer', + [param('ns3::NodeContainer', 'c')], + is_const=True) ## wifi-helper.h: ns3::NetDeviceContainer ns3::WifiHelper::Install(ns3::NodeContainer c, ns3::Ptr channel) const [member function] - cls.add_method('Install', 'ns3::NetDeviceContainer', [param('ns3::NodeContainer', 'c'), param('ns3::Ptr< ns3::WifiChannel >', 'channel')], is_const=True) + cls.add_method('Install', + 'ns3::NetDeviceContainer', + [param('ns3::NodeContainer', 'c'), param('ns3::Ptr< ns3::WifiChannel >', 'channel')], + is_const=True) return def register_Ns3Ipv4AddressHelper_methods(root_module, cls): ## ipv4-address-helper.h: ns3::Ipv4AddressHelper::Ipv4AddressHelper() [constructor] - cls.add_constructor([], visibility='public') + cls.add_constructor([]) ## ipv4-address-helper.h: void ns3::Ipv4AddressHelper::SetBase(ns3::Ipv4Address network, ns3::Ipv4Mask mask, ns3::Ipv4Address base="0.0.0.1") [member function] - cls.add_method('SetBase', 'void', [param('ns3::Ipv4Address', 'network'), param('ns3::Ipv4Mask', 'mask'), param('ns3::Ipv4Address', 'base', default_value='"0.0.0.1"')]) + cls.add_method('SetBase', + 'void', + [param('ns3::Ipv4Address', 'network'), param('ns3::Ipv4Mask', 'mask'), param('ns3::Ipv4Address', 'base', default_value='"0.0.0.1"')]) ## ipv4-address-helper.h: ns3::Ipv4Address ns3::Ipv4AddressHelper::NewNetwork() [member function] - cls.add_method('NewNetwork', 'ns3::Ipv4Address', []) + cls.add_method('NewNetwork', + 'ns3::Ipv4Address', + []) ## ipv4-address-helper.h: ns3::Ipv4Address ns3::Ipv4AddressHelper::NewAddress() [member function] - cls.add_method('NewAddress', 'ns3::Ipv4Address', []) + cls.add_method('NewAddress', + 'ns3::Ipv4Address', + []) ## ipv4-address-helper.h: ns3::Ipv4InterfaceContainer ns3::Ipv4AddressHelper::Assign(ns3::NetDeviceContainer const & c) [member function] - cls.add_method('Assign', 'ns3::Ipv4InterfaceContainer', [param('ns3::NetDeviceContainer&', 'c', is_const=True)]) + cls.add_method('Assign', + 'ns3::Ipv4InterfaceContainer', + [param('ns3::NetDeviceContainer&', 'c', is_const=True)]) return def register_Ns3PacketSinkHelper_methods(root_module, cls): ## packet-sink-helper.h: ns3::PacketSinkHelper::PacketSinkHelper(std::string protocol, ns3::Address address) [constructor] - cls.add_constructor([param('std::string', 'protocol'), param('ns3::Address', 'address')], visibility='public') + cls.add_constructor([param('std::string', 'protocol'), param('ns3::Address', 'address')]) ## packet-sink-helper.h: void ns3::PacketSinkHelper::SetAttribute(std::string name, ns3::AttributeValue const & value) [member function] - cls.add_method('SetAttribute', 'void', [param('std::string', 'name'), param('ns3::AttributeValue&', 'value', is_const=True)]) + cls.add_method('SetAttribute', + 'void', + [param('std::string', 'name'), param('ns3::AttributeValue&', 'value', is_const=True)]) ## packet-sink-helper.h: ns3::ApplicationContainer ns3::PacketSinkHelper::Install(ns3::NodeContainer c) [member function] - cls.add_method('Install', 'ns3::ApplicationContainer', [param('ns3::NodeContainer', 'c')]) + cls.add_method('Install', + 'ns3::ApplicationContainer', + [param('ns3::NodeContainer', 'c')]) return def register_Ns3Ns2MobilityHelper_methods(root_module, cls): ## ns2-mobility-helper.h: ns3::Ns2MobilityHelper::Ns2MobilityHelper(std::string filename) [constructor] - cls.add_constructor([param('std::string', 'filename')], visibility='public') + cls.add_constructor([param('std::string', 'filename')]) ## ns2-mobility-helper.h: void ns3::Ns2MobilityHelper::Install() const [member function] - cls.add_method('Install', 'void', [], is_const=True) + cls.add_method('Install', + 'void', + [], + is_const=True) return def register_functions(root_module): diff --git a/bindings/python/ns3_module_internet_stack.py b/bindings/python/ns3_module_internet_stack.py index 6adcbf070..455f52012 100644 --- a/bindings/python/ns3_module_internet_stack.py +++ b/bindings/python/ns3_module_internet_stack.py @@ -1,4 +1,4 @@ -from pybindgen import Module, FileCodeSink, write_preamble, param, retval +from pybindgen import Module, FileCodeSink, param, retval, cppclass def register_types(module): root_module = module.get_root() @@ -66,267 +66,557 @@ def register_methods(root_module): def register_Ns3Ipv4Interface_methods(root_module, cls): ## ipv4-interface.h: static ns3::TypeId ns3::Ipv4Interface::GetTypeId() [member function] - cls.add_method('GetTypeId', 'ns3::TypeId', [], is_static=True) + cls.add_method('GetTypeId', + 'ns3::TypeId', + [], + is_static=True) ## ipv4-interface.h: ns3::Ipv4Interface::Ipv4Interface() [constructor] - cls.add_constructor([], visibility='public') + cls.add_constructor([]) ## ipv4-interface.h: ns3::Ptr ns3::Ipv4Interface::GetDevice() const [member function] - cls.add_method('GetDevice', 'ns3::Ptr< ns3::NetDevice >', [], is_pure_virtual=True, is_const=True, is_virtual=True) + cls.add_method('GetDevice', + 'ns3::Ptr< ns3::NetDevice >', + [], + is_pure_virtual=True, is_const=True, is_virtual=True) ## ipv4-interface.h: void ns3::Ipv4Interface::SetAddress(ns3::Ipv4Address a) [member function] - cls.add_method('SetAddress', 'void', [param('ns3::Ipv4Address', 'a')]) + cls.add_method('SetAddress', + 'void', + [param('ns3::Ipv4Address', 'a')]) ## ipv4-interface.h: void ns3::Ipv4Interface::SetNetworkMask(ns3::Ipv4Mask mask) [member function] - cls.add_method('SetNetworkMask', 'void', [param('ns3::Ipv4Mask', 'mask')]) + cls.add_method('SetNetworkMask', + 'void', + [param('ns3::Ipv4Mask', 'mask')]) ## ipv4-interface.h: ns3::Ipv4Address ns3::Ipv4Interface::GetBroadcast() const [member function] - cls.add_method('GetBroadcast', 'ns3::Ipv4Address', [], is_const=True) + cls.add_method('GetBroadcast', + 'ns3::Ipv4Address', + [], + is_const=True) ## ipv4-interface.h: ns3::Ipv4Mask ns3::Ipv4Interface::GetNetworkMask() const [member function] - cls.add_method('GetNetworkMask', 'ns3::Ipv4Mask', [], is_const=True) + cls.add_method('GetNetworkMask', + 'ns3::Ipv4Mask', + [], + is_const=True) ## ipv4-interface.h: void ns3::Ipv4Interface::SetMetric(uint16_t metric) [member function] - cls.add_method('SetMetric', 'void', [param('uint16_t', 'metric')]) + cls.add_method('SetMetric', + 'void', + [param('uint16_t', 'metric')]) ## ipv4-interface.h: uint16_t ns3::Ipv4Interface::GetMetric() const [member function] - cls.add_method('GetMetric', 'uint16_t', [], is_const=True) + cls.add_method('GetMetric', + 'uint16_t', + [], + is_const=True) ## ipv4-interface.h: ns3::Ipv4Address ns3::Ipv4Interface::GetAddress() const [member function] - cls.add_method('GetAddress', 'ns3::Ipv4Address', [], is_const=True) + cls.add_method('GetAddress', + 'ns3::Ipv4Address', + [], + is_const=True) ## ipv4-interface.h: uint16_t ns3::Ipv4Interface::GetMtu() const [member function] - cls.add_method('GetMtu', 'uint16_t', [], is_const=True) + cls.add_method('GetMtu', + 'uint16_t', + [], + is_const=True) ## ipv4-interface.h: bool ns3::Ipv4Interface::IsUp() const [member function] - cls.add_method('IsUp', 'bool', [], is_const=True) + cls.add_method('IsUp', + 'bool', + [], + is_const=True) ## ipv4-interface.h: bool ns3::Ipv4Interface::IsDown() const [member function] - cls.add_method('IsDown', 'bool', [], is_const=True) + cls.add_method('IsDown', + 'bool', + [], + is_const=True) ## ipv4-interface.h: void ns3::Ipv4Interface::SetUp() [member function] - cls.add_method('SetUp', 'void', []) + cls.add_method('SetUp', + 'void', + []) ## ipv4-interface.h: void ns3::Ipv4Interface::SetDown() [member function] - cls.add_method('SetDown', 'void', []) + cls.add_method('SetDown', + 'void', + []) ## ipv4-interface.h: void ns3::Ipv4Interface::Send(ns3::Ptr p, ns3::Ipv4Address dest) [member function] - cls.add_method('Send', 'void', [param('ns3::Ptr< ns3::Packet >', 'p'), param('ns3::Ipv4Address', 'dest')]) + cls.add_method('Send', + 'void', + [param('ns3::Ptr< ns3::Packet >', 'p'), param('ns3::Ipv4Address', 'dest')]) ## ipv4-interface.h: void ns3::Ipv4Interface::DoDispose() [member function] - cls.add_method('DoDispose', 'void', [], visibility='protected', is_virtual=True) + cls.add_method('DoDispose', + 'void', + [], + visibility='protected', is_virtual=True) ## ipv4-interface.h: void ns3::Ipv4Interface::SendTo(ns3::Ptr p, ns3::Ipv4Address dest) [member function] - cls.add_method('SendTo', 'void', [param('ns3::Ptr< ns3::Packet >', 'p'), param('ns3::Ipv4Address', 'dest')], is_pure_virtual=True, visibility='private', is_virtual=True) + cls.add_method('SendTo', + 'void', + [param('ns3::Ptr< ns3::Packet >', 'p'), param('ns3::Ipv4Address', 'dest')], + is_pure_virtual=True, visibility='private', is_virtual=True) return def register_Ns3UdpHeader_methods(root_module, cls): ## udp-header.h: ns3::UdpHeader::UdpHeader() [constructor] - cls.add_constructor([], visibility='public') + cls.add_constructor([]) ## udp-header.h: void ns3::UdpHeader::EnableChecksums() [member function] - cls.add_method('EnableChecksums', 'void', []) + cls.add_method('EnableChecksums', + 'void', + []) ## udp-header.h: void ns3::UdpHeader::SetDestinationPort(uint16_t port) [member function] - cls.add_method('SetDestinationPort', 'void', [param('uint16_t', 'port')]) + cls.add_method('SetDestinationPort', + 'void', + [param('uint16_t', 'port')]) ## udp-header.h: void ns3::UdpHeader::SetSourcePort(uint16_t port) [member function] - cls.add_method('SetSourcePort', 'void', [param('uint16_t', 'port')]) + cls.add_method('SetSourcePort', + 'void', + [param('uint16_t', 'port')]) ## udp-header.h: uint16_t ns3::UdpHeader::GetSourcePort() const [member function] - cls.add_method('GetSourcePort', 'uint16_t', [], is_const=True) + cls.add_method('GetSourcePort', + 'uint16_t', + [], + is_const=True) ## udp-header.h: uint16_t ns3::UdpHeader::GetDestinationPort() const [member function] - cls.add_method('GetDestinationPort', 'uint16_t', [], is_const=True) + cls.add_method('GetDestinationPort', + 'uint16_t', + [], + is_const=True) ## udp-header.h: void ns3::UdpHeader::InitializeChecksum(ns3::Ipv4Address source, ns3::Ipv4Address destination, uint8_t protocol) [member function] - cls.add_method('InitializeChecksum', 'void', [param('ns3::Ipv4Address', 'source'), param('ns3::Ipv4Address', 'destination'), param('uint8_t', 'protocol')]) + cls.add_method('InitializeChecksum', + 'void', + [param('ns3::Ipv4Address', 'source'), param('ns3::Ipv4Address', 'destination'), param('uint8_t', 'protocol')]) ## udp-header.h: static ns3::TypeId ns3::UdpHeader::GetTypeId() [member function] - cls.add_method('GetTypeId', 'ns3::TypeId', [], is_static=True) + cls.add_method('GetTypeId', + 'ns3::TypeId', + [], + is_static=True) ## udp-header.h: ns3::TypeId ns3::UdpHeader::GetInstanceTypeId() const [member function] - cls.add_method('GetInstanceTypeId', 'ns3::TypeId', [], is_const=True, is_virtual=True) + cls.add_method('GetInstanceTypeId', + 'ns3::TypeId', + [], + is_const=True, is_virtual=True) ## udp-header.h: void ns3::UdpHeader::Print(std::ostream & os) const [member function] - cls.add_method('Print', 'void', [param('std::ostream&', 'os')], is_const=True, is_virtual=True) + cls.add_method('Print', + 'void', + [param('std::ostream&', 'os')], + is_const=True, is_virtual=True) ## udp-header.h: uint32_t ns3::UdpHeader::GetSerializedSize() const [member function] - cls.add_method('GetSerializedSize', 'uint32_t', [], is_const=True, is_virtual=True) + cls.add_method('GetSerializedSize', + 'uint32_t', + [], + is_const=True, is_virtual=True) ## udp-header.h: void ns3::UdpHeader::Serialize(ns3::Buffer::Iterator start) const [member function] - cls.add_method('Serialize', 'void', [param('ns3::Buffer::Iterator', 'start')], is_const=True, is_virtual=True) + cls.add_method('Serialize', + 'void', + [param('ns3::Buffer::Iterator', 'start')], + is_const=True, is_virtual=True) ## udp-header.h: uint32_t ns3::UdpHeader::Deserialize(ns3::Buffer::Iterator start) [member function] - cls.add_method('Deserialize', 'uint32_t', [param('ns3::Buffer::Iterator', 'start')], is_virtual=True) + cls.add_method('Deserialize', + 'uint32_t', + [param('ns3::Buffer::Iterator', 'start')], + is_virtual=True) ## udp-header.h: bool ns3::UdpHeader::IsChecksumOk() const [member function] - cls.add_method('IsChecksumOk', 'bool', [], is_const=True) + cls.add_method('IsChecksumOk', + 'bool', + [], + is_const=True) return def register_Ns3TcpHeader_methods(root_module, cls): ## tcp-header.h: ns3::TcpHeader::TcpHeader() [constructor] - cls.add_constructor([], visibility='public') + cls.add_constructor([]) ## tcp-header.h: void ns3::TcpHeader::EnableChecksums() [member function] - cls.add_method('EnableChecksums', 'void', []) + cls.add_method('EnableChecksums', + 'void', + []) ## tcp-header.h: void ns3::TcpHeader::SetSourcePort(uint16_t port) [member function] - cls.add_method('SetSourcePort', 'void', [param('uint16_t', 'port')]) + cls.add_method('SetSourcePort', + 'void', + [param('uint16_t', 'port')]) ## tcp-header.h: void ns3::TcpHeader::SetDestinationPort(uint16_t port) [member function] - cls.add_method('SetDestinationPort', 'void', [param('uint16_t', 'port')]) + cls.add_method('SetDestinationPort', + 'void', + [param('uint16_t', 'port')]) ## tcp-header.h: void ns3::TcpHeader::SetSequenceNumber(SequenceNumber sequenceNumber) [member function] - cls.add_method('SetSequenceNumber', 'void', [param('SequenceNumber', 'sequenceNumber')]) + cls.add_method('SetSequenceNumber', + 'void', + [param('SequenceNumber', 'sequenceNumber')]) ## tcp-header.h: void ns3::TcpHeader::SetAckNumber(SequenceNumber ackNumber) [member function] - cls.add_method('SetAckNumber', 'void', [param('SequenceNumber', 'ackNumber')]) + cls.add_method('SetAckNumber', + 'void', + [param('SequenceNumber', 'ackNumber')]) ## tcp-header.h: void ns3::TcpHeader::SetLength(uint8_t length) [member function] - cls.add_method('SetLength', 'void', [param('uint8_t', 'length')]) + cls.add_method('SetLength', + 'void', + [param('uint8_t', 'length')]) ## tcp-header.h: void ns3::TcpHeader::SetFlags(uint8_t flags) [member function] - cls.add_method('SetFlags', 'void', [param('uint8_t', 'flags')]) + cls.add_method('SetFlags', + 'void', + [param('uint8_t', 'flags')]) ## tcp-header.h: void ns3::TcpHeader::SetWindowSize(uint16_t windowSize) [member function] - cls.add_method('SetWindowSize', 'void', [param('uint16_t', 'windowSize')]) + cls.add_method('SetWindowSize', + 'void', + [param('uint16_t', 'windowSize')]) ## tcp-header.h: void ns3::TcpHeader::SetUrgentPointer(uint16_t urgentPointer) [member function] - cls.add_method('SetUrgentPointer', 'void', [param('uint16_t', 'urgentPointer')]) + cls.add_method('SetUrgentPointer', + 'void', + [param('uint16_t', 'urgentPointer')]) ## tcp-header.h: uint16_t ns3::TcpHeader::GetSourcePort() const [member function] - cls.add_method('GetSourcePort', 'uint16_t', [], is_const=True) + cls.add_method('GetSourcePort', + 'uint16_t', + [], + is_const=True) ## tcp-header.h: uint16_t ns3::TcpHeader::GetDestinationPort() const [member function] - cls.add_method('GetDestinationPort', 'uint16_t', [], is_const=True) + cls.add_method('GetDestinationPort', + 'uint16_t', + [], + is_const=True) ## tcp-header.h: SequenceNumber ns3::TcpHeader::GetSequenceNumber() const [member function] - cls.add_method('GetSequenceNumber', 'SequenceNumber', [], is_const=True) + cls.add_method('GetSequenceNumber', + 'SequenceNumber', + [], + is_const=True) ## tcp-header.h: SequenceNumber ns3::TcpHeader::GetAckNumber() const [member function] - cls.add_method('GetAckNumber', 'SequenceNumber', [], is_const=True) + cls.add_method('GetAckNumber', + 'SequenceNumber', + [], + is_const=True) ## tcp-header.h: uint8_t ns3::TcpHeader::GetLength() const [member function] - cls.add_method('GetLength', 'uint8_t', [], is_const=True) + cls.add_method('GetLength', + 'uint8_t', + [], + is_const=True) ## tcp-header.h: uint8_t ns3::TcpHeader::GetFlags() const [member function] - cls.add_method('GetFlags', 'uint8_t', [], is_const=True) + cls.add_method('GetFlags', + 'uint8_t', + [], + is_const=True) ## tcp-header.h: uint16_t ns3::TcpHeader::GetWindowSize() const [member function] - cls.add_method('GetWindowSize', 'uint16_t', [], is_const=True) + cls.add_method('GetWindowSize', + 'uint16_t', + [], + is_const=True) ## tcp-header.h: uint16_t ns3::TcpHeader::GetUrgentPointer() const [member function] - cls.add_method('GetUrgentPointer', 'uint16_t', [], is_const=True) + cls.add_method('GetUrgentPointer', + 'uint16_t', + [], + is_const=True) ## tcp-header.h: void ns3::TcpHeader::InitializeChecksum(ns3::Ipv4Address source, ns3::Ipv4Address destination, uint8_t protocol) [member function] - cls.add_method('InitializeChecksum', 'void', [param('ns3::Ipv4Address', 'source'), param('ns3::Ipv4Address', 'destination'), param('uint8_t', 'protocol')]) + cls.add_method('InitializeChecksum', + 'void', + [param('ns3::Ipv4Address', 'source'), param('ns3::Ipv4Address', 'destination'), param('uint8_t', 'protocol')]) ## tcp-header.h: static ns3::TypeId ns3::TcpHeader::GetTypeId() [member function] - cls.add_method('GetTypeId', 'ns3::TypeId', [], is_static=True) + cls.add_method('GetTypeId', + 'ns3::TypeId', + [], + is_static=True) ## tcp-header.h: ns3::TypeId ns3::TcpHeader::GetInstanceTypeId() const [member function] - cls.add_method('GetInstanceTypeId', 'ns3::TypeId', [], is_const=True, is_virtual=True) + cls.add_method('GetInstanceTypeId', + 'ns3::TypeId', + [], + is_const=True, is_virtual=True) ## tcp-header.h: void ns3::TcpHeader::Print(std::ostream & os) const [member function] - cls.add_method('Print', 'void', [param('std::ostream&', 'os')], is_const=True, is_virtual=True) + cls.add_method('Print', + 'void', + [param('std::ostream&', 'os')], + is_const=True, is_virtual=True) ## tcp-header.h: uint32_t ns3::TcpHeader::GetSerializedSize() const [member function] - cls.add_method('GetSerializedSize', 'uint32_t', [], is_const=True, is_virtual=True) + cls.add_method('GetSerializedSize', + 'uint32_t', + [], + is_const=True, is_virtual=True) ## tcp-header.h: void ns3::TcpHeader::Serialize(ns3::Buffer::Iterator start) const [member function] - cls.add_method('Serialize', 'void', [param('ns3::Buffer::Iterator', 'start')], is_const=True, is_virtual=True) + cls.add_method('Serialize', + 'void', + [param('ns3::Buffer::Iterator', 'start')], + is_const=True, is_virtual=True) ## tcp-header.h: uint32_t ns3::TcpHeader::Deserialize(ns3::Buffer::Iterator start) [member function] - cls.add_method('Deserialize', 'uint32_t', [param('ns3::Buffer::Iterator', 'start')], is_virtual=True) + cls.add_method('Deserialize', + 'uint32_t', + [param('ns3::Buffer::Iterator', 'start')], + is_virtual=True) ## tcp-header.h: bool ns3::TcpHeader::IsChecksumOk() const [member function] - cls.add_method('IsChecksumOk', 'bool', [], is_const=True) + cls.add_method('IsChecksumOk', + 'bool', + [], + is_const=True) return def register_Ns3Ipv4StaticRouting_methods(root_module, cls): ## ipv4-static-routing.h: ns3::Ipv4StaticRouting::Ipv4StaticRouting() [constructor] - cls.add_constructor([], visibility='public') + cls.add_constructor([]) ## ipv4-static-routing.h: bool ns3::Ipv4StaticRouting::RequestRoute(uint32_t ifIndex, ns3::Ipv4Header const & ipHeader, ns3::Ptr packet, ns3::Callback,const ns3::Ipv4Header&,ns3::empty,ns3::empty> routeReply) [member function] - cls.add_method('RequestRoute', 'bool', [param('uint32_t', 'ifIndex'), param('ns3::Ipv4Header&', 'ipHeader', is_const=True), param('ns3::Ptr< ns3::Packet >', 'packet'), param('ns3::Callback< void, bool, const ns3::Ipv4Route&, ns3::Ptr< ns3::Packet >, const ns3::Ipv4Header&, ns3::empty, ns3::empty >', 'routeReply')], is_virtual=True) + cls.add_method('RequestRoute', + 'bool', + [param('uint32_t', 'ifIndex'), param('ns3::Ipv4Header&', 'ipHeader', is_const=True), param('ns3::Ptr< ns3::Packet >', 'packet'), param('ns3::Callback< void, bool, const ns3::Ipv4Route&, ns3::Ptr< ns3::Packet >, const ns3::Ipv4Header&, ns3::empty, ns3::empty >', 'routeReply')], + is_virtual=True) ## ipv4-static-routing.h: bool ns3::Ipv4StaticRouting::RequestIfIndex(ns3::Ipv4Address destination, uint32_t & ifIndex) [member function] - cls.add_method('RequestIfIndex', 'bool', [param('ns3::Ipv4Address', 'destination'), param('uint32_t&', 'ifIndex')], is_virtual=True) + cls.add_method('RequestIfIndex', + 'bool', + [param('ns3::Ipv4Address', 'destination'), param('uint32_t&', 'ifIndex')], + is_virtual=True) ## ipv4-static-routing.h: void ns3::Ipv4StaticRouting::AddHostRouteTo(ns3::Ipv4Address dest, ns3::Ipv4Address nextHop, uint32_t interface) [member function] - cls.add_method('AddHostRouteTo', 'void', [param('ns3::Ipv4Address', 'dest'), param('ns3::Ipv4Address', 'nextHop'), param('uint32_t', 'interface')]) + cls.add_method('AddHostRouteTo', + 'void', + [param('ns3::Ipv4Address', 'dest'), param('ns3::Ipv4Address', 'nextHop'), param('uint32_t', 'interface')]) ## ipv4-static-routing.h: void ns3::Ipv4StaticRouting::AddHostRouteTo(ns3::Ipv4Address dest, uint32_t interface) [member function] - cls.add_method('AddHostRouteTo', 'void', [param('ns3::Ipv4Address', 'dest'), param('uint32_t', 'interface')]) + cls.add_method('AddHostRouteTo', + 'void', + [param('ns3::Ipv4Address', 'dest'), param('uint32_t', 'interface')]) ## ipv4-static-routing.h: void ns3::Ipv4StaticRouting::AddNetworkRouteTo(ns3::Ipv4Address network, ns3::Ipv4Mask networkMask, ns3::Ipv4Address nextHop, uint32_t interface) [member function] - cls.add_method('AddNetworkRouteTo', 'void', [param('ns3::Ipv4Address', 'network'), param('ns3::Ipv4Mask', 'networkMask'), param('ns3::Ipv4Address', 'nextHop'), param('uint32_t', 'interface')]) + cls.add_method('AddNetworkRouteTo', + 'void', + [param('ns3::Ipv4Address', 'network'), param('ns3::Ipv4Mask', 'networkMask'), param('ns3::Ipv4Address', 'nextHop'), param('uint32_t', 'interface')]) ## ipv4-static-routing.h: void ns3::Ipv4StaticRouting::AddNetworkRouteTo(ns3::Ipv4Address network, ns3::Ipv4Mask networkMask, uint32_t interface) [member function] - cls.add_method('AddNetworkRouteTo', 'void', [param('ns3::Ipv4Address', 'network'), param('ns3::Ipv4Mask', 'networkMask'), param('uint32_t', 'interface')]) + cls.add_method('AddNetworkRouteTo', + 'void', + [param('ns3::Ipv4Address', 'network'), param('ns3::Ipv4Mask', 'networkMask'), param('uint32_t', 'interface')]) ## ipv4-static-routing.h: void ns3::Ipv4StaticRouting::SetDefaultRoute(ns3::Ipv4Address nextHop, uint32_t interface) [member function] - cls.add_method('SetDefaultRoute', 'void', [param('ns3::Ipv4Address', 'nextHop'), param('uint32_t', 'interface')]) + cls.add_method('SetDefaultRoute', + 'void', + [param('ns3::Ipv4Address', 'nextHop'), param('uint32_t', 'interface')]) ## ipv4-static-routing.h: uint32_t ns3::Ipv4StaticRouting::GetNRoutes() [member function] - cls.add_method('GetNRoutes', 'uint32_t', []) + cls.add_method('GetNRoutes', + 'uint32_t', + []) ## ipv4-static-routing.h: ns3::Ipv4Route * ns3::Ipv4StaticRouting::GetDefaultRoute() [member function] - cls.add_method('GetDefaultRoute', 'ns3::Ipv4Route *', []) + cls.add_method('GetDefaultRoute', + 'ns3::Ipv4Route *', + []) ## ipv4-static-routing.h: ns3::Ipv4Route * ns3::Ipv4StaticRouting::GetRoute(uint32_t i) [member function] - cls.add_method('GetRoute', 'ns3::Ipv4Route *', [param('uint32_t', 'i')]) + cls.add_method('GetRoute', + 'ns3::Ipv4Route *', + [param('uint32_t', 'i')]) ## ipv4-static-routing.h: void ns3::Ipv4StaticRouting::RemoveRoute(uint32_t i) [member function] - cls.add_method('RemoveRoute', 'void', [param('uint32_t', 'i')]) + cls.add_method('RemoveRoute', + 'void', + [param('uint32_t', 'i')]) ## ipv4-static-routing.h: void ns3::Ipv4StaticRouting::AddMulticastRoute(ns3::Ipv4Address origin, ns3::Ipv4Address group, uint32_t inputInterface, std::vector > outputInterfaces) [member function] - cls.add_method('AddMulticastRoute', 'void', [param('ns3::Ipv4Address', 'origin'), param('ns3::Ipv4Address', 'group'), param('uint32_t', 'inputInterface'), param('std::vector< unsigned int, std::allocator< unsigned int > >', 'outputInterfaces')]) + cls.add_method('AddMulticastRoute', + 'void', + [param('ns3::Ipv4Address', 'origin'), param('ns3::Ipv4Address', 'group'), param('uint32_t', 'inputInterface'), param('std::vector< unsigned int, std::allocator< unsigned int > >', 'outputInterfaces')]) ## ipv4-static-routing.h: void ns3::Ipv4StaticRouting::SetDefaultMulticastRoute(uint32_t outputInterface) [member function] - cls.add_method('SetDefaultMulticastRoute', 'void', [param('uint32_t', 'outputInterface')]) + cls.add_method('SetDefaultMulticastRoute', + 'void', + [param('uint32_t', 'outputInterface')]) ## ipv4-static-routing.h: uint32_t ns3::Ipv4StaticRouting::GetNMulticastRoutes() const [member function] - cls.add_method('GetNMulticastRoutes', 'uint32_t', [], is_const=True) + cls.add_method('GetNMulticastRoutes', + 'uint32_t', + [], + is_const=True) ## ipv4-static-routing.h: ns3::Ipv4MulticastRoute * ns3::Ipv4StaticRouting::GetMulticastRoute(uint32_t i) const [member function] - cls.add_method('GetMulticastRoute', 'ns3::Ipv4MulticastRoute *', [param('uint32_t', 'i')], is_const=True) + cls.add_method('GetMulticastRoute', + 'ns3::Ipv4MulticastRoute *', + [param('uint32_t', 'i')], + is_const=True) ## ipv4-static-routing.h: ns3::Ipv4MulticastRoute * ns3::Ipv4StaticRouting::GetDefaultMulticastRoute() const [member function] - cls.add_method('GetDefaultMulticastRoute', 'ns3::Ipv4MulticastRoute *', [], is_const=True) + cls.add_method('GetDefaultMulticastRoute', + 'ns3::Ipv4MulticastRoute *', + [], + is_const=True) ## ipv4-static-routing.h: bool ns3::Ipv4StaticRouting::RemoveMulticastRoute(ns3::Ipv4Address origin, ns3::Ipv4Address group, uint32_t inputInterface) [member function] - cls.add_method('RemoveMulticastRoute', 'bool', [param('ns3::Ipv4Address', 'origin'), param('ns3::Ipv4Address', 'group'), param('uint32_t', 'inputInterface')]) + cls.add_method('RemoveMulticastRoute', + 'bool', + [param('ns3::Ipv4Address', 'origin'), param('ns3::Ipv4Address', 'group'), param('uint32_t', 'inputInterface')]) ## ipv4-static-routing.h: void ns3::Ipv4StaticRouting::RemoveMulticastRoute(uint32_t index) [member function] - cls.add_method('RemoveMulticastRoute', 'void', [param('uint32_t', 'index')]) + cls.add_method('RemoveMulticastRoute', + 'void', + [param('uint32_t', 'index')]) ## ipv4-static-routing.h: void ns3::Ipv4StaticRouting::DoDispose() [member function] - cls.add_method('DoDispose', 'void', [], visibility='protected', is_virtual=True) + cls.add_method('DoDispose', + 'void', + [], + visibility='protected', is_virtual=True) return def register_Ns3Ipv4L3Protocol_methods(root_module, cls): ## ipv4-l3-protocol.h: ns3::Ipv4L3Protocol::PROT_NUMBER [variable] cls.add_static_attribute('PROT_NUMBER', retval('uint16_t', is_const=True), is_const=True) ## ipv4-l3-protocol.h: static ns3::TypeId ns3::Ipv4L3Protocol::GetTypeId() [member function] - cls.add_method('GetTypeId', 'ns3::TypeId', [], is_static=True) + cls.add_method('GetTypeId', + 'ns3::TypeId', + [], + is_static=True) ## ipv4-l3-protocol.h: ns3::Ipv4L3Protocol::Ipv4L3Protocol() [constructor] - cls.add_constructor([], visibility='public') + cls.add_constructor([]) ## ipv4-l3-protocol.h: void ns3::Ipv4L3Protocol::SetNode(ns3::Ptr node) [member function] - cls.add_method('SetNode', 'void', [param('ns3::Ptr< ns3::Node >', 'node')]) + cls.add_method('SetNode', + 'void', + [param('ns3::Ptr< ns3::Node >', 'node')]) ## ipv4-l3-protocol.h: void ns3::Ipv4L3Protocol::SetDefaultTtl(uint8_t ttl) [member function] - cls.add_method('SetDefaultTtl', 'void', [param('uint8_t', 'ttl')]) + cls.add_method('SetDefaultTtl', + 'void', + [param('uint8_t', 'ttl')]) ## ipv4-l3-protocol.h: ns3::Ptr ns3::Ipv4L3Protocol::FindInterfaceForDevice(ns3::Ptr device) [member function] - cls.add_method('FindInterfaceForDevice', 'ns3::Ptr< ns3::Ipv4Interface >', [param('ns3::Ptr< const ns3::NetDevice >', 'device')]) + cls.add_method('FindInterfaceForDevice', + 'ns3::Ptr< ns3::Ipv4Interface >', + [param('ns3::Ptr< const ns3::NetDevice >', 'device')]) ## ipv4-l3-protocol.h: void ns3::Ipv4L3Protocol::Receive(ns3::Ptr device, ns3::Ptr p, uint16_t protocol, ns3::Address const & from, ns3::Address const & to, ns3::NetDevice::PacketType packetType) [member function] - cls.add_method('Receive', 'void', [param('ns3::Ptr< ns3::NetDevice >', 'device'), param('ns3::Ptr< ns3::Packet >', 'p'), param('uint16_t', 'protocol'), param('ns3::Address&', 'from', is_const=True), param('ns3::Address&', 'to', is_const=True), param('ns3::NetDevice::PacketType', 'packetType')]) + cls.add_method('Receive', + 'void', + [param('ns3::Ptr< ns3::NetDevice >', 'device'), param('ns3::Ptr< ns3::Packet >', 'p'), param('uint16_t', 'protocol'), param('ns3::Address&', 'from', is_const=True), param('ns3::Address&', 'to', is_const=True), param('ns3::NetDevice::PacketType', 'packetType')]) ## ipv4-l3-protocol.h: void ns3::Ipv4L3Protocol::Send(ns3::Ptr packet, ns3::Ipv4Address source, ns3::Ipv4Address destination, uint8_t protocol) [member function] - cls.add_method('Send', 'void', [param('ns3::Ptr< ns3::Packet >', 'packet'), param('ns3::Ipv4Address', 'source'), param('ns3::Ipv4Address', 'destination'), param('uint8_t', 'protocol')]) + cls.add_method('Send', + 'void', + [param('ns3::Ptr< ns3::Packet >', 'packet'), param('ns3::Ipv4Address', 'source'), param('ns3::Ipv4Address', 'destination'), param('uint8_t', 'protocol')]) ## ipv4-l3-protocol.h: void ns3::Ipv4L3Protocol::AddHostRouteTo(ns3::Ipv4Address dest, ns3::Ipv4Address nextHop, uint32_t interface) [member function] - cls.add_method('AddHostRouteTo', 'void', [param('ns3::Ipv4Address', 'dest'), param('ns3::Ipv4Address', 'nextHop'), param('uint32_t', 'interface')]) + cls.add_method('AddHostRouteTo', + 'void', + [param('ns3::Ipv4Address', 'dest'), param('ns3::Ipv4Address', 'nextHop'), param('uint32_t', 'interface')]) ## ipv4-l3-protocol.h: void ns3::Ipv4L3Protocol::AddHostRouteTo(ns3::Ipv4Address dest, uint32_t interface) [member function] - cls.add_method('AddHostRouteTo', 'void', [param('ns3::Ipv4Address', 'dest'), param('uint32_t', 'interface')]) + cls.add_method('AddHostRouteTo', + 'void', + [param('ns3::Ipv4Address', 'dest'), param('uint32_t', 'interface')]) ## ipv4-l3-protocol.h: void ns3::Ipv4L3Protocol::AddNetworkRouteTo(ns3::Ipv4Address network, ns3::Ipv4Mask networkMask, ns3::Ipv4Address nextHop, uint32_t interface) [member function] - cls.add_method('AddNetworkRouteTo', 'void', [param('ns3::Ipv4Address', 'network'), param('ns3::Ipv4Mask', 'networkMask'), param('ns3::Ipv4Address', 'nextHop'), param('uint32_t', 'interface')]) + cls.add_method('AddNetworkRouteTo', + 'void', + [param('ns3::Ipv4Address', 'network'), param('ns3::Ipv4Mask', 'networkMask'), param('ns3::Ipv4Address', 'nextHop'), param('uint32_t', 'interface')]) ## ipv4-l3-protocol.h: void ns3::Ipv4L3Protocol::AddNetworkRouteTo(ns3::Ipv4Address network, ns3::Ipv4Mask networkMask, uint32_t interface) [member function] - cls.add_method('AddNetworkRouteTo', 'void', [param('ns3::Ipv4Address', 'network'), param('ns3::Ipv4Mask', 'networkMask'), param('uint32_t', 'interface')]) + cls.add_method('AddNetworkRouteTo', + 'void', + [param('ns3::Ipv4Address', 'network'), param('ns3::Ipv4Mask', 'networkMask'), param('uint32_t', 'interface')]) ## ipv4-l3-protocol.h: void ns3::Ipv4L3Protocol::SetDefaultRoute(ns3::Ipv4Address nextHop, uint32_t interface) [member function] - cls.add_method('SetDefaultRoute', 'void', [param('ns3::Ipv4Address', 'nextHop'), param('uint32_t', 'interface')]) + cls.add_method('SetDefaultRoute', + 'void', + [param('ns3::Ipv4Address', 'nextHop'), param('uint32_t', 'interface')]) ## ipv4-l3-protocol.h: void ns3::Ipv4L3Protocol::Lookup(ns3::Ipv4Header const & ipHeader, ns3::Ptr packet, ns3::Callback,const ns3::Ipv4Header&,ns3::empty,ns3::empty> routeReply) [member function] - cls.add_method('Lookup', 'void', [param('ns3::Ipv4Header&', 'ipHeader', is_const=True), param('ns3::Ptr< ns3::Packet >', 'packet'), param('ns3::Callback< void, bool, const ns3::Ipv4Route&, ns3::Ptr< ns3::Packet >, const ns3::Ipv4Header&, ns3::empty, ns3::empty >', 'routeReply')]) + cls.add_method('Lookup', + 'void', + [param('ns3::Ipv4Header&', 'ipHeader', is_const=True), param('ns3::Ptr< ns3::Packet >', 'packet'), param('ns3::Callback< void, bool, const ns3::Ipv4Route&, ns3::Ptr< ns3::Packet >, const ns3::Ipv4Header&, ns3::empty, ns3::empty >', 'routeReply')]) ## ipv4-l3-protocol.h: uint32_t ns3::Ipv4L3Protocol::GetNRoutes() [member function] - cls.add_method('GetNRoutes', 'uint32_t', []) + cls.add_method('GetNRoutes', + 'uint32_t', + []) ## ipv4-l3-protocol.h: ns3::Ipv4Route * ns3::Ipv4L3Protocol::GetRoute(uint32_t i) [member function] - cls.add_method('GetRoute', 'ns3::Ipv4Route *', [param('uint32_t', 'i')]) + cls.add_method('GetRoute', + 'ns3::Ipv4Route *', + [param('uint32_t', 'i')]) ## ipv4-l3-protocol.h: void ns3::Ipv4L3Protocol::RemoveRoute(uint32_t i) [member function] - cls.add_method('RemoveRoute', 'void', [param('uint32_t', 'i')]) + cls.add_method('RemoveRoute', + 'void', + [param('uint32_t', 'i')]) ## ipv4-l3-protocol.h: void ns3::Ipv4L3Protocol::AddMulticastRoute(ns3::Ipv4Address origin, ns3::Ipv4Address group, uint32_t inputInterface, std::vector > outputInterfaces) [member function] - cls.add_method('AddMulticastRoute', 'void', [param('ns3::Ipv4Address', 'origin'), param('ns3::Ipv4Address', 'group'), param('uint32_t', 'inputInterface'), param('std::vector< unsigned int, std::allocator< unsigned int > >', 'outputInterfaces')]) + cls.add_method('AddMulticastRoute', + 'void', + [param('ns3::Ipv4Address', 'origin'), param('ns3::Ipv4Address', 'group'), param('uint32_t', 'inputInterface'), param('std::vector< unsigned int, std::allocator< unsigned int > >', 'outputInterfaces')]) ## ipv4-l3-protocol.h: void ns3::Ipv4L3Protocol::SetDefaultMulticastRoute(uint32_t onputInterface) [member function] - cls.add_method('SetDefaultMulticastRoute', 'void', [param('uint32_t', 'onputInterface')]) + cls.add_method('SetDefaultMulticastRoute', + 'void', + [param('uint32_t', 'onputInterface')]) ## ipv4-l3-protocol.h: uint32_t ns3::Ipv4L3Protocol::GetNMulticastRoutes() const [member function] - cls.add_method('GetNMulticastRoutes', 'uint32_t', [], is_const=True) + cls.add_method('GetNMulticastRoutes', + 'uint32_t', + [], + is_const=True) ## ipv4-l3-protocol.h: ns3::Ipv4MulticastRoute * ns3::Ipv4L3Protocol::GetMulticastRoute(uint32_t i) const [member function] - cls.add_method('GetMulticastRoute', 'ns3::Ipv4MulticastRoute *', [param('uint32_t', 'i')], is_const=True) + cls.add_method('GetMulticastRoute', + 'ns3::Ipv4MulticastRoute *', + [param('uint32_t', 'i')], + is_const=True) ## ipv4-l3-protocol.h: void ns3::Ipv4L3Protocol::RemoveMulticastRoute(ns3::Ipv4Address origin, ns3::Ipv4Address group, uint32_t inputInterface) [member function] - cls.add_method('RemoveMulticastRoute', 'void', [param('ns3::Ipv4Address', 'origin'), param('ns3::Ipv4Address', 'group'), param('uint32_t', 'inputInterface')]) + cls.add_method('RemoveMulticastRoute', + 'void', + [param('ns3::Ipv4Address', 'origin'), param('ns3::Ipv4Address', 'group'), param('uint32_t', 'inputInterface')]) ## ipv4-l3-protocol.h: void ns3::Ipv4L3Protocol::RemoveMulticastRoute(uint32_t i) [member function] - cls.add_method('RemoveMulticastRoute', 'void', [param('uint32_t', 'i')]) + cls.add_method('RemoveMulticastRoute', + 'void', + [param('uint32_t', 'i')]) ## ipv4-l3-protocol.h: uint32_t ns3::Ipv4L3Protocol::AddInterface(ns3::Ptr device) [member function] - cls.add_method('AddInterface', 'uint32_t', [param('ns3::Ptr< ns3::NetDevice >', 'device')]) + cls.add_method('AddInterface', + 'uint32_t', + [param('ns3::Ptr< ns3::NetDevice >', 'device')]) ## ipv4-l3-protocol.h: ns3::Ptr ns3::Ipv4L3Protocol::GetInterface(uint32_t i) const [member function] - cls.add_method('GetInterface', 'ns3::Ptr< ns3::Ipv4Interface >', [param('uint32_t', 'i')], is_const=True) + cls.add_method('GetInterface', + 'ns3::Ptr< ns3::Ipv4Interface >', + [param('uint32_t', 'i')], + is_const=True) ## ipv4-l3-protocol.h: uint32_t ns3::Ipv4L3Protocol::GetNInterfaces() const [member function] - cls.add_method('GetNInterfaces', 'uint32_t', [], is_const=True) + cls.add_method('GetNInterfaces', + 'uint32_t', + [], + is_const=True) ## ipv4-l3-protocol.h: uint32_t ns3::Ipv4L3Protocol::FindInterfaceForAddr(ns3::Ipv4Address addr) const [member function] - cls.add_method('FindInterfaceForAddr', 'uint32_t', [param('ns3::Ipv4Address', 'addr')], is_const=True) + cls.add_method('FindInterfaceForAddr', + 'uint32_t', + [param('ns3::Ipv4Address', 'addr')], + is_const=True) ## ipv4-l3-protocol.h: uint32_t ns3::Ipv4L3Protocol::FindInterfaceForAddr(ns3::Ipv4Address addr, ns3::Ipv4Mask mask) const [member function] - cls.add_method('FindInterfaceForAddr', 'uint32_t', [param('ns3::Ipv4Address', 'addr'), param('ns3::Ipv4Mask', 'mask')], is_const=True) + cls.add_method('FindInterfaceForAddr', + 'uint32_t', + [param('ns3::Ipv4Address', 'addr'), param('ns3::Ipv4Mask', 'mask')], + is_const=True) ## ipv4-l3-protocol.h: int32_t ns3::Ipv4L3Protocol::FindInterfaceIndexForDevice(ns3::Ptr device) const [member function] - cls.add_method('FindInterfaceIndexForDevice', 'int32_t', [param('ns3::Ptr< ns3::NetDevice >', 'device')], is_const=True) + cls.add_method('FindInterfaceIndexForDevice', + 'int32_t', + [param('ns3::Ptr< ns3::NetDevice >', 'device')], + is_const=True) ## ipv4-l3-protocol.h: void ns3::Ipv4L3Protocol::JoinMulticastGroup(ns3::Ipv4Address origin, ns3::Ipv4Address group) [member function] - cls.add_method('JoinMulticastGroup', 'void', [param('ns3::Ipv4Address', 'origin'), param('ns3::Ipv4Address', 'group')]) + cls.add_method('JoinMulticastGroup', + 'void', + [param('ns3::Ipv4Address', 'origin'), param('ns3::Ipv4Address', 'group')]) ## ipv4-l3-protocol.h: void ns3::Ipv4L3Protocol::LeaveMulticastGroup(ns3::Ipv4Address origin, ns3::Ipv4Address group) [member function] - cls.add_method('LeaveMulticastGroup', 'void', [param('ns3::Ipv4Address', 'origin'), param('ns3::Ipv4Address', 'group')]) + cls.add_method('LeaveMulticastGroup', + 'void', + [param('ns3::Ipv4Address', 'origin'), param('ns3::Ipv4Address', 'group')]) ## ipv4-l3-protocol.h: void ns3::Ipv4L3Protocol::SetAddress(uint32_t i, ns3::Ipv4Address address) [member function] - cls.add_method('SetAddress', 'void', [param('uint32_t', 'i'), param('ns3::Ipv4Address', 'address')]) + cls.add_method('SetAddress', + 'void', + [param('uint32_t', 'i'), param('ns3::Ipv4Address', 'address')]) ## ipv4-l3-protocol.h: void ns3::Ipv4L3Protocol::SetNetworkMask(uint32_t i, ns3::Ipv4Mask mask) [member function] - cls.add_method('SetNetworkMask', 'void', [param('uint32_t', 'i'), param('ns3::Ipv4Mask', 'mask')]) + cls.add_method('SetNetworkMask', + 'void', + [param('uint32_t', 'i'), param('ns3::Ipv4Mask', 'mask')]) ## ipv4-l3-protocol.h: ns3::Ipv4Mask ns3::Ipv4L3Protocol::GetNetworkMask(uint32_t t) const [member function] - cls.add_method('GetNetworkMask', 'ns3::Ipv4Mask', [param('uint32_t', 't')], is_const=True) + cls.add_method('GetNetworkMask', + 'ns3::Ipv4Mask', + [param('uint32_t', 't')], + is_const=True) ## ipv4-l3-protocol.h: ns3::Ipv4Address ns3::Ipv4L3Protocol::GetAddress(uint32_t i) const [member function] - cls.add_method('GetAddress', 'ns3::Ipv4Address', [param('uint32_t', 'i')], is_const=True) + cls.add_method('GetAddress', + 'ns3::Ipv4Address', + [param('uint32_t', 'i')], + is_const=True) ## ipv4-l3-protocol.h: void ns3::Ipv4L3Protocol::SetMetric(uint32_t i, uint16_t metric) [member function] - cls.add_method('SetMetric', 'void', [param('uint32_t', 'i'), param('uint16_t', 'metric')]) + cls.add_method('SetMetric', + 'void', + [param('uint32_t', 'i'), param('uint16_t', 'metric')]) ## ipv4-l3-protocol.h: uint16_t ns3::Ipv4L3Protocol::GetMetric(uint32_t i) const [member function] - cls.add_method('GetMetric', 'uint16_t', [param('uint32_t', 'i')], is_const=True) + cls.add_method('GetMetric', + 'uint16_t', + [param('uint32_t', 'i')], + is_const=True) ## ipv4-l3-protocol.h: bool ns3::Ipv4L3Protocol::GetIfIndexForDestination(ns3::Ipv4Address destination, uint32_t & ifIndex) const [member function] - cls.add_method('GetIfIndexForDestination', 'bool', [param('ns3::Ipv4Address', 'destination'), param('uint32_t&', 'ifIndex')], is_const=True) + cls.add_method('GetIfIndexForDestination', + 'bool', + [param('ns3::Ipv4Address', 'destination'), param('uint32_t&', 'ifIndex')], + is_const=True) ## ipv4-l3-protocol.h: uint16_t ns3::Ipv4L3Protocol::GetMtu(uint32_t i) const [member function] - cls.add_method('GetMtu', 'uint16_t', [param('uint32_t', 'i')], is_const=True) + cls.add_method('GetMtu', + 'uint16_t', + [param('uint32_t', 'i')], + is_const=True) ## ipv4-l3-protocol.h: bool ns3::Ipv4L3Protocol::IsUp(uint32_t i) const [member function] - cls.add_method('IsUp', 'bool', [param('uint32_t', 'i')], is_const=True) + cls.add_method('IsUp', + 'bool', + [param('uint32_t', 'i')], + is_const=True) ## ipv4-l3-protocol.h: void ns3::Ipv4L3Protocol::SetUp(uint32_t i) [member function] - cls.add_method('SetUp', 'void', [param('uint32_t', 'i')]) + cls.add_method('SetUp', + 'void', + [param('uint32_t', 'i')]) ## ipv4-l3-protocol.h: void ns3::Ipv4L3Protocol::SetDown(uint32_t i) [member function] - cls.add_method('SetDown', 'void', [param('uint32_t', 'i')]) + cls.add_method('SetDown', + 'void', + [param('uint32_t', 'i')]) ## ipv4-l3-protocol.h: void ns3::Ipv4L3Protocol::AddRoutingProtocol(ns3::Ptr routingProtocol, int priority) [member function] - cls.add_method('AddRoutingProtocol', 'void', [param('ns3::Ptr< ns3::Ipv4RoutingProtocol >', 'routingProtocol'), param('int', 'priority')]) + cls.add_method('AddRoutingProtocol', + 'void', + [param('ns3::Ptr< ns3::Ipv4RoutingProtocol >', 'routingProtocol'), param('int', 'priority')]) ## ipv4-l3-protocol.h: void ns3::Ipv4L3Protocol::DoDispose() [member function] - cls.add_method('DoDispose', 'void', [], visibility='protected', is_virtual=True) + cls.add_method('DoDispose', + 'void', + [], + visibility='protected', is_virtual=True) return def register_functions(root_module): module = root_module ## internet-stack.h: extern void ns3::AddInternetStack(ns3::Ptr node) [free function] - module.add_function('AddInternetStack', 'void', [param('ns3::Ptr< ns3::Node >', 'node')]) + module.add_function('AddInternetStack', + 'void', + [param('ns3::Ptr< ns3::Node >', 'node')]) register_functions_ns3_internal(module.get_submodule('internal'), root_module) register_functions_ns3_TimeStepPrecision(module.get_submodule('TimeStepPrecision'), root_module) register_functions_ns3_Config(module.get_submodule('Config'), root_module) diff --git a/bindings/python/ns3_module_mobility.py b/bindings/python/ns3_module_mobility.py index 470560ba9..812594415 100644 --- a/bindings/python/ns3_module_mobility.py +++ b/bindings/python/ns3_module_mobility.py @@ -1,4 +1,4 @@ -from pybindgen import Module, FileCodeSink, write_preamble, param, retval +from pybindgen import Module, FileCodeSink, param, retval, cppclass def register_types(module): root_module = module.get_root() @@ -112,36 +112,55 @@ def register_methods(root_module): def register_Ns3StaticSpeedHelper_methods(root_module, cls): ## static-speed-helper.h: ns3::StaticSpeedHelper::StaticSpeedHelper() [constructor] - cls.add_constructor([], visibility='public') + cls.add_constructor([]) ## static-speed-helper.h: ns3::StaticSpeedHelper::StaticSpeedHelper(ns3::Vector const & position) [constructor] - cls.add_constructor([param('ns3::Vector&', 'position', is_const=True)], visibility='public') + cls.add_constructor([param('ns3::Vector&', 'position', is_const=True)]) ## static-speed-helper.h: ns3::StaticSpeedHelper::StaticSpeedHelper(ns3::Vector const & position, ns3::Vector const & speed) [constructor] - cls.add_constructor([param('ns3::Vector&', 'position', is_const=True), param('ns3::Vector&', 'speed', is_const=True)], visibility='public') + cls.add_constructor([param('ns3::Vector&', 'position', is_const=True), param('ns3::Vector&', 'speed', is_const=True)]) ## static-speed-helper.h: void ns3::StaticSpeedHelper::InitializePosition(ns3::Vector const & position) [member function] - cls.add_method('InitializePosition', 'void', [param('ns3::Vector&', 'position', is_const=True)]) + cls.add_method('InitializePosition', + 'void', + [param('ns3::Vector&', 'position', is_const=True)]) ## static-speed-helper.h: void ns3::StaticSpeedHelper::Reset(ns3::Vector const & speed) [member function] - cls.add_method('Reset', 'void', [param('ns3::Vector&', 'speed', is_const=True)]) + cls.add_method('Reset', + 'void', + [param('ns3::Vector&', 'speed', is_const=True)]) ## static-speed-helper.h: ns3::Vector ns3::StaticSpeedHelper::GetCurrentPosition(ns3::Rectangle const & bounds) const [member function] - cls.add_method('GetCurrentPosition', 'ns3::Vector', [param('ns3::Rectangle&', 'bounds', is_const=True)], is_const=True) + cls.add_method('GetCurrentPosition', + 'ns3::Vector', + [param('ns3::Rectangle&', 'bounds', is_const=True)], + is_const=True) ## static-speed-helper.h: ns3::Vector ns3::StaticSpeedHelper::GetCurrentPosition() const [member function] - cls.add_method('GetCurrentPosition', 'ns3::Vector', [], is_const=True) + cls.add_method('GetCurrentPosition', + 'ns3::Vector', + [], + is_const=True) ## static-speed-helper.h: ns3::Vector ns3::StaticSpeedHelper::GetVelocity() const [member function] - cls.add_method('GetVelocity', 'ns3::Vector', [], is_const=True) + cls.add_method('GetVelocity', + 'ns3::Vector', + [], + is_const=True) ## static-speed-helper.h: void ns3::StaticSpeedHelper::SetSpeed(ns3::Vector const & speed) [member function] - cls.add_method('SetSpeed', 'void', [param('ns3::Vector&', 'speed', is_const=True)]) + cls.add_method('SetSpeed', + 'void', + [param('ns3::Vector&', 'speed', is_const=True)]) ## static-speed-helper.h: void ns3::StaticSpeedHelper::Pause() [member function] - cls.add_method('Pause', 'void', []) + cls.add_method('Pause', + 'void', + []) ## static-speed-helper.h: void ns3::StaticSpeedHelper::Unpause() [member function] - cls.add_method('Unpause', 'void', []) + cls.add_method('Unpause', + 'void', + []) return def register_Ns3Vector_methods(root_module, cls): ## vector.h: ns3::Vector::Vector(ns3::Vector const & arg0) [copy constructor] - cls.add_constructor([param('ns3::Vector&', 'arg0', is_const=True)], visibility='public') + cls.add_constructor([param('ns3::Vector&', 'arg0', is_const=True)]) ## vector.h: ns3::Vector::Vector(double _x, double _y, double _z) [constructor] - cls.add_constructor([param('double', '_x'), param('double', '_y'), param('double', '_z')], visibility='public') + cls.add_constructor([param('double', '_x'), param('double', '_y'), param('double', '_z')]) ## vector.h: ns3::Vector::Vector() [constructor] - cls.add_constructor([], visibility='public') + cls.add_constructor([]) ## vector.h: ns3::Vector::x [variable] cls.add_instance_attribute('x', 'double', is_const=False) ## vector.h: ns3::Vector::y [variable] @@ -161,17 +180,26 @@ def register_Ns3RectangleChecker_methods(root_module, cls): def register_Ns3Rectangle_methods(root_module, cls): ## rectangle.h: ns3::Rectangle::Rectangle(ns3::Rectangle const & arg0) [copy constructor] - cls.add_constructor([param('ns3::Rectangle&', 'arg0', is_const=True)], visibility='public') + cls.add_constructor([param('ns3::Rectangle&', 'arg0', is_const=True)]) ## rectangle.h: ns3::Rectangle::Rectangle(double _xMin, double _xMax, double _yMin, double _yMax) [constructor] - cls.add_constructor([param('double', '_xMin'), param('double', '_xMax'), param('double', '_yMin'), param('double', '_yMax')], visibility='public') + cls.add_constructor([param('double', '_xMin'), param('double', '_xMax'), param('double', '_yMin'), param('double', '_yMax')]) ## rectangle.h: ns3::Rectangle::Rectangle() [constructor] - cls.add_constructor([], visibility='public') + cls.add_constructor([]) ## rectangle.h: ns3::Vector ns3::Rectangle::CalculateIntersection(ns3::Vector const & current, ns3::Vector const & speed) const [member function] - cls.add_method('CalculateIntersection', 'ns3::Vector', [param('ns3::Vector&', 'current', is_const=True), param('ns3::Vector&', 'speed', is_const=True)], is_const=True) + cls.add_method('CalculateIntersection', + 'ns3::Vector', + [param('ns3::Vector&', 'current', is_const=True), param('ns3::Vector&', 'speed', is_const=True)], + is_const=True) ## rectangle.h: ns3::Rectangle::Side ns3::Rectangle::GetClosestSide(ns3::Vector const & position) const [member function] - cls.add_method('GetClosestSide', 'ns3::Rectangle::Side', [param('ns3::Vector&', 'position', is_const=True)], is_const=True) + cls.add_method('GetClosestSide', + 'ns3::Rectangle::Side', + [param('ns3::Vector&', 'position', is_const=True)], + is_const=True) ## rectangle.h: bool ns3::Rectangle::IsInside(ns3::Vector const & position) const [member function] - cls.add_method('IsInside', 'bool', [param('ns3::Vector&', 'position', is_const=True)], is_const=True) + cls.add_method('IsInside', + 'bool', + [param('ns3::Vector&', 'position', is_const=True)], + is_const=True) ## rectangle.h: ns3::Rectangle::xMax [variable] cls.add_instance_attribute('xMax', 'double', is_const=False) ## rectangle.h: ns3::Rectangle::xMin [variable] @@ -185,240 +213,460 @@ def register_Ns3Rectangle_methods(root_module, cls): def register_Ns3PositionAllocator_methods(root_module, cls): ## position-allocator.h: static ns3::TypeId ns3::PositionAllocator::GetTypeId() [member function] - cls.add_method('GetTypeId', 'ns3::TypeId', [], is_static=True) + cls.add_method('GetTypeId', + 'ns3::TypeId', + [], + is_static=True) ## position-allocator.h: ns3::PositionAllocator::PositionAllocator() [constructor] - cls.add_constructor([], visibility='public') + cls.add_constructor([]) ## position-allocator.h: ns3::Vector ns3::PositionAllocator::GetNext() const [member function] - cls.add_method('GetNext', 'ns3::Vector', [], is_pure_virtual=True, is_const=True, is_virtual=True) + cls.add_method('GetNext', + 'ns3::Vector', + [], + is_pure_virtual=True, is_const=True, is_virtual=True) return def register_Ns3ListPositionAllocator_methods(root_module, cls): ## position-allocator.h: static ns3::TypeId ns3::ListPositionAllocator::GetTypeId() [member function] - cls.add_method('GetTypeId', 'ns3::TypeId', [], is_static=True) + cls.add_method('GetTypeId', + 'ns3::TypeId', + [], + is_static=True) ## position-allocator.h: ns3::ListPositionAllocator::ListPositionAllocator() [constructor] - cls.add_constructor([], visibility='public') + cls.add_constructor([]) ## position-allocator.h: void ns3::ListPositionAllocator::Add(ns3::Vector v) [member function] - cls.add_method('Add', 'void', [param('ns3::Vector', 'v')]) + cls.add_method('Add', + 'void', + [param('ns3::Vector', 'v')]) ## position-allocator.h: ns3::Vector ns3::ListPositionAllocator::GetNext() const [member function] - cls.add_method('GetNext', 'ns3::Vector', [], is_const=True, is_virtual=True) + cls.add_method('GetNext', + 'ns3::Vector', + [], + is_const=True, is_virtual=True) return def register_Ns3RectangleValue_methods(root_module, cls): ## rectangle.h: ns3::RectangleValue::RectangleValue() [constructor] - cls.add_constructor([], visibility='public') + cls.add_constructor([]) ## rectangle.h: ns3::RectangleValue::RectangleValue(ns3::Rectangle const & value) [constructor] - cls.add_constructor([param('ns3::Rectangle&', 'value', is_const=True)], visibility='public') + cls.add_constructor([param('ns3::Rectangle&', 'value', is_const=True)]) ## rectangle.h: void ns3::RectangleValue::Set(ns3::Rectangle const & value) [member function] - cls.add_method('Set', 'void', [param('ns3::Rectangle&', 'value', is_const=True)]) + cls.add_method('Set', + 'void', + [param('ns3::Rectangle&', 'value', is_const=True)]) ## rectangle.h: ns3::Rectangle ns3::RectangleValue::Get() const [member function] - cls.add_method('Get', 'ns3::Rectangle', [], is_const=True) + cls.add_method('Get', + 'ns3::Rectangle', + [], + is_const=True) ## rectangle.h: ns3::Ptr ns3::RectangleValue::Copy() const [member function] - cls.add_method('Copy', 'ns3::Ptr< ns3::AttributeValue >', [], is_const=True, is_virtual=True) + cls.add_method('Copy', + 'ns3::Ptr< ns3::AttributeValue >', + [], + is_const=True, is_virtual=True) ## rectangle.h: std::string ns3::RectangleValue::SerializeToString(ns3::Ptr checker) const [member function] - cls.add_method('SerializeToString', 'std::string', [param('ns3::Ptr< ns3::AttributeChecker const >', 'checker')], is_const=True, is_virtual=True) + cls.add_method('SerializeToString', + 'std::string', + [param('ns3::Ptr< ns3::AttributeChecker const >', 'checker')], + is_const=True, is_virtual=True) ## rectangle.h: bool ns3::RectangleValue::DeserializeFromString(std::string value, ns3::Ptr checker) [member function] - cls.add_method('DeserializeFromString', 'bool', [param('std::string', 'value'), param('ns3::Ptr< ns3::AttributeChecker const >', 'checker')], is_virtual=True) + cls.add_method('DeserializeFromString', + 'bool', + [param('std::string', 'value'), param('ns3::Ptr< ns3::AttributeChecker const >', 'checker')], + is_virtual=True) return def register_Ns3RandomRectanglePositionAllocator_methods(root_module, cls): ## position-allocator.h: static ns3::TypeId ns3::RandomRectanglePositionAllocator::GetTypeId() [member function] - cls.add_method('GetTypeId', 'ns3::TypeId', [], is_static=True) + cls.add_method('GetTypeId', + 'ns3::TypeId', + [], + is_static=True) ## position-allocator.h: ns3::RandomRectanglePositionAllocator::RandomRectanglePositionAllocator() [constructor] - cls.add_constructor([], visibility='public') + cls.add_constructor([]) ## position-allocator.h: void ns3::RandomRectanglePositionAllocator::SetX(ns3::RandomVariable x) [member function] - cls.add_method('SetX', 'void', [param('ns3::RandomVariable', 'x')]) + cls.add_method('SetX', + 'void', + [param('ns3::RandomVariable', 'x')]) ## position-allocator.h: void ns3::RandomRectanglePositionAllocator::SetY(ns3::RandomVariable y) [member function] - cls.add_method('SetY', 'void', [param('ns3::RandomVariable', 'y')]) + cls.add_method('SetY', + 'void', + [param('ns3::RandomVariable', 'y')]) ## position-allocator.h: ns3::Vector ns3::RandomRectanglePositionAllocator::GetNext() const [member function] - cls.add_method('GetNext', 'ns3::Vector', [], is_const=True, is_virtual=True) + cls.add_method('GetNext', + 'ns3::Vector', + [], + is_const=True, is_virtual=True) return def register_Ns3VectorValue_methods(root_module, cls): ## vector.h: ns3::VectorValue::VectorValue() [constructor] - cls.add_constructor([], visibility='public') + cls.add_constructor([]) ## vector.h: ns3::VectorValue::VectorValue(ns3::Vector const & value) [constructor] - cls.add_constructor([param('ns3::Vector&', 'value', is_const=True)], visibility='public') + cls.add_constructor([param('ns3::Vector&', 'value', is_const=True)]) ## vector.h: void ns3::VectorValue::Set(ns3::Vector const & value) [member function] - cls.add_method('Set', 'void', [param('ns3::Vector&', 'value', is_const=True)]) + cls.add_method('Set', + 'void', + [param('ns3::Vector&', 'value', is_const=True)]) ## vector.h: ns3::Vector ns3::VectorValue::Get() const [member function] - cls.add_method('Get', 'ns3::Vector', [], is_const=True) + cls.add_method('Get', + 'ns3::Vector', + [], + is_const=True) ## vector.h: ns3::Ptr ns3::VectorValue::Copy() const [member function] - cls.add_method('Copy', 'ns3::Ptr< ns3::AttributeValue >', [], is_const=True, is_virtual=True) + cls.add_method('Copy', + 'ns3::Ptr< ns3::AttributeValue >', + [], + is_const=True, is_virtual=True) ## vector.h: std::string ns3::VectorValue::SerializeToString(ns3::Ptr checker) const [member function] - cls.add_method('SerializeToString', 'std::string', [param('ns3::Ptr< ns3::AttributeChecker const >', 'checker')], is_const=True, is_virtual=True) + cls.add_method('SerializeToString', + 'std::string', + [param('ns3::Ptr< ns3::AttributeChecker const >', 'checker')], + is_const=True, is_virtual=True) ## vector.h: bool ns3::VectorValue::DeserializeFromString(std::string value, ns3::Ptr checker) [member function] - cls.add_method('DeserializeFromString', 'bool', [param('std::string', 'value'), param('ns3::Ptr< ns3::AttributeChecker const >', 'checker')], is_virtual=True) + cls.add_method('DeserializeFromString', + 'bool', + [param('std::string', 'value'), param('ns3::Ptr< ns3::AttributeChecker const >', 'checker')], + is_virtual=True) return def register_Ns3RandomDiscPositionAllocator_methods(root_module, cls): ## position-allocator.h: static ns3::TypeId ns3::RandomDiscPositionAllocator::GetTypeId() [member function] - cls.add_method('GetTypeId', 'ns3::TypeId', [], is_static=True) + cls.add_method('GetTypeId', + 'ns3::TypeId', + [], + is_static=True) ## position-allocator.h: ns3::RandomDiscPositionAllocator::RandomDiscPositionAllocator() [constructor] - cls.add_constructor([], visibility='public') + cls.add_constructor([]) ## position-allocator.h: void ns3::RandomDiscPositionAllocator::SetTheta(ns3::RandomVariable theta) [member function] - cls.add_method('SetTheta', 'void', [param('ns3::RandomVariable', 'theta')]) + cls.add_method('SetTheta', + 'void', + [param('ns3::RandomVariable', 'theta')]) ## position-allocator.h: void ns3::RandomDiscPositionAllocator::SetRho(ns3::RandomVariable rho) [member function] - cls.add_method('SetRho', 'void', [param('ns3::RandomVariable', 'rho')]) + cls.add_method('SetRho', + 'void', + [param('ns3::RandomVariable', 'rho')]) ## position-allocator.h: void ns3::RandomDiscPositionAllocator::SetX(double x) [member function] - cls.add_method('SetX', 'void', [param('double', 'x')]) + cls.add_method('SetX', + 'void', + [param('double', 'x')]) ## position-allocator.h: void ns3::RandomDiscPositionAllocator::SetY(double y) [member function] - cls.add_method('SetY', 'void', [param('double', 'y')]) + cls.add_method('SetY', + 'void', + [param('double', 'y')]) ## position-allocator.h: ns3::Vector ns3::RandomDiscPositionAllocator::GetNext() const [member function] - cls.add_method('GetNext', 'ns3::Vector', [], is_const=True, is_virtual=True) + cls.add_method('GetNext', + 'ns3::Vector', + [], + is_const=True, is_virtual=True) return def register_Ns3MobilityModel_methods(root_module, cls): ## mobility-model.h: static ns3::TypeId ns3::MobilityModel::GetTypeId() [member function] - cls.add_method('GetTypeId', 'ns3::TypeId', [], is_static=True) + cls.add_method('GetTypeId', + 'ns3::TypeId', + [], + is_static=True) ## mobility-model.h: ns3::MobilityModel::MobilityModel() [constructor] - cls.add_constructor([], visibility='public') + cls.add_constructor([]) ## mobility-model.h: ns3::Vector ns3::MobilityModel::GetPosition() const [member function] - cls.add_method('GetPosition', 'ns3::Vector', [], is_const=True) + cls.add_method('GetPosition', + 'ns3::Vector', + [], + is_const=True) ## mobility-model.h: void ns3::MobilityModel::SetPosition(ns3::Vector const & position) [member function] - cls.add_method('SetPosition', 'void', [param('ns3::Vector&', 'position', is_const=True)]) + cls.add_method('SetPosition', + 'void', + [param('ns3::Vector&', 'position', is_const=True)]) ## mobility-model.h: ns3::Vector ns3::MobilityModel::GetVelocity() const [member function] - cls.add_method('GetVelocity', 'ns3::Vector', [], is_const=True) + cls.add_method('GetVelocity', + 'ns3::Vector', + [], + is_const=True) ## mobility-model.h: double ns3::MobilityModel::GetDistanceFrom(ns3::Ptr position) const [member function] - cls.add_method('GetDistanceFrom', 'double', [param('ns3::Ptr< const ns3::MobilityModel >', 'position')], is_const=True) + cls.add_method('GetDistanceFrom', + 'double', + [param('ns3::Ptr< const ns3::MobilityModel >', 'position')], + is_const=True) ## mobility-model.h: void ns3::MobilityModel::NotifyCourseChange() const [member function] - cls.add_method('NotifyCourseChange', 'void', [], is_const=True, visibility='protected') + cls.add_method('NotifyCourseChange', + 'void', + [], + is_const=True, visibility='protected') ## mobility-model.h: ns3::Vector ns3::MobilityModel::DoGetPosition() const [member function] - cls.add_method('DoGetPosition', 'ns3::Vector', [], is_pure_virtual=True, is_const=True, visibility='private', is_virtual=True) + cls.add_method('DoGetPosition', + 'ns3::Vector', + [], + is_pure_virtual=True, is_const=True, visibility='private', is_virtual=True) ## mobility-model.h: void ns3::MobilityModel::DoSetPosition(ns3::Vector const & position) [member function] - cls.add_method('DoSetPosition', 'void', [param('ns3::Vector&', 'position', is_const=True)], is_pure_virtual=True, visibility='private', is_virtual=True) + cls.add_method('DoSetPosition', + 'void', + [param('ns3::Vector&', 'position', is_const=True)], + is_pure_virtual=True, visibility='private', is_virtual=True) ## mobility-model.h: ns3::Vector ns3::MobilityModel::DoGetVelocity() const [member function] - cls.add_method('DoGetVelocity', 'ns3::Vector', [], is_pure_virtual=True, is_const=True, visibility='private', is_virtual=True) + cls.add_method('DoGetVelocity', + 'ns3::Vector', + [], + is_pure_virtual=True, is_const=True, visibility='private', is_virtual=True) return def register_Ns3RandomDirection2dMobilityModel_methods(root_module, cls): ## random-direction-2d-mobility-model.h: static ns3::TypeId ns3::RandomDirection2dMobilityModel::GetTypeId() [member function] - cls.add_method('GetTypeId', 'ns3::TypeId', [], is_static=True) + cls.add_method('GetTypeId', + 'ns3::TypeId', + [], + is_static=True) ## random-direction-2d-mobility-model.h: ns3::RandomDirection2dMobilityModel::RandomDirection2dMobilityModel() [constructor] - cls.add_constructor([], visibility='public') + cls.add_constructor([]) ## random-direction-2d-mobility-model.h: void ns3::RandomDirection2dMobilityModel::DoDispose() [member function] - cls.add_method('DoDispose', 'void', [], visibility='private', is_virtual=True) + cls.add_method('DoDispose', + 'void', + [], + visibility='private', is_virtual=True) ## random-direction-2d-mobility-model.h: ns3::Vector ns3::RandomDirection2dMobilityModel::DoGetPosition() const [member function] - cls.add_method('DoGetPosition', 'ns3::Vector', [], is_const=True, visibility='private', is_virtual=True) + cls.add_method('DoGetPosition', + 'ns3::Vector', + [], + is_const=True, visibility='private', is_virtual=True) ## random-direction-2d-mobility-model.h: void ns3::RandomDirection2dMobilityModel::DoSetPosition(ns3::Vector const & position) [member function] - cls.add_method('DoSetPosition', 'void', [param('ns3::Vector&', 'position', is_const=True)], visibility='private', is_virtual=True) + cls.add_method('DoSetPosition', + 'void', + [param('ns3::Vector&', 'position', is_const=True)], + visibility='private', is_virtual=True) ## random-direction-2d-mobility-model.h: ns3::Vector ns3::RandomDirection2dMobilityModel::DoGetVelocity() const [member function] - cls.add_method('DoGetVelocity', 'ns3::Vector', [], is_const=True, visibility='private', is_virtual=True) + cls.add_method('DoGetVelocity', + 'ns3::Vector', + [], + is_const=True, visibility='private', is_virtual=True) return def register_Ns3GridPositionAllocator_methods(root_module, cls): ## position-allocator.h: static ns3::TypeId ns3::GridPositionAllocator::GetTypeId() [member function] - cls.add_method('GetTypeId', 'ns3::TypeId', [], is_static=True) + cls.add_method('GetTypeId', + 'ns3::TypeId', + [], + is_static=True) ## position-allocator.h: ns3::GridPositionAllocator::GridPositionAllocator() [constructor] - cls.add_constructor([], visibility='public') + cls.add_constructor([]) ## position-allocator.h: void ns3::GridPositionAllocator::SetMinX(double xMin) [member function] - cls.add_method('SetMinX', 'void', [param('double', 'xMin')]) + cls.add_method('SetMinX', + 'void', + [param('double', 'xMin')]) ## position-allocator.h: void ns3::GridPositionAllocator::SetMinY(double yMin) [member function] - cls.add_method('SetMinY', 'void', [param('double', 'yMin')]) + cls.add_method('SetMinY', + 'void', + [param('double', 'yMin')]) ## position-allocator.h: void ns3::GridPositionAllocator::SetDeltaX(double deltaX) [member function] - cls.add_method('SetDeltaX', 'void', [param('double', 'deltaX')]) + cls.add_method('SetDeltaX', + 'void', + [param('double', 'deltaX')]) ## position-allocator.h: void ns3::GridPositionAllocator::SetDeltaY(double deltaY) [member function] - cls.add_method('SetDeltaY', 'void', [param('double', 'deltaY')]) + cls.add_method('SetDeltaY', + 'void', + [param('double', 'deltaY')]) ## position-allocator.h: void ns3::GridPositionAllocator::SetN(uint32_t n) [member function] - cls.add_method('SetN', 'void', [param('uint32_t', 'n')]) + cls.add_method('SetN', + 'void', + [param('uint32_t', 'n')]) ## position-allocator.h: void ns3::GridPositionAllocator::SetLayoutType(ns3::GridPositionAllocator::LayoutType layoutType) [member function] - cls.add_method('SetLayoutType', 'void', [param('ns3::GridPositionAllocator::LayoutType', 'layoutType')]) + cls.add_method('SetLayoutType', + 'void', + [param('ns3::GridPositionAllocator::LayoutType', 'layoutType')]) ## position-allocator.h: double ns3::GridPositionAllocator::GetMinX() const [member function] - cls.add_method('GetMinX', 'double', [], is_const=True) + cls.add_method('GetMinX', + 'double', + [], + is_const=True) ## position-allocator.h: double ns3::GridPositionAllocator::GetMinY() const [member function] - cls.add_method('GetMinY', 'double', [], is_const=True) + cls.add_method('GetMinY', + 'double', + [], + is_const=True) ## position-allocator.h: double ns3::GridPositionAllocator::GetDeltaX() const [member function] - cls.add_method('GetDeltaX', 'double', [], is_const=True) + cls.add_method('GetDeltaX', + 'double', + [], + is_const=True) ## position-allocator.h: double ns3::GridPositionAllocator::GetDeltaY() const [member function] - cls.add_method('GetDeltaY', 'double', [], is_const=True) + cls.add_method('GetDeltaY', + 'double', + [], + is_const=True) ## position-allocator.h: uint32_t ns3::GridPositionAllocator::GetN() const [member function] - cls.add_method('GetN', 'uint32_t', [], is_const=True) + cls.add_method('GetN', + 'uint32_t', + [], + is_const=True) ## position-allocator.h: ns3::GridPositionAllocator::LayoutType ns3::GridPositionAllocator::GetLayoutType() const [member function] - cls.add_method('GetLayoutType', 'ns3::GridPositionAllocator::LayoutType', [], is_const=True) + cls.add_method('GetLayoutType', + 'ns3::GridPositionAllocator::LayoutType', + [], + is_const=True) ## position-allocator.h: ns3::Vector ns3::GridPositionAllocator::GetNext() const [member function] - cls.add_method('GetNext', 'ns3::Vector', [], is_const=True, is_virtual=True) + cls.add_method('GetNext', + 'ns3::Vector', + [], + is_const=True, is_virtual=True) return def register_Ns3RandomWaypointMobilityModel_methods(root_module, cls): ## random-waypoint-mobility-model.h: static ns3::TypeId ns3::RandomWaypointMobilityModel::GetTypeId() [member function] - cls.add_method('GetTypeId', 'ns3::TypeId', [], is_static=True) + cls.add_method('GetTypeId', + 'ns3::TypeId', + [], + is_static=True) ## random-waypoint-mobility-model.h: ns3::RandomWaypointMobilityModel::RandomWaypointMobilityModel() [constructor] - cls.add_constructor([], visibility='public') + cls.add_constructor([]) ## random-waypoint-mobility-model.h: ns3::Vector ns3::RandomWaypointMobilityModel::DoGetPosition() const [member function] - cls.add_method('DoGetPosition', 'ns3::Vector', [], is_const=True, visibility='private', is_virtual=True) + cls.add_method('DoGetPosition', + 'ns3::Vector', + [], + is_const=True, visibility='private', is_virtual=True) ## random-waypoint-mobility-model.h: void ns3::RandomWaypointMobilityModel::DoSetPosition(ns3::Vector const & position) [member function] - cls.add_method('DoSetPosition', 'void', [param('ns3::Vector&', 'position', is_const=True)], visibility='private', is_virtual=True) + cls.add_method('DoSetPosition', + 'void', + [param('ns3::Vector&', 'position', is_const=True)], + visibility='private', is_virtual=True) ## random-waypoint-mobility-model.h: ns3::Vector ns3::RandomWaypointMobilityModel::DoGetVelocity() const [member function] - cls.add_method('DoGetVelocity', 'ns3::Vector', [], is_const=True, visibility='private', is_virtual=True) + cls.add_method('DoGetVelocity', + 'ns3::Vector', + [], + is_const=True, visibility='private', is_virtual=True) return def register_Ns3RandomWalk2dMobilityModel_methods(root_module, cls): ## random-walk-2d-mobility-model.h: static ns3::TypeId ns3::RandomWalk2dMobilityModel::GetTypeId() [member function] - cls.add_method('GetTypeId', 'ns3::TypeId', [], is_static=True) + cls.add_method('GetTypeId', + 'ns3::TypeId', + [], + is_static=True) ## random-walk-2d-mobility-model.h: ns3::RandomWalk2dMobilityModel::RandomWalk2dMobilityModel() [constructor] - cls.add_constructor([], visibility='public') + cls.add_constructor([]) ## random-walk-2d-mobility-model.h: void ns3::RandomWalk2dMobilityModel::DoDispose() [member function] - cls.add_method('DoDispose', 'void', [], visibility='private', is_virtual=True) + cls.add_method('DoDispose', + 'void', + [], + visibility='private', is_virtual=True) ## random-walk-2d-mobility-model.h: ns3::Vector ns3::RandomWalk2dMobilityModel::DoGetPosition() const [member function] - cls.add_method('DoGetPosition', 'ns3::Vector', [], is_const=True, visibility='private', is_virtual=True) + cls.add_method('DoGetPosition', + 'ns3::Vector', + [], + is_const=True, visibility='private', is_virtual=True) ## random-walk-2d-mobility-model.h: void ns3::RandomWalk2dMobilityModel::DoSetPosition(ns3::Vector const & position) [member function] - cls.add_method('DoSetPosition', 'void', [param('ns3::Vector&', 'position', is_const=True)], visibility='private', is_virtual=True) + cls.add_method('DoSetPosition', + 'void', + [param('ns3::Vector&', 'position', is_const=True)], + visibility='private', is_virtual=True) ## random-walk-2d-mobility-model.h: ns3::Vector ns3::RandomWalk2dMobilityModel::DoGetVelocity() const [member function] - cls.add_method('DoGetVelocity', 'ns3::Vector', [], is_const=True, visibility='private', is_virtual=True) + cls.add_method('DoGetVelocity', + 'ns3::Vector', + [], + is_const=True, visibility='private', is_virtual=True) return def register_Ns3StaticSpeedMobilityModel_methods(root_module, cls): ## static-speed-mobility-model.h: static ns3::TypeId ns3::StaticSpeedMobilityModel::GetTypeId() [member function] - cls.add_method('GetTypeId', 'ns3::TypeId', [], is_static=True) + cls.add_method('GetTypeId', + 'ns3::TypeId', + [], + is_static=True) ## static-speed-mobility-model.h: ns3::StaticSpeedMobilityModel::StaticSpeedMobilityModel() [constructor] - cls.add_constructor([], visibility='public') + cls.add_constructor([]) ## static-speed-mobility-model.h: void ns3::StaticSpeedMobilityModel::SetSpeed(ns3::Vector const & speed) [member function] - cls.add_method('SetSpeed', 'void', [param('ns3::Vector&', 'speed', is_const=True)]) + cls.add_method('SetSpeed', + 'void', + [param('ns3::Vector&', 'speed', is_const=True)]) ## static-speed-mobility-model.h: ns3::Vector ns3::StaticSpeedMobilityModel::DoGetPosition() const [member function] - cls.add_method('DoGetPosition', 'ns3::Vector', [], is_const=True, visibility='private', is_virtual=True) + cls.add_method('DoGetPosition', + 'ns3::Vector', + [], + is_const=True, visibility='private', is_virtual=True) ## static-speed-mobility-model.h: void ns3::StaticSpeedMobilityModel::DoSetPosition(ns3::Vector const & position) [member function] - cls.add_method('DoSetPosition', 'void', [param('ns3::Vector&', 'position', is_const=True)], visibility='private', is_virtual=True) + cls.add_method('DoSetPosition', + 'void', + [param('ns3::Vector&', 'position', is_const=True)], + visibility='private', is_virtual=True) ## static-speed-mobility-model.h: ns3::Vector ns3::StaticSpeedMobilityModel::DoGetVelocity() const [member function] - cls.add_method('DoGetVelocity', 'ns3::Vector', [], is_const=True, visibility='private', is_virtual=True) + cls.add_method('DoGetVelocity', + 'ns3::Vector', + [], + is_const=True, visibility='private', is_virtual=True) return def register_Ns3HierarchicalMobilityModel_methods(root_module, cls): ## hierarchical-mobility-model.h: static ns3::TypeId ns3::HierarchicalMobilityModel::GetTypeId() [member function] - cls.add_method('GetTypeId', 'ns3::TypeId', [], is_static=True) + cls.add_method('GetTypeId', + 'ns3::TypeId', + [], + is_static=True) ## hierarchical-mobility-model.h: ns3::HierarchicalMobilityModel::HierarchicalMobilityModel() [constructor] - cls.add_constructor([], visibility='public') + cls.add_constructor([]) ## hierarchical-mobility-model.h: ns3::Ptr ns3::HierarchicalMobilityModel::GetChild() const [member function] - cls.add_method('GetChild', 'ns3::Ptr< ns3::MobilityModel >', [], is_const=True) + cls.add_method('GetChild', + 'ns3::Ptr< ns3::MobilityModel >', + [], + is_const=True) ## hierarchical-mobility-model.h: ns3::Ptr ns3::HierarchicalMobilityModel::GetParent() const [member function] - cls.add_method('GetParent', 'ns3::Ptr< ns3::MobilityModel >', [], is_const=True) + cls.add_method('GetParent', + 'ns3::Ptr< ns3::MobilityModel >', + [], + is_const=True) ## hierarchical-mobility-model.h: ns3::Vector ns3::HierarchicalMobilityModel::DoGetPosition() const [member function] - cls.add_method('DoGetPosition', 'ns3::Vector', [], is_const=True, visibility='private', is_virtual=True) + cls.add_method('DoGetPosition', + 'ns3::Vector', + [], + is_const=True, visibility='private', is_virtual=True) ## hierarchical-mobility-model.h: void ns3::HierarchicalMobilityModel::DoSetPosition(ns3::Vector const & position) [member function] - cls.add_method('DoSetPosition', 'void', [param('ns3::Vector&', 'position', is_const=True)], visibility='private', is_virtual=True) + cls.add_method('DoSetPosition', + 'void', + [param('ns3::Vector&', 'position', is_const=True)], + visibility='private', is_virtual=True) ## hierarchical-mobility-model.h: ns3::Vector ns3::HierarchicalMobilityModel::DoGetVelocity() const [member function] - cls.add_method('DoGetVelocity', 'ns3::Vector', [], is_const=True, visibility='private', is_virtual=True) + cls.add_method('DoGetVelocity', + 'ns3::Vector', + [], + is_const=True, visibility='private', is_virtual=True) return def register_Ns3StaticMobilityModel_methods(root_module, cls): ## static-mobility-model.h: static ns3::TypeId ns3::StaticMobilityModel::GetTypeId() [member function] - cls.add_method('GetTypeId', 'ns3::TypeId', [], is_static=True) + cls.add_method('GetTypeId', + 'ns3::TypeId', + [], + is_static=True) ## static-mobility-model.h: ns3::StaticMobilityModel::StaticMobilityModel() [constructor] - cls.add_constructor([], visibility='public') + cls.add_constructor([]) ## static-mobility-model.h: ns3::Vector ns3::StaticMobilityModel::DoGetPosition() const [member function] - cls.add_method('DoGetPosition', 'ns3::Vector', [], is_const=True, visibility='private', is_virtual=True) + cls.add_method('DoGetPosition', + 'ns3::Vector', + [], + is_const=True, visibility='private', is_virtual=True) ## static-mobility-model.h: void ns3::StaticMobilityModel::DoSetPosition(ns3::Vector const & position) [member function] - cls.add_method('DoSetPosition', 'void', [param('ns3::Vector&', 'position', is_const=True)], visibility='private', is_virtual=True) + cls.add_method('DoSetPosition', + 'void', + [param('ns3::Vector&', 'position', is_const=True)], + visibility='private', is_virtual=True) ## static-mobility-model.h: ns3::Vector ns3::StaticMobilityModel::DoGetVelocity() const [member function] - cls.add_method('DoGetVelocity', 'ns3::Vector', [], is_const=True, visibility='private', is_virtual=True) + cls.add_method('DoGetVelocity', + 'ns3::Vector', + [], + is_const=True, visibility='private', is_virtual=True) return def register_functions(root_module): module = root_module ## rectangle.h: extern ns3::Ptr ns3::MakeRectangleChecker() [free function] - module.add_function('MakeRectangleChecker', 'ns3::Ptr< ns3::AttributeChecker const >', []) + module.add_function('MakeRectangleChecker', + 'ns3::Ptr< ns3::AttributeChecker const >', + []) ## vector.h: extern double ns3::CalculateDistance(ns3::Vector const & a, ns3::Vector const & b) [free function] - module.add_function('CalculateDistance', 'double', [param('ns3::Vector&', 'a', is_const=True), param('ns3::Vector&', 'b', is_const=True)]) + module.add_function('CalculateDistance', + 'double', + [param('ns3::Vector&', 'a', is_const=True), param('ns3::Vector&', 'b', is_const=True)]) ## vector.h: extern ns3::Ptr ns3::MakeVectorChecker() [free function] - module.add_function('MakeVectorChecker', 'ns3::Ptr< ns3::AttributeChecker const >', []) + module.add_function('MakeVectorChecker', + 'ns3::Ptr< ns3::AttributeChecker const >', + []) register_functions_ns3_internal(module.get_submodule('internal'), root_module) register_functions_ns3_TimeStepPrecision(module.get_submodule('TimeStepPrecision'), root_module) register_functions_ns3_Config(module.get_submodule('Config'), root_module) diff --git a/bindings/python/ns3_module_node.py b/bindings/python/ns3_module_node.py index 67f3e6055..2bfdbe97a 100644 --- a/bindings/python/ns3_module_node.py +++ b/bindings/python/ns3_module_node.py @@ -1,4 +1,4 @@ -from pybindgen import Module, FileCodeSink, write_preamble, param, retval +from pybindgen import Module, FileCodeSink, param, retval, cppclass def register_types(module): root_module = module.get_root() @@ -193,49 +193,97 @@ def register_methods(root_module): def register_Ns3NodeList_methods(root_module, cls): ## node-list.h: static uint32_t ns3::NodeList::Add(ns3::Ptr node) [member function] - cls.add_method('Add', 'uint32_t', [param('ns3::Ptr< ns3::Node >', 'node')], is_static=True) + cls.add_method('Add', + 'uint32_t', + [param('ns3::Ptr< ns3::Node >', 'node')], + is_static=True) ## node-list.h: static __gnu_cxx::__normal_iterator*,std::vector, std::allocator > > > ns3::NodeList::Begin() [member function] - cls.add_method('Begin', '__gnu_cxx::__normal_iterator< const ns3::Ptr< ns3::Node >, std::vector< ns3::Ptr< ns3::Node >, std::allocator< ns3::Ptr< ns3::Node > > > >', [], is_static=True) + cls.add_method('Begin', + '__gnu_cxx::__normal_iterator< const ns3::Ptr< ns3::Node >, std::vector< ns3::Ptr< ns3::Node >, std::allocator< ns3::Ptr< ns3::Node > > > >', + [], + is_static=True) ## node-list.h: static __gnu_cxx::__normal_iterator*,std::vector, std::allocator > > > ns3::NodeList::End() [member function] - cls.add_method('End', '__gnu_cxx::__normal_iterator< const ns3::Ptr< ns3::Node >, std::vector< ns3::Ptr< ns3::Node >, std::allocator< ns3::Ptr< ns3::Node > > > >', [], is_static=True) + cls.add_method('End', + '__gnu_cxx::__normal_iterator< const ns3::Ptr< ns3::Node >, std::vector< ns3::Ptr< ns3::Node >, std::allocator< ns3::Ptr< ns3::Node > > > >', + [], + is_static=True) ## node-list.h: static ns3::Ptr ns3::NodeList::GetNode(uint32_t n) [member function] - cls.add_method('GetNode', 'ns3::Ptr< ns3::Node >', [param('uint32_t', 'n')], is_static=True) + cls.add_method('GetNode', + 'ns3::Ptr< ns3::Node >', + [param('uint32_t', 'n')], + is_static=True) ## node-list.h: static uint32_t ns3::NodeList::GetNNodes() [member function] - cls.add_method('GetNNodes', 'uint32_t', [], is_static=True) + cls.add_method('GetNNodes', + 'uint32_t', + [], + is_static=True) cls.add_constructor([]) return def register_Ns3Address_methods(root_module, cls): ## address.h: ns3::Address::Address() [constructor] - cls.add_constructor([], visibility='public') + cls.add_constructor([]) ## address.h: ns3::Address::Address(uint8_t type, uint8_t const * buffer, uint8_t len) [constructor] - cls.add_constructor([param('uint8_t', 'type'), param('uint8_t *', 'buffer', transfer_ownership=False, is_const=True), param('uint8_t', 'len')], visibility='public') + cls.add_constructor([param('uint8_t', 'type'), param('uint8_t *', 'buffer', transfer_ownership=False, is_const=True), param('uint8_t', 'len')]) ## address.h: ns3::Address::Address(ns3::Address const & address) [copy constructor] - cls.add_constructor([param('ns3::Address&', 'address', is_const=True)], visibility='public') + cls.add_constructor([param('ns3::Address&', 'address', is_const=True)]) ## address.h: bool ns3::Address::CheckCompatible(uint8_t type, uint8_t len) const [member function] - cls.add_method('CheckCompatible', 'bool', [param('uint8_t', 'type'), param('uint8_t', 'len')], is_const=True) + cls.add_method('CheckCompatible', + 'bool', + [param('uint8_t', 'type'), param('uint8_t', 'len')], + is_const=True) ## address.h: uint32_t ns3::Address::CopyAllFrom(uint8_t const * buffer, uint8_t len) [member function] - cls.add_method('CopyAllFrom', 'uint32_t', [param('uint8_t *', 'buffer', transfer_ownership=False, is_const=True), param('uint8_t', 'len')]) + cls.add_method('CopyAllFrom', + 'uint32_t', + [param('uint8_t *', 'buffer', transfer_ownership=False, is_const=True), param('uint8_t', 'len')]) ## address.h: uint32_t ns3::Address::CopyAllTo(uint8_t * buffer, uint8_t len) const [member function] - cls.add_method('CopyAllTo', 'uint32_t', [param('uint8_t *', 'buffer'), param('uint8_t', 'len')], is_const=True) + cls.add_method('CopyAllTo', + 'uint32_t', + [param('uint8_t *', 'buffer'), param('uint8_t', 'len')], + is_const=True) ## address.h: uint32_t ns3::Address::CopyFrom(uint8_t const * buffer, uint8_t len) [member function] - cls.add_method('CopyFrom', 'uint32_t', [param('uint8_t *', 'buffer', transfer_ownership=False, is_const=True), param('uint8_t', 'len')]) + cls.add_method('CopyFrom', + 'uint32_t', + [param('uint8_t *', 'buffer', transfer_ownership=False, is_const=True), param('uint8_t', 'len')]) ## address.h: uint32_t ns3::Address::CopyTo(uint8_t * buffer) const [member function] - cls.add_method('CopyTo', 'uint32_t', [param('uint8_t *', 'buffer')], is_const=True) + cls.add_method('CopyTo', + 'uint32_t', + [param('uint8_t *', 'buffer')], + is_const=True) ## address.h: void ns3::Address::Deserialize(ns3::TagBuffer buffer) [member function] - cls.add_method('Deserialize', 'void', [param('ns3::TagBuffer', 'buffer')]) + cls.add_method('Deserialize', + 'void', + [param('ns3::TagBuffer', 'buffer')]) ## address.h: uint8_t ns3::Address::GetLength() const [member function] - cls.add_method('GetLength', 'uint8_t', [], is_const=True) + cls.add_method('GetLength', + 'uint8_t', + [], + is_const=True) ## address.h: uint32_t ns3::Address::GetSerializedSize() const [member function] - cls.add_method('GetSerializedSize', 'uint32_t', [], is_const=True) + cls.add_method('GetSerializedSize', + 'uint32_t', + [], + is_const=True) ## address.h: bool ns3::Address::IsInvalid() const [member function] - cls.add_method('IsInvalid', 'bool', [], is_const=True) + cls.add_method('IsInvalid', + 'bool', + [], + is_const=True) ## address.h: bool ns3::Address::IsMatchingType(uint8_t type) const [member function] - cls.add_method('IsMatchingType', 'bool', [param('uint8_t', 'type')], is_const=True) + cls.add_method('IsMatchingType', + 'bool', + [param('uint8_t', 'type')], + is_const=True) ## address.h: static uint8_t ns3::Address::Register() [member function] - cls.add_method('Register', 'uint8_t', [], is_static=True) + cls.add_method('Register', + 'uint8_t', + [], + is_static=True) ## address.h: void ns3::Address::Serialize(ns3::TagBuffer buffer) const [member function] - cls.add_method('Serialize', 'void', [param('ns3::TagBuffer', 'buffer')], is_const=True) + cls.add_method('Serialize', + 'void', + [param('ns3::TagBuffer', 'buffer')], + is_const=True) cls.add_output_stream_operator() return @@ -245,69 +293,133 @@ def register_Ns3Ipv4AddressChecker_methods(root_module, cls): def register_Ns3Mac48Address_methods(root_module, cls): ## mac48-address.h: ns3::Mac48Address::Mac48Address(ns3::Mac48Address const & arg0) [copy constructor] - cls.add_constructor([param('ns3::Mac48Address&', 'arg0', is_const=True)], visibility='public') + cls.add_constructor([param('ns3::Mac48Address&', 'arg0', is_const=True)]) ## mac48-address.h: ns3::Mac48Address::Mac48Address() [constructor] - cls.add_constructor([], visibility='public') + cls.add_constructor([]) ## mac48-address.h: ns3::Mac48Address::Mac48Address(char const * str) [constructor] - cls.add_constructor([param('char *', 'str', transfer_ownership=False, is_const=True)], visibility='public') + cls.add_constructor([param('char *', 'str', transfer_ownership=False, is_const=True)]) ## mac48-address.h: static ns3::Mac48Address ns3::Mac48Address::Allocate() [member function] - cls.add_method('Allocate', 'ns3::Mac48Address', [], is_static=True) + cls.add_method('Allocate', + 'ns3::Mac48Address', + [], + is_static=True) ## mac48-address.h: static ns3::Mac48Address ns3::Mac48Address::ConvertFrom(ns3::Address const & address) [member function] - cls.add_method('ConvertFrom', 'ns3::Mac48Address', [param('ns3::Address&', 'address', is_const=True)], is_static=True) + cls.add_method('ConvertFrom', + 'ns3::Mac48Address', + [param('ns3::Address&', 'address', is_const=True)], + is_static=True) ## mac48-address.h: void ns3::Mac48Address::CopyFrom(uint8_t const * buffer) [member function] - cls.add_method('CopyFrom', 'void', [param('uint8_t *', 'buffer', transfer_ownership=False, is_const=True)]) + cls.add_method('CopyFrom', + 'void', + [param('uint8_t *', 'buffer', transfer_ownership=False, is_const=True)]) ## mac48-address.h: void ns3::Mac48Address::CopyTo(uint8_t * buffer) const [member function] - cls.add_method('CopyTo', 'void', [param('uint8_t *', 'buffer')], is_const=True) + cls.add_method('CopyTo', + 'void', + [param('uint8_t *', 'buffer')], + is_const=True) ## mac48-address.h: static ns3::Mac48Address ns3::Mac48Address::GetBroadcast() [member function] - cls.add_method('GetBroadcast', 'ns3::Mac48Address', [], is_static=True) + cls.add_method('GetBroadcast', + 'ns3::Mac48Address', + [], + is_static=True) ## mac48-address.h: bool ns3::Mac48Address::IsBroadcast() const [member function] - cls.add_method('IsBroadcast', 'bool', [], is_const=True) + cls.add_method('IsBroadcast', + 'bool', + [], + is_const=True) ## mac48-address.h: static bool ns3::Mac48Address::IsMatchingType(ns3::Address const & address) [member function] - cls.add_method('IsMatchingType', 'bool', [param('ns3::Address&', 'address', is_const=True)], is_static=True) + cls.add_method('IsMatchingType', + 'bool', + [param('ns3::Address&', 'address', is_const=True)], + is_static=True) ## mac48-address.h: bool ns3::Mac48Address::IsMulticast() const [member function] - cls.add_method('IsMulticast', 'bool', [], is_const=True) + cls.add_method('IsMulticast', + 'bool', + [], + is_const=True) cls.add_output_stream_operator() return def register_Ns3Mac64Address_methods(root_module, cls): ## mac64-address.h: ns3::Mac64Address::Mac64Address(ns3::Mac64Address const & arg0) [copy constructor] - cls.add_constructor([param('ns3::Mac64Address&', 'arg0', is_const=True)], visibility='public') + cls.add_constructor([param('ns3::Mac64Address&', 'arg0', is_const=True)]) ## mac64-address.h: ns3::Mac64Address::Mac64Address() [constructor] - cls.add_constructor([], visibility='public') + cls.add_constructor([]) ## mac64-address.h: ns3::Mac64Address::Mac64Address(char const * str) [constructor] - cls.add_constructor([param('char *', 'str', transfer_ownership=False, is_const=True)], visibility='public') + cls.add_constructor([param('char *', 'str', transfer_ownership=False, is_const=True)]) ## mac64-address.h: static ns3::Mac64Address ns3::Mac64Address::Allocate() [member function] - cls.add_method('Allocate', 'ns3::Mac64Address', [], is_static=True) + cls.add_method('Allocate', + 'ns3::Mac64Address', + [], + is_static=True) ## mac64-address.h: static ns3::Mac64Address ns3::Mac64Address::ConvertFrom(ns3::Address const & address) [member function] - cls.add_method('ConvertFrom', 'ns3::Mac64Address', [param('ns3::Address&', 'address', is_const=True)], is_static=True) + cls.add_method('ConvertFrom', + 'ns3::Mac64Address', + [param('ns3::Address&', 'address', is_const=True)], + is_static=True) ## mac64-address.h: void ns3::Mac64Address::CopyFrom(uint8_t const * buffer) [member function] - cls.add_method('CopyFrom', 'void', [param('uint8_t *', 'buffer', transfer_ownership=False, is_const=True)]) + cls.add_method('CopyFrom', + 'void', + [param('uint8_t *', 'buffer', transfer_ownership=False, is_const=True)]) ## mac64-address.h: void ns3::Mac64Address::CopyTo(uint8_t * buffer) const [member function] - cls.add_method('CopyTo', 'void', [param('uint8_t *', 'buffer')], is_const=True) + cls.add_method('CopyTo', + 'void', + [param('uint8_t *', 'buffer')], + is_const=True) ## mac64-address.h: static bool ns3::Mac64Address::IsMatchingType(ns3::Address const & address) [member function] - cls.add_method('IsMatchingType', 'bool', [param('ns3::Address&', 'address', is_const=True)], is_static=True) + cls.add_method('IsMatchingType', + 'bool', + [param('ns3::Address&', 'address', is_const=True)], + is_static=True) cls.add_output_stream_operator() return def register_Ns3Ipv4AddressGenerator_methods(root_module, cls): ## ipv4-address-generator.h: static void ns3::Ipv4AddressGenerator::Init(ns3::Ipv4Address const net, ns3::Ipv4Mask const mask, ns3::Ipv4Address const addr="0.0.0.1") [member function] - cls.add_method('Init', 'void', [param('ns3::Ipv4Address', 'net', is_const=True), param('ns3::Ipv4Mask', 'mask', is_const=True), param('ns3::Ipv4Address', 'addr', default_value='"0.0.0.1"', is_const=True)], is_static=True) + cls.add_method('Init', + 'void', + [param('ns3::Ipv4Address', 'net', is_const=True), param('ns3::Ipv4Mask', 'mask', is_const=True), param('ns3::Ipv4Address', 'addr', default_value='"0.0.0.1"', is_const=True)], + is_static=True) ## ipv4-address-generator.h: static ns3::Ipv4Address ns3::Ipv4AddressGenerator::NextNetwork(ns3::Ipv4Mask const mask) [member function] - cls.add_method('NextNetwork', 'ns3::Ipv4Address', [param('ns3::Ipv4Mask', 'mask', is_const=True)], is_static=True) + cls.add_method('NextNetwork', + 'ns3::Ipv4Address', + [param('ns3::Ipv4Mask', 'mask', is_const=True)], + is_static=True) ## ipv4-address-generator.h: static ns3::Ipv4Address ns3::Ipv4AddressGenerator::GetNetwork(ns3::Ipv4Mask const mask) [member function] - cls.add_method('GetNetwork', 'ns3::Ipv4Address', [param('ns3::Ipv4Mask', 'mask', is_const=True)], is_static=True) + cls.add_method('GetNetwork', + 'ns3::Ipv4Address', + [param('ns3::Ipv4Mask', 'mask', is_const=True)], + is_static=True) ## ipv4-address-generator.h: static void ns3::Ipv4AddressGenerator::InitAddress(ns3::Ipv4Address const addr, ns3::Ipv4Mask const mask) [member function] - cls.add_method('InitAddress', 'void', [param('ns3::Ipv4Address', 'addr', is_const=True), param('ns3::Ipv4Mask', 'mask', is_const=True)], is_static=True) + cls.add_method('InitAddress', + 'void', + [param('ns3::Ipv4Address', 'addr', is_const=True), param('ns3::Ipv4Mask', 'mask', is_const=True)], + is_static=True) ## ipv4-address-generator.h: static ns3::Ipv4Address ns3::Ipv4AddressGenerator::NextAddress(ns3::Ipv4Mask const mask) [member function] - cls.add_method('NextAddress', 'ns3::Ipv4Address', [param('ns3::Ipv4Mask', 'mask', is_const=True)], is_static=True) + cls.add_method('NextAddress', + 'ns3::Ipv4Address', + [param('ns3::Ipv4Mask', 'mask', is_const=True)], + is_static=True) ## ipv4-address-generator.h: static ns3::Ipv4Address ns3::Ipv4AddressGenerator::GetAddress(ns3::Ipv4Mask const mask) [member function] - cls.add_method('GetAddress', 'ns3::Ipv4Address', [param('ns3::Ipv4Mask', 'mask', is_const=True)], is_static=True) + cls.add_method('GetAddress', + 'ns3::Ipv4Address', + [param('ns3::Ipv4Mask', 'mask', is_const=True)], + is_static=True) ## ipv4-address-generator.h: static void ns3::Ipv4AddressGenerator::Reset() [member function] - cls.add_method('Reset', 'void', [], is_static=True) + cls.add_method('Reset', + 'void', + [], + is_static=True) ## ipv4-address-generator.h: static bool ns3::Ipv4AddressGenerator::AddAllocated(ns3::Ipv4Address const addr) [member function] - cls.add_method('AddAllocated', 'bool', [param('ns3::Ipv4Address', 'addr', is_const=True)], is_static=True) + cls.add_method('AddAllocated', + 'bool', + [param('ns3::Ipv4Address', 'addr', is_const=True)], + is_static=True) ## ipv4-address-generator.h: static void ns3::Ipv4AddressGenerator::TestMode() [member function] - cls.add_method('TestMode', 'void', [], is_static=True) + cls.add_method('TestMode', + 'void', + [], + is_static=True) cls.add_constructor([]) return @@ -321,63 +433,126 @@ def register_Ns3Ipv4MaskChecker_methods(root_module, cls): def register_Ns3Ipv4Route_methods(root_module, cls): ## ipv4-route.h: ns3::Ipv4Route::Ipv4Route() [constructor] - cls.add_constructor([], visibility='public') + cls.add_constructor([]) ## ipv4-route.h: ns3::Ipv4Route::Ipv4Route(ns3::Ipv4Route const & route) [copy constructor] - cls.add_constructor([param('ns3::Ipv4Route&', 'route', is_const=True)], visibility='public') + cls.add_constructor([param('ns3::Ipv4Route&', 'route', is_const=True)]) ## ipv4-route.h: ns3::Ipv4Route::Ipv4Route(ns3::Ipv4Route const * route) [constructor] - cls.add_constructor([param('ns3::Ipv4Route *', 'route', transfer_ownership=False, is_const=True)], visibility='public') + cls.add_constructor([param('ns3::Ipv4Route *', 'route', transfer_ownership=False, is_const=True)]) ## ipv4-route.h: static ns3::Ipv4Route ns3::Ipv4Route::CreateDefaultRoute(ns3::Ipv4Address nextHop, uint32_t interface) [member function] - cls.add_method('CreateDefaultRoute', 'ns3::Ipv4Route', [param('ns3::Ipv4Address', 'nextHop'), param('uint32_t', 'interface')], is_static=True) + cls.add_method('CreateDefaultRoute', + 'ns3::Ipv4Route', + [param('ns3::Ipv4Address', 'nextHop'), param('uint32_t', 'interface')], + is_static=True) ## ipv4-route.h: static ns3::Ipv4Route ns3::Ipv4Route::CreateHostRouteTo(ns3::Ipv4Address dest, ns3::Ipv4Address nextHop, uint32_t interface) [member function] - cls.add_method('CreateHostRouteTo', 'ns3::Ipv4Route', [param('ns3::Ipv4Address', 'dest'), param('ns3::Ipv4Address', 'nextHop'), param('uint32_t', 'interface')], is_static=True) + cls.add_method('CreateHostRouteTo', + 'ns3::Ipv4Route', + [param('ns3::Ipv4Address', 'dest'), param('ns3::Ipv4Address', 'nextHop'), param('uint32_t', 'interface')], + is_static=True) ## ipv4-route.h: static ns3::Ipv4Route ns3::Ipv4Route::CreateHostRouteTo(ns3::Ipv4Address dest, uint32_t interface) [member function] - cls.add_method('CreateHostRouteTo', 'ns3::Ipv4Route', [param('ns3::Ipv4Address', 'dest'), param('uint32_t', 'interface')], is_static=True) + cls.add_method('CreateHostRouteTo', + 'ns3::Ipv4Route', + [param('ns3::Ipv4Address', 'dest'), param('uint32_t', 'interface')], + is_static=True) ## ipv4-route.h: static ns3::Ipv4Route ns3::Ipv4Route::CreateNetworkRouteTo(ns3::Ipv4Address network, ns3::Ipv4Mask networkMask, ns3::Ipv4Address nextHop, uint32_t interface) [member function] - cls.add_method('CreateNetworkRouteTo', 'ns3::Ipv4Route', [param('ns3::Ipv4Address', 'network'), param('ns3::Ipv4Mask', 'networkMask'), param('ns3::Ipv4Address', 'nextHop'), param('uint32_t', 'interface')], is_static=True) + cls.add_method('CreateNetworkRouteTo', + 'ns3::Ipv4Route', + [param('ns3::Ipv4Address', 'network'), param('ns3::Ipv4Mask', 'networkMask'), param('ns3::Ipv4Address', 'nextHop'), param('uint32_t', 'interface')], + is_static=True) ## ipv4-route.h: static ns3::Ipv4Route ns3::Ipv4Route::CreateNetworkRouteTo(ns3::Ipv4Address network, ns3::Ipv4Mask networkMask, uint32_t interface) [member function] - cls.add_method('CreateNetworkRouteTo', 'ns3::Ipv4Route', [param('ns3::Ipv4Address', 'network'), param('ns3::Ipv4Mask', 'networkMask'), param('uint32_t', 'interface')], is_static=True) + cls.add_method('CreateNetworkRouteTo', + 'ns3::Ipv4Route', + [param('ns3::Ipv4Address', 'network'), param('ns3::Ipv4Mask', 'networkMask'), param('uint32_t', 'interface')], + is_static=True) ## ipv4-route.h: ns3::Ipv4Address ns3::Ipv4Route::GetDest() const [member function] - cls.add_method('GetDest', 'ns3::Ipv4Address', [], is_const=True) + cls.add_method('GetDest', + 'ns3::Ipv4Address', + [], + is_const=True) ## ipv4-route.h: ns3::Ipv4Address ns3::Ipv4Route::GetDestNetwork() const [member function] - cls.add_method('GetDestNetwork', 'ns3::Ipv4Address', [], is_const=True) + cls.add_method('GetDestNetwork', + 'ns3::Ipv4Address', + [], + is_const=True) ## ipv4-route.h: ns3::Ipv4Mask ns3::Ipv4Route::GetDestNetworkMask() const [member function] - cls.add_method('GetDestNetworkMask', 'ns3::Ipv4Mask', [], is_const=True) + cls.add_method('GetDestNetworkMask', + 'ns3::Ipv4Mask', + [], + is_const=True) ## ipv4-route.h: ns3::Ipv4Address ns3::Ipv4Route::GetGateway() const [member function] - cls.add_method('GetGateway', 'ns3::Ipv4Address', [], is_const=True) + cls.add_method('GetGateway', + 'ns3::Ipv4Address', + [], + is_const=True) ## ipv4-route.h: uint32_t ns3::Ipv4Route::GetInterface() const [member function] - cls.add_method('GetInterface', 'uint32_t', [], is_const=True) + cls.add_method('GetInterface', + 'uint32_t', + [], + is_const=True) ## ipv4-route.h: bool ns3::Ipv4Route::IsDefault() const [member function] - cls.add_method('IsDefault', 'bool', [], is_const=True) + cls.add_method('IsDefault', + 'bool', + [], + is_const=True) ## ipv4-route.h: bool ns3::Ipv4Route::IsGateway() const [member function] - cls.add_method('IsGateway', 'bool', [], is_const=True) + cls.add_method('IsGateway', + 'bool', + [], + is_const=True) ## ipv4-route.h: bool ns3::Ipv4Route::IsHost() const [member function] - cls.add_method('IsHost', 'bool', [], is_const=True) + cls.add_method('IsHost', + 'bool', + [], + is_const=True) ## ipv4-route.h: bool ns3::Ipv4Route::IsNetwork() const [member function] - cls.add_method('IsNetwork', 'bool', [], is_const=True) + cls.add_method('IsNetwork', + 'bool', + [], + is_const=True) cls.add_output_stream_operator() return def register_Ns3Ipv4MulticastRoute_methods(root_module, cls): ## ipv4-route.h: ns3::Ipv4MulticastRoute::Ipv4MulticastRoute() [constructor] - cls.add_constructor([], visibility='public') + cls.add_constructor([]) ## ipv4-route.h: ns3::Ipv4MulticastRoute::Ipv4MulticastRoute(ns3::Ipv4MulticastRoute const & route) [copy constructor] - cls.add_constructor([param('ns3::Ipv4MulticastRoute&', 'route', is_const=True)], visibility='public') + cls.add_constructor([param('ns3::Ipv4MulticastRoute&', 'route', is_const=True)]) ## ipv4-route.h: ns3::Ipv4MulticastRoute::Ipv4MulticastRoute(ns3::Ipv4MulticastRoute const * route) [constructor] - cls.add_constructor([param('ns3::Ipv4MulticastRoute *', 'route', transfer_ownership=False, is_const=True)], visibility='public') + cls.add_constructor([param('ns3::Ipv4MulticastRoute *', 'route', transfer_ownership=False, is_const=True)]) ## ipv4-route.h: static ns3::Ipv4MulticastRoute ns3::Ipv4MulticastRoute::CreateMulticastRoute(ns3::Ipv4Address origin, ns3::Ipv4Address group, uint32_t inputInterface, std::vector > outputInterfaces) [member function] - cls.add_method('CreateMulticastRoute', 'ns3::Ipv4MulticastRoute', [param('ns3::Ipv4Address', 'origin'), param('ns3::Ipv4Address', 'group'), param('uint32_t', 'inputInterface'), param('std::vector< unsigned int, std::allocator< unsigned int > >', 'outputInterfaces')], is_static=True) + cls.add_method('CreateMulticastRoute', + 'ns3::Ipv4MulticastRoute', + [param('ns3::Ipv4Address', 'origin'), param('ns3::Ipv4Address', 'group'), param('uint32_t', 'inputInterface'), param('std::vector< unsigned int, std::allocator< unsigned int > >', 'outputInterfaces')], + is_static=True) ## ipv4-route.h: ns3::Ipv4Address ns3::Ipv4MulticastRoute::GetGroup() const [member function] - cls.add_method('GetGroup', 'ns3::Ipv4Address', [], is_const=True) + cls.add_method('GetGroup', + 'ns3::Ipv4Address', + [], + is_const=True) ## ipv4-route.h: uint32_t ns3::Ipv4MulticastRoute::GetInputInterface() const [member function] - cls.add_method('GetInputInterface', 'uint32_t', [], is_const=True) + cls.add_method('GetInputInterface', + 'uint32_t', + [], + is_const=True) ## ipv4-route.h: uint32_t ns3::Ipv4MulticastRoute::GetNOutputInterfaces() const [member function] - cls.add_method('GetNOutputInterfaces', 'uint32_t', [], is_const=True) + cls.add_method('GetNOutputInterfaces', + 'uint32_t', + [], + is_const=True) ## ipv4-route.h: ns3::Ipv4Address ns3::Ipv4MulticastRoute::GetOrigin() const [member function] - cls.add_method('GetOrigin', 'ns3::Ipv4Address', [], is_const=True) + cls.add_method('GetOrigin', + 'ns3::Ipv4Address', + [], + is_const=True) ## ipv4-route.h: uint32_t ns3::Ipv4MulticastRoute::GetOutputInterface(uint32_t n) const [member function] - cls.add_method('GetOutputInterface', 'uint32_t', [param('uint32_t', 'n')], is_const=True) + cls.add_method('GetOutputInterface', + 'uint32_t', + [param('uint32_t', 'n')], + is_const=True) ## ipv4-route.h: std::vector > ns3::Ipv4MulticastRoute::GetOutputInterfaces() const [member function] - cls.add_method('GetOutputInterfaces', 'std::vector< unsigned int, std::allocator< unsigned int > >', [], is_const=True) + cls.add_method('GetOutputInterfaces', + 'std::vector< unsigned int, std::allocator< unsigned int > >', + [], + is_const=True) cls.add_output_stream_operator() return @@ -387,933 +562,1961 @@ def register_Ns3AddressChecker_methods(root_module, cls): def register_Ns3PacketSocketAddress_methods(root_module, cls): ## packet-socket-address.h: ns3::PacketSocketAddress::PacketSocketAddress() [constructor] - cls.add_constructor([], visibility='public') + cls.add_constructor([]) ## packet-socket-address.h: void ns3::PacketSocketAddress::SetProtocol(uint16_t protocol) [member function] - cls.add_method('SetProtocol', 'void', [param('uint16_t', 'protocol')]) + cls.add_method('SetProtocol', + 'void', + [param('uint16_t', 'protocol')]) ## packet-socket-address.h: void ns3::PacketSocketAddress::SetAllDevices() [member function] - cls.add_method('SetAllDevices', 'void', []) + cls.add_method('SetAllDevices', + 'void', + []) ## packet-socket-address.h: void ns3::PacketSocketAddress::SetSingleDevice(uint32_t device) [member function] - cls.add_method('SetSingleDevice', 'void', [param('uint32_t', 'device')]) + cls.add_method('SetSingleDevice', + 'void', + [param('uint32_t', 'device')]) ## packet-socket-address.h: void ns3::PacketSocketAddress::SetPhysicalAddress(ns3::Address const address) [member function] - cls.add_method('SetPhysicalAddress', 'void', [param('ns3::Address', 'address', is_const=True)]) + cls.add_method('SetPhysicalAddress', + 'void', + [param('ns3::Address', 'address', is_const=True)]) ## packet-socket-address.h: uint16_t ns3::PacketSocketAddress::GetProtocol() const [member function] - cls.add_method('GetProtocol', 'uint16_t', [], is_const=True) + cls.add_method('GetProtocol', + 'uint16_t', + [], + is_const=True) ## packet-socket-address.h: uint32_t ns3::PacketSocketAddress::GetSingleDevice() const [member function] - cls.add_method('GetSingleDevice', 'uint32_t', [], is_const=True) + cls.add_method('GetSingleDevice', + 'uint32_t', + [], + is_const=True) ## packet-socket-address.h: bool ns3::PacketSocketAddress::IsSingleDevice() const [member function] - cls.add_method('IsSingleDevice', 'bool', [], is_const=True) + cls.add_method('IsSingleDevice', + 'bool', + [], + is_const=True) ## packet-socket-address.h: ns3::Address ns3::PacketSocketAddress::GetPhysicalAddress() const [member function] - cls.add_method('GetPhysicalAddress', 'ns3::Address', [], is_const=True) + cls.add_method('GetPhysicalAddress', + 'ns3::Address', + [], + is_const=True) ## packet-socket-address.h: static ns3::PacketSocketAddress ns3::PacketSocketAddress::ConvertFrom(ns3::Address const & address) [member function] - cls.add_method('ConvertFrom', 'ns3::PacketSocketAddress', [param('ns3::Address&', 'address', is_const=True)], is_static=True) + cls.add_method('ConvertFrom', + 'ns3::PacketSocketAddress', + [param('ns3::Address&', 'address', is_const=True)], + is_static=True) ## packet-socket-address.h: static bool ns3::PacketSocketAddress::IsMatchingType(ns3::Address const & address) [member function] - cls.add_method('IsMatchingType', 'bool', [param('ns3::Address&', 'address', is_const=True)], is_static=True) + cls.add_method('IsMatchingType', + 'bool', + [param('ns3::Address&', 'address', is_const=True)], + is_static=True) return def register_Ns3Ipv4Mask_methods(root_module, cls): ## ipv4-address.h: ns3::Ipv4Mask::Ipv4Mask(ns3::Ipv4Mask const & arg0) [copy constructor] - cls.add_constructor([param('ns3::Ipv4Mask&', 'arg0', is_const=True)], visibility='public') + cls.add_constructor([param('ns3::Ipv4Mask&', 'arg0', is_const=True)]) ## ipv4-address.h: ns3::Ipv4Mask::Ipv4Mask() [constructor] - cls.add_constructor([], visibility='public') + cls.add_constructor([]) ## ipv4-address.h: ns3::Ipv4Mask::Ipv4Mask(uint32_t mask) [constructor] - cls.add_constructor([param('uint32_t', 'mask')], visibility='public') + cls.add_constructor([param('uint32_t', 'mask')]) ## ipv4-address.h: ns3::Ipv4Mask::Ipv4Mask(char const * mask) [constructor] - cls.add_constructor([param('char *', 'mask', transfer_ownership=False, is_const=True)], visibility='public') + cls.add_constructor([param('char *', 'mask', transfer_ownership=False, is_const=True)]) ## ipv4-address.h: uint32_t ns3::Ipv4Mask::Get() const [member function] - cls.add_method('Get', 'uint32_t', [], is_const=True) + cls.add_method('Get', + 'uint32_t', + [], + is_const=True) ## ipv4-address.h: uint32_t ns3::Ipv4Mask::GetInverse() const [member function] - cls.add_method('GetInverse', 'uint32_t', [], is_const=True) + cls.add_method('GetInverse', + 'uint32_t', + [], + is_const=True) ## ipv4-address.h: static ns3::Ipv4Mask ns3::Ipv4Mask::GetLoopback() [member function] - cls.add_method('GetLoopback', 'ns3::Ipv4Mask', [], is_static=True) + cls.add_method('GetLoopback', + 'ns3::Ipv4Mask', + [], + is_static=True) ## ipv4-address.h: static ns3::Ipv4Mask ns3::Ipv4Mask::GetZero() [member function] - cls.add_method('GetZero', 'ns3::Ipv4Mask', [], is_static=True) + cls.add_method('GetZero', + 'ns3::Ipv4Mask', + [], + is_static=True) ## ipv4-address.h: bool ns3::Ipv4Mask::IsEqual(ns3::Ipv4Mask other) const [member function] - cls.add_method('IsEqual', 'bool', [param('ns3::Ipv4Mask', 'other')], is_const=True) + cls.add_method('IsEqual', + 'bool', + [param('ns3::Ipv4Mask', 'other')], + is_const=True) ## ipv4-address.h: bool ns3::Ipv4Mask::IsMatch(ns3::Ipv4Address a, ns3::Ipv4Address b) const [member function] - cls.add_method('IsMatch', 'bool', [param('ns3::Ipv4Address', 'a'), param('ns3::Ipv4Address', 'b')], is_const=True) + cls.add_method('IsMatch', + 'bool', + [param('ns3::Ipv4Address', 'a'), param('ns3::Ipv4Address', 'b')], + is_const=True) ## ipv4-address.h: void ns3::Ipv4Mask::Print(std::ostream & os) const [member function] - cls.add_method('Print', 'void', [param('std::ostream&', 'os')], is_const=True) + cls.add_method('Print', + 'void', + [param('std::ostream&', 'os')], + is_const=True) ## ipv4-address.h: void ns3::Ipv4Mask::Set(uint32_t mask) [member function] - cls.add_method('Set', 'void', [param('uint32_t', 'mask')]) + cls.add_method('Set', + 'void', + [param('uint32_t', 'mask')]) cls.add_output_stream_operator() return def register_Ns3Ipv4AddressValue_methods(root_module, cls): ## ipv4-address.h: ns3::Ipv4AddressValue::Ipv4AddressValue() [constructor] - cls.add_constructor([], visibility='public') + cls.add_constructor([]) ## ipv4-address.h: ns3::Ipv4AddressValue::Ipv4AddressValue(ns3::Ipv4Address const & value) [constructor] - cls.add_constructor([param('ns3::Ipv4Address&', 'value', is_const=True)], visibility='public') + cls.add_constructor([param('ns3::Ipv4Address&', 'value', is_const=True)]) ## ipv4-address.h: void ns3::Ipv4AddressValue::Set(ns3::Ipv4Address const & value) [member function] - cls.add_method('Set', 'void', [param('ns3::Ipv4Address&', 'value', is_const=True)]) + cls.add_method('Set', + 'void', + [param('ns3::Ipv4Address&', 'value', is_const=True)]) ## ipv4-address.h: ns3::Ipv4Address ns3::Ipv4AddressValue::Get() const [member function] - cls.add_method('Get', 'ns3::Ipv4Address', [], is_const=True) + cls.add_method('Get', + 'ns3::Ipv4Address', + [], + is_const=True) ## ipv4-address.h: ns3::Ptr ns3::Ipv4AddressValue::Copy() const [member function] - cls.add_method('Copy', 'ns3::Ptr< ns3::AttributeValue >', [], is_const=True, is_virtual=True) + cls.add_method('Copy', + 'ns3::Ptr< ns3::AttributeValue >', + [], + is_const=True, is_virtual=True) ## ipv4-address.h: std::string ns3::Ipv4AddressValue::SerializeToString(ns3::Ptr checker) const [member function] - cls.add_method('SerializeToString', 'std::string', [param('ns3::Ptr< ns3::AttributeChecker const >', 'checker')], is_const=True, is_virtual=True) + cls.add_method('SerializeToString', + 'std::string', + [param('ns3::Ptr< ns3::AttributeChecker const >', 'checker')], + is_const=True, is_virtual=True) ## ipv4-address.h: bool ns3::Ipv4AddressValue::DeserializeFromString(std::string value, ns3::Ptr checker) [member function] - cls.add_method('DeserializeFromString', 'bool', [param('std::string', 'value'), param('ns3::Ptr< ns3::AttributeChecker const >', 'checker')], is_virtual=True) + cls.add_method('DeserializeFromString', + 'bool', + [param('std::string', 'value'), param('ns3::Ptr< ns3::AttributeChecker const >', 'checker')], + is_virtual=True) return def register_Ns3Ipv4RoutingProtocol_methods(root_module, cls): ## ipv4.h: ns3::Ipv4RoutingProtocol::IF_INDEX_ANY [variable] cls.add_static_attribute('IF_INDEX_ANY', retval('uint32_t', is_const=True), is_const=True) ## ipv4.h: bool ns3::Ipv4RoutingProtocol::RequestRoute(uint32_t ifIndex, ns3::Ipv4Header const & ipHeader, ns3::Ptr packet, ns3::Callback,const ns3::Ipv4Header&,ns3::empty,ns3::empty> routeReply) [member function] - cls.add_method('RequestRoute', 'bool', [param('uint32_t', 'ifIndex'), param('ns3::Ipv4Header&', 'ipHeader', is_const=True), param('ns3::Ptr< ns3::Packet >', 'packet'), param('ns3::Callback< void, bool, const ns3::Ipv4Route&, ns3::Ptr< ns3::Packet >, const ns3::Ipv4Header&, ns3::empty, ns3::empty >', 'routeReply')], is_pure_virtual=True, is_virtual=True) + cls.add_method('RequestRoute', + 'bool', + [param('uint32_t', 'ifIndex'), param('ns3::Ipv4Header&', 'ipHeader', is_const=True), param('ns3::Ptr< ns3::Packet >', 'packet'), param('ns3::Callback< void, bool, const ns3::Ipv4Route&, ns3::Ptr< ns3::Packet >, const ns3::Ipv4Header&, ns3::empty, ns3::empty >', 'routeReply')], + is_pure_virtual=True, is_virtual=True) ## ipv4.h: bool ns3::Ipv4RoutingProtocol::RequestIfIndex(ns3::Ipv4Address destination, uint32_t & ifIndex) [member function] - cls.add_method('RequestIfIndex', 'bool', [param('ns3::Ipv4Address', 'destination'), param('uint32_t&', 'ifIndex')], is_pure_virtual=True, is_virtual=True) + cls.add_method('RequestIfIndex', + 'bool', + [param('ns3::Ipv4Address', 'destination'), param('uint32_t&', 'ifIndex')], + is_pure_virtual=True, is_virtual=True) cls.add_constructor([]) return def register_Ns3Mac48AddressValue_methods(root_module, cls): ## mac48-address.h: ns3::Mac48AddressValue::Mac48AddressValue() [constructor] - cls.add_constructor([], visibility='public') + cls.add_constructor([]) ## mac48-address.h: ns3::Mac48AddressValue::Mac48AddressValue(ns3::Mac48Address const & value) [constructor] - cls.add_constructor([param('ns3::Mac48Address&', 'value', is_const=True)], visibility='public') + cls.add_constructor([param('ns3::Mac48Address&', 'value', is_const=True)]) ## mac48-address.h: void ns3::Mac48AddressValue::Set(ns3::Mac48Address const & value) [member function] - cls.add_method('Set', 'void', [param('ns3::Mac48Address&', 'value', is_const=True)]) + cls.add_method('Set', + 'void', + [param('ns3::Mac48Address&', 'value', is_const=True)]) ## mac48-address.h: ns3::Mac48Address ns3::Mac48AddressValue::Get() const [member function] - cls.add_method('Get', 'ns3::Mac48Address', [], is_const=True) + cls.add_method('Get', + 'ns3::Mac48Address', + [], + is_const=True) ## mac48-address.h: ns3::Ptr ns3::Mac48AddressValue::Copy() const [member function] - cls.add_method('Copy', 'ns3::Ptr< ns3::AttributeValue >', [], is_const=True, is_virtual=True) + cls.add_method('Copy', + 'ns3::Ptr< ns3::AttributeValue >', + [], + is_const=True, is_virtual=True) ## mac48-address.h: std::string ns3::Mac48AddressValue::SerializeToString(ns3::Ptr checker) const [member function] - cls.add_method('SerializeToString', 'std::string', [param('ns3::Ptr< ns3::AttributeChecker const >', 'checker')], is_const=True, is_virtual=True) + cls.add_method('SerializeToString', + 'std::string', + [param('ns3::Ptr< ns3::AttributeChecker const >', 'checker')], + is_const=True, is_virtual=True) ## mac48-address.h: bool ns3::Mac48AddressValue::DeserializeFromString(std::string value, ns3::Ptr checker) [member function] - cls.add_method('DeserializeFromString', 'bool', [param('std::string', 'value'), param('ns3::Ptr< ns3::AttributeChecker const >', 'checker')], is_virtual=True) + cls.add_method('DeserializeFromString', + 'bool', + [param('std::string', 'value'), param('ns3::Ptr< ns3::AttributeChecker const >', 'checker')], + is_virtual=True) return def register_Ns3Ipv4MaskValue_methods(root_module, cls): ## ipv4-address.h: ns3::Ipv4MaskValue::Ipv4MaskValue() [constructor] - cls.add_constructor([], visibility='public') + cls.add_constructor([]) ## ipv4-address.h: ns3::Ipv4MaskValue::Ipv4MaskValue(ns3::Ipv4Mask const & value) [constructor] - cls.add_constructor([param('ns3::Ipv4Mask&', 'value', is_const=True)], visibility='public') + cls.add_constructor([param('ns3::Ipv4Mask&', 'value', is_const=True)]) ## ipv4-address.h: void ns3::Ipv4MaskValue::Set(ns3::Ipv4Mask const & value) [member function] - cls.add_method('Set', 'void', [param('ns3::Ipv4Mask&', 'value', is_const=True)]) + cls.add_method('Set', + 'void', + [param('ns3::Ipv4Mask&', 'value', is_const=True)]) ## ipv4-address.h: ns3::Ipv4Mask ns3::Ipv4MaskValue::Get() const [member function] - cls.add_method('Get', 'ns3::Ipv4Mask', [], is_const=True) + cls.add_method('Get', + 'ns3::Ipv4Mask', + [], + is_const=True) ## ipv4-address.h: ns3::Ptr ns3::Ipv4MaskValue::Copy() const [member function] - cls.add_method('Copy', 'ns3::Ptr< ns3::AttributeValue >', [], is_const=True, is_virtual=True) + cls.add_method('Copy', + 'ns3::Ptr< ns3::AttributeValue >', + [], + is_const=True, is_virtual=True) ## ipv4-address.h: std::string ns3::Ipv4MaskValue::SerializeToString(ns3::Ptr checker) const [member function] - cls.add_method('SerializeToString', 'std::string', [param('ns3::Ptr< ns3::AttributeChecker const >', 'checker')], is_const=True, is_virtual=True) + cls.add_method('SerializeToString', + 'std::string', + [param('ns3::Ptr< ns3::AttributeChecker const >', 'checker')], + is_const=True, is_virtual=True) ## ipv4-address.h: bool ns3::Ipv4MaskValue::DeserializeFromString(std::string value, ns3::Ptr checker) [member function] - cls.add_method('DeserializeFromString', 'bool', [param('std::string', 'value'), param('ns3::Ptr< ns3::AttributeChecker const >', 'checker')], is_virtual=True) + cls.add_method('DeserializeFromString', + 'bool', + [param('std::string', 'value'), param('ns3::Ptr< ns3::AttributeChecker const >', 'checker')], + is_virtual=True) return def register_Ns3SocketAddressTag_methods(root_module, cls): ## socket.h: ns3::SocketAddressTag::SocketAddressTag() [constructor] - cls.add_constructor([], visibility='public') + cls.add_constructor([]) ## socket.h: void ns3::SocketAddressTag::SetAddress(ns3::Address addr) [member function] - cls.add_method('SetAddress', 'void', [param('ns3::Address', 'addr')]) + cls.add_method('SetAddress', + 'void', + [param('ns3::Address', 'addr')]) ## socket.h: ns3::Address ns3::SocketAddressTag::GetAddress() const [member function] - cls.add_method('GetAddress', 'ns3::Address', [], is_const=True) + cls.add_method('GetAddress', + 'ns3::Address', + [], + is_const=True) ## socket.h: static ns3::TypeId ns3::SocketAddressTag::GetTypeId() [member function] - cls.add_method('GetTypeId', 'ns3::TypeId', [], is_static=True) + cls.add_method('GetTypeId', + 'ns3::TypeId', + [], + is_static=True) ## socket.h: ns3::TypeId ns3::SocketAddressTag::GetInstanceTypeId() const [member function] - cls.add_method('GetInstanceTypeId', 'ns3::TypeId', [], is_const=True, is_virtual=True) + cls.add_method('GetInstanceTypeId', + 'ns3::TypeId', + [], + is_const=True, is_virtual=True) ## socket.h: uint32_t ns3::SocketAddressTag::GetSerializedSize() const [member function] - cls.add_method('GetSerializedSize', 'uint32_t', [], is_const=True, is_virtual=True) + cls.add_method('GetSerializedSize', + 'uint32_t', + [], + is_const=True, is_virtual=True) ## socket.h: void ns3::SocketAddressTag::Serialize(ns3::TagBuffer i) const [member function] - cls.add_method('Serialize', 'void', [param('ns3::TagBuffer', 'i')], is_const=True, is_virtual=True) + cls.add_method('Serialize', + 'void', + [param('ns3::TagBuffer', 'i')], + is_const=True, is_virtual=True) ## socket.h: void ns3::SocketAddressTag::Deserialize(ns3::TagBuffer i) [member function] - cls.add_method('Deserialize', 'void', [param('ns3::TagBuffer', 'i')], is_virtual=True) + cls.add_method('Deserialize', + 'void', + [param('ns3::TagBuffer', 'i')], + is_virtual=True) ## socket.h: void ns3::SocketAddressTag::Print(std::ostream & os) const [member function] - cls.add_method('Print', 'void', [param('std::ostream&', 'os')], is_const=True, is_virtual=True) + cls.add_method('Print', + 'void', + [param('std::ostream&', 'os')], + is_const=True, is_virtual=True) return def register_Ns3InetSocketAddress_methods(root_module, cls): ## inet-socket-address.h: ns3::InetSocketAddress::InetSocketAddress(ns3::Ipv4Address ipv4, uint16_t port) [constructor] - cls.add_constructor([param('ns3::Ipv4Address', 'ipv4'), param('uint16_t', 'port')], visibility='public') + cls.add_constructor([param('ns3::Ipv4Address', 'ipv4'), param('uint16_t', 'port')]) ## inet-socket-address.h: ns3::InetSocketAddress::InetSocketAddress(ns3::Ipv4Address ipv4) [constructor] - cls.add_constructor([param('ns3::Ipv4Address', 'ipv4')], visibility='public') + cls.add_constructor([param('ns3::Ipv4Address', 'ipv4')]) ## inet-socket-address.h: ns3::InetSocketAddress::InetSocketAddress(uint16_t port) [constructor] - cls.add_constructor([param('uint16_t', 'port')], visibility='public') + cls.add_constructor([param('uint16_t', 'port')]) ## inet-socket-address.h: ns3::InetSocketAddress::InetSocketAddress(char const * ipv4, uint16_t port) [constructor] - cls.add_constructor([param('char *', 'ipv4', transfer_ownership=False, is_const=True), param('uint16_t', 'port')], visibility='public') + cls.add_constructor([param('char *', 'ipv4', transfer_ownership=False, is_const=True), param('uint16_t', 'port')]) ## inet-socket-address.h: ns3::InetSocketAddress::InetSocketAddress(char const * ipv4) [constructor] - cls.add_constructor([param('char *', 'ipv4', transfer_ownership=False, is_const=True)], visibility='public') + cls.add_constructor([param('char *', 'ipv4', transfer_ownership=False, is_const=True)]) ## inet-socket-address.h: uint16_t ns3::InetSocketAddress::GetPort() const [member function] - cls.add_method('GetPort', 'uint16_t', [], is_const=True) + cls.add_method('GetPort', + 'uint16_t', + [], + is_const=True) ## inet-socket-address.h: ns3::Ipv4Address ns3::InetSocketAddress::GetIpv4() const [member function] - cls.add_method('GetIpv4', 'ns3::Ipv4Address', [], is_const=True) + cls.add_method('GetIpv4', + 'ns3::Ipv4Address', + [], + is_const=True) ## inet-socket-address.h: void ns3::InetSocketAddress::SetPort(uint16_t port) [member function] - cls.add_method('SetPort', 'void', [param('uint16_t', 'port')]) + cls.add_method('SetPort', + 'void', + [param('uint16_t', 'port')]) ## inet-socket-address.h: void ns3::InetSocketAddress::SetIpv4(ns3::Ipv4Address address) [member function] - cls.add_method('SetIpv4', 'void', [param('ns3::Ipv4Address', 'address')]) + cls.add_method('SetIpv4', + 'void', + [param('ns3::Ipv4Address', 'address')]) ## inet-socket-address.h: static bool ns3::InetSocketAddress::IsMatchingType(ns3::Address const & address) [member function] - cls.add_method('IsMatchingType', 'bool', [param('ns3::Address&', 'address', is_const=True)], is_static=True) + cls.add_method('IsMatchingType', + 'bool', + [param('ns3::Address&', 'address', is_const=True)], + is_static=True) ## inet-socket-address.h: static ns3::InetSocketAddress ns3::InetSocketAddress::ConvertFrom(ns3::Address const & address) [member function] - cls.add_method('ConvertFrom', 'ns3::InetSocketAddress', [param('ns3::Address&', 'address', is_const=True)], is_static=True) + cls.add_method('ConvertFrom', + 'ns3::InetSocketAddress', + [param('ns3::Address&', 'address', is_const=True)], + is_static=True) return def register_Ns3Ipv4Address_methods(root_module, cls): ## ipv4-address.h: ns3::Ipv4Address::Ipv4Address(ns3::Ipv4Address const & arg0) [copy constructor] - cls.add_constructor([param('ns3::Ipv4Address&', 'arg0', is_const=True)], visibility='public') + cls.add_constructor([param('ns3::Ipv4Address&', 'arg0', is_const=True)]) ## ipv4-address.h: ns3::Ipv4Address::Ipv4Address() [constructor] - cls.add_constructor([], visibility='public') + cls.add_constructor([]) ## ipv4-address.h: ns3::Ipv4Address::Ipv4Address(uint32_t address) [constructor] - cls.add_constructor([param('uint32_t', 'address')], visibility='public') + cls.add_constructor([param('uint32_t', 'address')]) ## ipv4-address.h: ns3::Ipv4Address::Ipv4Address(char const * address) [constructor] - cls.add_constructor([param('char *', 'address', transfer_ownership=False, is_const=True)], visibility='public') + cls.add_constructor([param('char *', 'address', transfer_ownership=False, is_const=True)]) ## ipv4-address.h: ns3::Ipv4Address ns3::Ipv4Address::CombineMask(ns3::Ipv4Mask const & mask) const [member function] - cls.add_method('CombineMask', 'ns3::Ipv4Address', [param('ns3::Ipv4Mask&', 'mask', is_const=True)], is_const=True) + cls.add_method('CombineMask', + 'ns3::Ipv4Address', + [param('ns3::Ipv4Mask&', 'mask', is_const=True)], + is_const=True) ## ipv4-address.h: static ns3::Ipv4Address ns3::Ipv4Address::ConvertFrom(ns3::Address const & address) [member function] - cls.add_method('ConvertFrom', 'ns3::Ipv4Address', [param('ns3::Address&', 'address', is_const=True)], is_static=True) + cls.add_method('ConvertFrom', + 'ns3::Ipv4Address', + [param('ns3::Address&', 'address', is_const=True)], + is_static=True) ## ipv4-address.h: static ns3::Ipv4Address ns3::Ipv4Address::Deserialize(uint8_t const * buf) [member function] - cls.add_method('Deserialize', 'ns3::Ipv4Address', [param('uint8_t *', 'buf', transfer_ownership=False, is_const=True)], is_static=True) + cls.add_method('Deserialize', + 'ns3::Ipv4Address', + [param('uint8_t *', 'buf', transfer_ownership=False, is_const=True)], + is_static=True) ## ipv4-address.h: uint32_t ns3::Ipv4Address::Get() const [member function] - cls.add_method('Get', 'uint32_t', [], is_const=True) + cls.add_method('Get', + 'uint32_t', + [], + is_const=True) ## ipv4-address.h: static ns3::Ipv4Address ns3::Ipv4Address::GetAny() [member function] - cls.add_method('GetAny', 'ns3::Ipv4Address', [], is_static=True) + cls.add_method('GetAny', + 'ns3::Ipv4Address', + [], + is_static=True) ## ipv4-address.h: static ns3::Ipv4Address ns3::Ipv4Address::GetBroadcast() [member function] - cls.add_method('GetBroadcast', 'ns3::Ipv4Address', [], is_static=True) + cls.add_method('GetBroadcast', + 'ns3::Ipv4Address', + [], + is_static=True) ## ipv4-address.h: static ns3::Ipv4Address ns3::Ipv4Address::GetLoopback() [member function] - cls.add_method('GetLoopback', 'ns3::Ipv4Address', [], is_static=True) + cls.add_method('GetLoopback', + 'ns3::Ipv4Address', + [], + is_static=True) ## ipv4-address.h: ns3::Ipv4Address ns3::Ipv4Address::GetSubnetDirectedBroadcast(ns3::Ipv4Mask const & mask) const [member function] - cls.add_method('GetSubnetDirectedBroadcast', 'ns3::Ipv4Address', [param('ns3::Ipv4Mask&', 'mask', is_const=True)], is_const=True) + cls.add_method('GetSubnetDirectedBroadcast', + 'ns3::Ipv4Address', + [param('ns3::Ipv4Mask&', 'mask', is_const=True)], + is_const=True) ## ipv4-address.h: static ns3::Ipv4Address ns3::Ipv4Address::GetZero() [member function] - cls.add_method('GetZero', 'ns3::Ipv4Address', [], is_static=True) + cls.add_method('GetZero', + 'ns3::Ipv4Address', + [], + is_static=True) ## ipv4-address.h: bool ns3::Ipv4Address::IsBroadcast() const [member function] - cls.add_method('IsBroadcast', 'bool', [], is_const=True) + cls.add_method('IsBroadcast', + 'bool', + [], + is_const=True) ## ipv4-address.h: bool ns3::Ipv4Address::IsEqual(ns3::Ipv4Address const & other) const [member function] - cls.add_method('IsEqual', 'bool', [param('ns3::Ipv4Address&', 'other', is_const=True)], is_const=True) + cls.add_method('IsEqual', + 'bool', + [param('ns3::Ipv4Address&', 'other', is_const=True)], + is_const=True) ## ipv4-address.h: static bool ns3::Ipv4Address::IsMatchingType(ns3::Address const & address) [member function] - cls.add_method('IsMatchingType', 'bool', [param('ns3::Address&', 'address', is_const=True)], is_static=True) + cls.add_method('IsMatchingType', + 'bool', + [param('ns3::Address&', 'address', is_const=True)], + is_static=True) ## ipv4-address.h: bool ns3::Ipv4Address::IsMulticast() const [member function] - cls.add_method('IsMulticast', 'bool', [], is_const=True) + cls.add_method('IsMulticast', + 'bool', + [], + is_const=True) ## ipv4-address.h: bool ns3::Ipv4Address::IsSubnetDirectedBroadcast(ns3::Ipv4Mask const & mask) const [member function] - cls.add_method('IsSubnetDirectedBroadcast', 'bool', [param('ns3::Ipv4Mask&', 'mask', is_const=True)], is_const=True) + cls.add_method('IsSubnetDirectedBroadcast', + 'bool', + [param('ns3::Ipv4Mask&', 'mask', is_const=True)], + is_const=True) ## ipv4-address.h: void ns3::Ipv4Address::Print(std::ostream & os) const [member function] - cls.add_method('Print', 'void', [param('std::ostream&', 'os')], is_const=True) + cls.add_method('Print', + 'void', + [param('std::ostream&', 'os')], + is_const=True) ## ipv4-address.h: void ns3::Ipv4Address::Serialize(uint8_t * buf) const [member function] - cls.add_method('Serialize', 'void', [param('uint8_t *', 'buf')], is_const=True) + cls.add_method('Serialize', + 'void', + [param('uint8_t *', 'buf')], + is_const=True) ## ipv4-address.h: void ns3::Ipv4Address::Set(uint32_t address) [member function] - cls.add_method('Set', 'void', [param('uint32_t', 'address')]) + cls.add_method('Set', + 'void', + [param('uint32_t', 'address')]) ## ipv4-address.h: void ns3::Ipv4Address::Set(char const * address) [member function] - cls.add_method('Set', 'void', [param('char *', 'address', transfer_ownership=False, is_const=True)]) + cls.add_method('Set', + 'void', + [param('char *', 'address', transfer_ownership=False, is_const=True)]) cls.add_output_stream_operator() return def register_Ns3Application_methods(root_module, cls): ## application.h: static ns3::TypeId ns3::Application::GetTypeId() [member function] - cls.add_method('GetTypeId', 'ns3::TypeId', [], is_static=True) + cls.add_method('GetTypeId', + 'ns3::TypeId', + [], + is_static=True) ## application.h: ns3::Application::Application() [constructor] - cls.add_constructor([], visibility='public') + cls.add_constructor([]) ## application.h: void ns3::Application::Start(ns3::Time const & startTime) [member function] - cls.add_method('Start', 'void', [param('ns3::Time&', 'startTime', is_const=True)]) + cls.add_method('Start', + 'void', + [param('ns3::Time&', 'startTime', is_const=True)]) ## application.h: void ns3::Application::Start(ns3::RandomVariable const & startVariable) [member function] - cls.add_method('Start', 'void', [param('ns3::RandomVariable&', 'startVariable', is_const=True)]) + cls.add_method('Start', + 'void', + [param('ns3::RandomVariable&', 'startVariable', is_const=True)]) ## application.h: void ns3::Application::Stop(ns3::Time const & stopTime) [member function] - cls.add_method('Stop', 'void', [param('ns3::Time&', 'stopTime', is_const=True)]) + cls.add_method('Stop', + 'void', + [param('ns3::Time&', 'stopTime', is_const=True)]) ## application.h: void ns3::Application::Stop(ns3::RandomVariable const & stopVariable) [member function] - cls.add_method('Stop', 'void', [param('ns3::RandomVariable&', 'stopVariable', is_const=True)]) + cls.add_method('Stop', + 'void', + [param('ns3::RandomVariable&', 'stopVariable', is_const=True)]) ## application.h: ns3::Ptr ns3::Application::GetNode() const [member function] - cls.add_method('GetNode', 'ns3::Ptr< ns3::Node >', [], is_const=True) + cls.add_method('GetNode', + 'ns3::Ptr< ns3::Node >', + [], + is_const=True) ## application.h: void ns3::Application::SetNode(ns3::Ptr node) [member function] - cls.add_method('SetNode', 'void', [param('ns3::Ptr< ns3::Node >', 'node')]) + cls.add_method('SetNode', + 'void', + [param('ns3::Ptr< ns3::Node >', 'node')]) ## application.h: void ns3::Application::DoDispose() [member function] - cls.add_method('DoDispose', 'void', [], visibility='protected', is_virtual=True) + cls.add_method('DoDispose', + 'void', + [], + visibility='protected', is_virtual=True) ## application.h: void ns3::Application::StartApplication() [member function] - cls.add_method('StartApplication', 'void', [], visibility='private', is_virtual=True) + cls.add_method('StartApplication', + 'void', + [], + visibility='private', is_virtual=True) ## application.h: void ns3::Application::StopApplication() [member function] - cls.add_method('StopApplication', 'void', [], visibility='private', is_virtual=True) + cls.add_method('StopApplication', + 'void', + [], + visibility='private', is_virtual=True) return def register_Ns3Queue_methods(root_module, cls): ## queue.h: static ns3::TypeId ns3::Queue::GetTypeId() [member function] - cls.add_method('GetTypeId', 'ns3::TypeId', [], is_static=True) + cls.add_method('GetTypeId', + 'ns3::TypeId', + [], + is_static=True) ## queue.h: ns3::Queue::Queue() [constructor] - cls.add_constructor([], visibility='public') + cls.add_constructor([]) ## queue.h: bool ns3::Queue::IsEmpty() const [member function] - cls.add_method('IsEmpty', 'bool', [], is_const=True) + cls.add_method('IsEmpty', + 'bool', + [], + is_const=True) ## queue.h: bool ns3::Queue::Enqueue(ns3::Ptr p) [member function] - cls.add_method('Enqueue', 'bool', [param('ns3::Ptr< ns3::Packet >', 'p')]) + cls.add_method('Enqueue', + 'bool', + [param('ns3::Ptr< ns3::Packet >', 'p')]) ## queue.h: ns3::Ptr ns3::Queue::Dequeue() [member function] - cls.add_method('Dequeue', 'ns3::Ptr< ns3::Packet >', []) + cls.add_method('Dequeue', + 'ns3::Ptr< ns3::Packet >', + []) ## queue.h: ns3::Ptr ns3::Queue::Peek() const [member function] - cls.add_method('Peek', 'ns3::Ptr< ns3::Packet >', [], is_const=True) + cls.add_method('Peek', + 'ns3::Ptr< ns3::Packet >', + [], + is_const=True) ## queue.h: void ns3::Queue::DequeueAll() [member function] - cls.add_method('DequeueAll', 'void', []) + cls.add_method('DequeueAll', + 'void', + []) ## queue.h: uint32_t ns3::Queue::GetNPackets() const [member function] - cls.add_method('GetNPackets', 'uint32_t', [], is_const=True) + cls.add_method('GetNPackets', + 'uint32_t', + [], + is_const=True) ## queue.h: uint32_t ns3::Queue::GetNBytes() const [member function] - cls.add_method('GetNBytes', 'uint32_t', [], is_const=True) + cls.add_method('GetNBytes', + 'uint32_t', + [], + is_const=True) ## queue.h: uint32_t ns3::Queue::GetTotalReceivedBytes() const [member function] - cls.add_method('GetTotalReceivedBytes', 'uint32_t', [], is_const=True) + cls.add_method('GetTotalReceivedBytes', + 'uint32_t', + [], + is_const=True) ## queue.h: uint32_t ns3::Queue::GetTotalReceivedPackets() const [member function] - cls.add_method('GetTotalReceivedPackets', 'uint32_t', [], is_const=True) + cls.add_method('GetTotalReceivedPackets', + 'uint32_t', + [], + is_const=True) ## queue.h: uint32_t ns3::Queue::GetTotalDroppedBytes() const [member function] - cls.add_method('GetTotalDroppedBytes', 'uint32_t', [], is_const=True) + cls.add_method('GetTotalDroppedBytes', + 'uint32_t', + [], + is_const=True) ## queue.h: uint32_t ns3::Queue::GetTotalDroppedPackets() const [member function] - cls.add_method('GetTotalDroppedPackets', 'uint32_t', [], is_const=True) + cls.add_method('GetTotalDroppedPackets', + 'uint32_t', + [], + is_const=True) ## queue.h: void ns3::Queue::ResetStatistics() [member function] - cls.add_method('ResetStatistics', 'void', []) + cls.add_method('ResetStatistics', + 'void', + []) ## queue.h: void ns3::Queue::Drop(ns3::Ptr packet) [member function] - cls.add_method('Drop', 'void', [param('ns3::Ptr< ns3::Packet >', 'packet')], visibility='protected') + cls.add_method('Drop', + 'void', + [param('ns3::Ptr< ns3::Packet >', 'packet')], + visibility='protected') ## queue.h: bool ns3::Queue::DoEnqueue(ns3::Ptr p) [member function] - cls.add_method('DoEnqueue', 'bool', [param('ns3::Ptr< ns3::Packet >', 'p')], is_pure_virtual=True, visibility='private', is_virtual=True) + cls.add_method('DoEnqueue', + 'bool', + [param('ns3::Ptr< ns3::Packet >', 'p')], + is_pure_virtual=True, visibility='private', is_virtual=True) ## queue.h: ns3::Ptr ns3::Queue::DoDequeue() [member function] - cls.add_method('DoDequeue', 'ns3::Ptr< ns3::Packet >', [], is_pure_virtual=True, visibility='private', is_virtual=True) + cls.add_method('DoDequeue', + 'ns3::Ptr< ns3::Packet >', + [], + is_pure_virtual=True, visibility='private', is_virtual=True) ## queue.h: ns3::Ptr ns3::Queue::DoPeek() const [member function] - cls.add_method('DoPeek', 'ns3::Ptr< ns3::Packet >', [], is_pure_virtual=True, is_const=True, visibility='private', is_virtual=True) + cls.add_method('DoPeek', + 'ns3::Ptr< ns3::Packet >', + [], + is_pure_virtual=True, is_const=True, visibility='private', is_virtual=True) return def register_Ns3Socket_methods(root_module, cls): ## socket.h: ns3::Socket::Socket() [constructor] - cls.add_constructor([], visibility='public') + cls.add_constructor([]) ## socket.h: static ns3::Ptr ns3::Socket::CreateSocket(ns3::Ptr node, ns3::TypeId tid) [member function] - cls.add_method('CreateSocket', 'ns3::Ptr< ns3::Socket >', [param('ns3::Ptr< ns3::Node >', 'node'), param('ns3::TypeId', 'tid')], is_static=True) + cls.add_method('CreateSocket', + 'ns3::Ptr< ns3::Socket >', + [param('ns3::Ptr< ns3::Node >', 'node'), param('ns3::TypeId', 'tid')], + is_static=True) ## socket.h: ns3::Socket::SocketErrno ns3::Socket::GetErrno() const [member function] - cls.add_method('GetErrno', 'ns3::Socket::SocketErrno', [], is_pure_virtual=True, is_const=True, is_virtual=True) + cls.add_method('GetErrno', + 'ns3::Socket::SocketErrno', + [], + is_pure_virtual=True, is_const=True, is_virtual=True) ## socket.h: ns3::Ptr ns3::Socket::GetNode() const [member function] - cls.add_method('GetNode', 'ns3::Ptr< ns3::Node >', [], is_pure_virtual=True, is_const=True, is_virtual=True) + cls.add_method('GetNode', + 'ns3::Ptr< ns3::Node >', + [], + is_pure_virtual=True, is_const=True, is_virtual=True) ## socket.h: void ns3::Socket::SetConnectCallback(ns3::Callback, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty> connectionSucceeded, ns3::Callback, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty> connectionFailed) [member function] - cls.add_method('SetConnectCallback', 'void', [param('ns3::Callback< void, ns3::Ptr< ns3::Socket >, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty >', 'connectionSucceeded'), param('ns3::Callback< void, ns3::Ptr< ns3::Socket >, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty >', 'connectionFailed')]) + cls.add_method('SetConnectCallback', + 'void', + [param('ns3::Callback< void, ns3::Ptr< ns3::Socket >, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty >', 'connectionSucceeded'), param('ns3::Callback< void, ns3::Ptr< ns3::Socket >, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty >', 'connectionFailed')]) ## socket.h: void ns3::Socket::SetAcceptCallback(ns3::Callback, ns3::Address const&, ns3::empty, ns3::empty, ns3::empty, ns3::empty> connectionRequest, ns3::Callback, ns3::Address const&, ns3::empty, ns3::empty, ns3::empty, ns3::empty> newConnectionCreated) [member function] - cls.add_method('SetAcceptCallback', 'void', [param('ns3::Callback< bool, ns3::Ptr< ns3::Socket >, ns3::Address const&, ns3::empty, ns3::empty, ns3::empty, ns3::empty >', 'connectionRequest'), param('ns3::Callback< void, ns3::Ptr< ns3::Socket >, ns3::Address const&, ns3::empty, ns3::empty, ns3::empty, ns3::empty >', 'newConnectionCreated')]) + cls.add_method('SetAcceptCallback', + 'void', + [param('ns3::Callback< bool, ns3::Ptr< ns3::Socket >, ns3::Address const&, ns3::empty, ns3::empty, ns3::empty, ns3::empty >', 'connectionRequest'), param('ns3::Callback< void, ns3::Ptr< ns3::Socket >, ns3::Address const&, ns3::empty, ns3::empty, ns3::empty, ns3::empty >', 'newConnectionCreated')]) ## socket.h: bool ns3::Socket::SetDataSentCallback(ns3::Callback, unsigned int, ns3::empty, ns3::empty, ns3::empty, ns3::empty> dataSent) [member function] - cls.add_method('SetDataSentCallback', 'bool', [param('ns3::Callback< void, ns3::Ptr< ns3::Socket >, unsigned int, ns3::empty, ns3::empty, ns3::empty, ns3::empty >', 'dataSent')], is_virtual=True) + cls.add_method('SetDataSentCallback', + 'bool', + [param('ns3::Callback< void, ns3::Ptr< ns3::Socket >, unsigned int, ns3::empty, ns3::empty, ns3::empty, ns3::empty >', 'dataSent')], + is_virtual=True) ## socket.h: void ns3::Socket::SetSendCallback(ns3::Callback, unsigned int, ns3::empty, ns3::empty, ns3::empty, ns3::empty> sendCb) [member function] - cls.add_method('SetSendCallback', 'void', [param('ns3::Callback< void, ns3::Ptr< ns3::Socket >, unsigned int, ns3::empty, ns3::empty, ns3::empty, ns3::empty >', 'sendCb')]) + cls.add_method('SetSendCallback', + 'void', + [param('ns3::Callback< void, ns3::Ptr< ns3::Socket >, unsigned int, ns3::empty, ns3::empty, ns3::empty, ns3::empty >', 'sendCb')]) ## socket.h: void ns3::Socket::SetRecvCallback(ns3::Callback, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty> arg0) [member function] - cls.add_method('SetRecvCallback', 'void', [param('ns3::Callback< void, ns3::Ptr< ns3::Socket >, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty >', 'arg0')]) + cls.add_method('SetRecvCallback', + 'void', + [param('ns3::Callback< void, ns3::Ptr< ns3::Socket >, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty >', 'arg0')]) ## socket.h: int ns3::Socket::Bind(ns3::Address const & address) [member function] - cls.add_method('Bind', 'int', [param('ns3::Address&', 'address', is_const=True)], is_pure_virtual=True, is_virtual=True) + cls.add_method('Bind', + 'int', + [param('ns3::Address&', 'address', is_const=True)], + is_pure_virtual=True, is_virtual=True) ## socket.h: int ns3::Socket::Bind() [member function] - cls.add_method('Bind', 'int', [], is_pure_virtual=True, is_virtual=True) + cls.add_method('Bind', + 'int', + [], + is_pure_virtual=True, is_virtual=True) ## socket.h: int ns3::Socket::Close() [member function] - cls.add_method('Close', 'int', [], is_pure_virtual=True, is_virtual=True) + cls.add_method('Close', + 'int', + [], + is_pure_virtual=True, is_virtual=True) ## socket.h: int ns3::Socket::ShutdownSend() [member function] - cls.add_method('ShutdownSend', 'int', [], is_pure_virtual=True, is_virtual=True) + cls.add_method('ShutdownSend', + 'int', + [], + is_pure_virtual=True, is_virtual=True) ## socket.h: int ns3::Socket::ShutdownRecv() [member function] - cls.add_method('ShutdownRecv', 'int', [], is_pure_virtual=True, is_virtual=True) + cls.add_method('ShutdownRecv', + 'int', + [], + is_pure_virtual=True, is_virtual=True) ## socket.h: int ns3::Socket::Connect(ns3::Address const & address) [member function] - cls.add_method('Connect', 'int', [param('ns3::Address&', 'address', is_const=True)], is_pure_virtual=True, is_virtual=True) + cls.add_method('Connect', + 'int', + [param('ns3::Address&', 'address', is_const=True)], + is_pure_virtual=True, is_virtual=True) ## socket.h: int ns3::Socket::Listen(uint32_t queueLimit) [member function] - cls.add_method('Listen', 'int', [param('uint32_t', 'queueLimit')], is_pure_virtual=True, is_virtual=True) + cls.add_method('Listen', + 'int', + [param('uint32_t', 'queueLimit')], + is_pure_virtual=True, is_virtual=True) ## socket.h: uint32_t ns3::Socket::GetTxAvailable() const [member function] - cls.add_method('GetTxAvailable', 'uint32_t', [], is_pure_virtual=True, is_const=True, is_virtual=True) + cls.add_method('GetTxAvailable', + 'uint32_t', + [], + is_pure_virtual=True, is_const=True, is_virtual=True) ## socket.h: int ns3::Socket::Send(ns3::Ptr p, uint32_t flags) [member function] - cls.add_method('Send', 'int', [param('ns3::Ptr< ns3::Packet >', 'p'), param('uint32_t', 'flags')], is_pure_virtual=True, is_virtual=True) + cls.add_method('Send', + 'int', + [param('ns3::Ptr< ns3::Packet >', 'p'), param('uint32_t', 'flags')], + is_pure_virtual=True, is_virtual=True) ## socket.h: int ns3::Socket::SendTo(ns3::Ptr p, uint32_t flags, ns3::Address const & toAddress) [member function] - cls.add_method('SendTo', 'int', [param('ns3::Ptr< ns3::Packet >', 'p'), param('uint32_t', 'flags'), param('ns3::Address&', 'toAddress', is_const=True)], is_pure_virtual=True, is_virtual=True) + cls.add_method('SendTo', + 'int', + [param('ns3::Ptr< ns3::Packet >', 'p'), param('uint32_t', 'flags'), param('ns3::Address&', 'toAddress', is_const=True)], + is_pure_virtual=True, is_virtual=True) ## socket.h: uint32_t ns3::Socket::GetRxAvailable() const [member function] - cls.add_method('GetRxAvailable', 'uint32_t', [], is_pure_virtual=True, is_const=True, is_virtual=True) + cls.add_method('GetRxAvailable', + 'uint32_t', + [], + is_pure_virtual=True, is_const=True, is_virtual=True) ## socket.h: ns3::Ptr ns3::Socket::Recv(uint32_t maxSize, uint32_t flags) [member function] - cls.add_method('Recv', 'ns3::Ptr< ns3::Packet >', [param('uint32_t', 'maxSize'), param('uint32_t', 'flags')], is_pure_virtual=True, is_virtual=True) + cls.add_method('Recv', + 'ns3::Ptr< ns3::Packet >', + [param('uint32_t', 'maxSize'), param('uint32_t', 'flags')], + is_pure_virtual=True, is_virtual=True) ## socket.h: ns3::Ptr ns3::Socket::RecvFrom(uint32_t maxSize, uint32_t flags, ns3::Address & fromAddress) [member function] - cls.add_method('RecvFrom', 'ns3::Ptr< ns3::Packet >', [param('uint32_t', 'maxSize'), param('uint32_t', 'flags'), param('ns3::Address&', 'fromAddress')], is_pure_virtual=True, is_virtual=True) + cls.add_method('RecvFrom', + 'ns3::Ptr< ns3::Packet >', + [param('uint32_t', 'maxSize'), param('uint32_t', 'flags'), param('ns3::Address&', 'fromAddress')], + is_pure_virtual=True, is_virtual=True) ## socket.h: int ns3::Socket::Send(ns3::Ptr p) [member function] - cls.add_method('Send', 'int', [param('ns3::Ptr< ns3::Packet >', 'p')]) + cls.add_method('Send', + 'int', + [param('ns3::Ptr< ns3::Packet >', 'p')]) ## socket.h: int ns3::Socket::Send(uint8_t const * buf, uint32_t size, uint32_t flags) [member function] - cls.add_method('Send', 'int', [param('uint8_t *', 'buf', transfer_ownership=False, is_const=True), param('uint32_t', 'size'), param('uint32_t', 'flags')]) + cls.add_method('Send', + 'int', + [param('uint8_t *', 'buf', transfer_ownership=False, is_const=True), param('uint32_t', 'size'), param('uint32_t', 'flags')]) ## socket.h: int ns3::Socket::SendTo(uint8_t const * buf, uint32_t size, uint32_t flags, ns3::Address const & address) [member function] - cls.add_method('SendTo', 'int', [param('uint8_t *', 'buf', transfer_ownership=False, is_const=True), param('uint32_t', 'size'), param('uint32_t', 'flags'), param('ns3::Address&', 'address', is_const=True)]) + cls.add_method('SendTo', + 'int', + [param('uint8_t *', 'buf', transfer_ownership=False, is_const=True), param('uint32_t', 'size'), param('uint32_t', 'flags'), param('ns3::Address&', 'address', is_const=True)]) ## socket.h: ns3::Ptr ns3::Socket::Recv() [member function] - cls.add_method('Recv', 'ns3::Ptr< ns3::Packet >', []) + cls.add_method('Recv', + 'ns3::Ptr< ns3::Packet >', + []) ## socket.h: int ns3::Socket::Recv(uint8_t * buf, uint32_t size, uint32_t flags) [member function] - cls.add_method('Recv', 'int', [param('uint8_t *', 'buf'), param('uint32_t', 'size'), param('uint32_t', 'flags')]) + cls.add_method('Recv', + 'int', + [param('uint8_t *', 'buf'), param('uint32_t', 'size'), param('uint32_t', 'flags')]) ## socket.h: ns3::Ptr ns3::Socket::RecvFrom(ns3::Address & fromAddress) [member function] - cls.add_method('RecvFrom', 'ns3::Ptr< ns3::Packet >', [param('ns3::Address&', 'fromAddress')]) + cls.add_method('RecvFrom', + 'ns3::Ptr< ns3::Packet >', + [param('ns3::Address&', 'fromAddress')]) ## socket.h: int ns3::Socket::RecvFrom(uint8_t * buf, uint32_t size, uint32_t flags, ns3::Address & fromAddress) [member function] - cls.add_method('RecvFrom', 'int', [param('uint8_t *', 'buf'), param('uint32_t', 'size'), param('uint32_t', 'flags'), param('ns3::Address&', 'fromAddress')]) + cls.add_method('RecvFrom', + 'int', + [param('uint8_t *', 'buf'), param('uint32_t', 'size'), param('uint32_t', 'flags'), param('ns3::Address&', 'fromAddress')]) ## socket.h: void ns3::Socket::NotifyConnectionSucceeded() [member function] - cls.add_method('NotifyConnectionSucceeded', 'void', [], visibility='protected') + cls.add_method('NotifyConnectionSucceeded', + 'void', + [], + visibility='protected') ## socket.h: void ns3::Socket::NotifyConnectionFailed() [member function] - cls.add_method('NotifyConnectionFailed', 'void', [], visibility='protected') + cls.add_method('NotifyConnectionFailed', + 'void', + [], + visibility='protected') ## socket.h: bool ns3::Socket::NotifyConnectionRequest(ns3::Address const & from) [member function] - cls.add_method('NotifyConnectionRequest', 'bool', [param('ns3::Address&', 'from', is_const=True)], visibility='protected') + cls.add_method('NotifyConnectionRequest', + 'bool', + [param('ns3::Address&', 'from', is_const=True)], + visibility='protected') ## socket.h: void ns3::Socket::NotifyNewConnectionCreated(ns3::Ptr socket, ns3::Address const & from) [member function] - cls.add_method('NotifyNewConnectionCreated', 'void', [param('ns3::Ptr< ns3::Socket >', 'socket'), param('ns3::Address&', 'from', is_const=True)], visibility='protected') + cls.add_method('NotifyNewConnectionCreated', + 'void', + [param('ns3::Ptr< ns3::Socket >', 'socket'), param('ns3::Address&', 'from', is_const=True)], + visibility='protected') ## socket.h: void ns3::Socket::NotifyDataSent(uint32_t size) [member function] - cls.add_method('NotifyDataSent', 'void', [param('uint32_t', 'size')], visibility='protected') + cls.add_method('NotifyDataSent', + 'void', + [param('uint32_t', 'size')], + visibility='protected') ## socket.h: void ns3::Socket::NotifySend(uint32_t spaceAvailable) [member function] - cls.add_method('NotifySend', 'void', [param('uint32_t', 'spaceAvailable')], visibility='protected') + cls.add_method('NotifySend', + 'void', + [param('uint32_t', 'spaceAvailable')], + visibility='protected') ## socket.h: void ns3::Socket::NotifyDataRecv() [member function] - cls.add_method('NotifyDataRecv', 'void', [], visibility='protected') + cls.add_method('NotifyDataRecv', + 'void', + [], + visibility='protected') return def register_Ns3Ipv4Header_methods(root_module, cls): ## ipv4-header.h: ns3::Ipv4Header::Ipv4Header() [constructor] - cls.add_constructor([], visibility='public') + cls.add_constructor([]) ## ipv4-header.h: void ns3::Ipv4Header::EnableChecksum() [member function] - cls.add_method('EnableChecksum', 'void', []) + cls.add_method('EnableChecksum', + 'void', + []) ## ipv4-header.h: void ns3::Ipv4Header::SetPayloadSize(uint16_t size) [member function] - cls.add_method('SetPayloadSize', 'void', [param('uint16_t', 'size')]) + cls.add_method('SetPayloadSize', + 'void', + [param('uint16_t', 'size')]) ## ipv4-header.h: void ns3::Ipv4Header::SetIdentification(uint16_t identification) [member function] - cls.add_method('SetIdentification', 'void', [param('uint16_t', 'identification')]) + cls.add_method('SetIdentification', + 'void', + [param('uint16_t', 'identification')]) ## ipv4-header.h: void ns3::Ipv4Header::SetTos(uint8_t tos) [member function] - cls.add_method('SetTos', 'void', [param('uint8_t', 'tos')]) + cls.add_method('SetTos', + 'void', + [param('uint8_t', 'tos')]) ## ipv4-header.h: void ns3::Ipv4Header::SetMoreFragments() [member function] - cls.add_method('SetMoreFragments', 'void', []) + cls.add_method('SetMoreFragments', + 'void', + []) ## ipv4-header.h: void ns3::Ipv4Header::SetLastFragment() [member function] - cls.add_method('SetLastFragment', 'void', []) + cls.add_method('SetLastFragment', + 'void', + []) ## ipv4-header.h: void ns3::Ipv4Header::SetDontFragment() [member function] - cls.add_method('SetDontFragment', 'void', []) + cls.add_method('SetDontFragment', + 'void', + []) ## ipv4-header.h: void ns3::Ipv4Header::SetMayFragment() [member function] - cls.add_method('SetMayFragment', 'void', []) + cls.add_method('SetMayFragment', + 'void', + []) ## ipv4-header.h: void ns3::Ipv4Header::SetFragmentOffset(uint16_t offset) [member function] - cls.add_method('SetFragmentOffset', 'void', [param('uint16_t', 'offset')]) + cls.add_method('SetFragmentOffset', + 'void', + [param('uint16_t', 'offset')]) ## ipv4-header.h: void ns3::Ipv4Header::SetTtl(uint8_t ttl) [member function] - cls.add_method('SetTtl', 'void', [param('uint8_t', 'ttl')]) + cls.add_method('SetTtl', + 'void', + [param('uint8_t', 'ttl')]) ## ipv4-header.h: void ns3::Ipv4Header::SetProtocol(uint8_t num) [member function] - cls.add_method('SetProtocol', 'void', [param('uint8_t', 'num')]) + cls.add_method('SetProtocol', + 'void', + [param('uint8_t', 'num')]) ## ipv4-header.h: void ns3::Ipv4Header::SetSource(ns3::Ipv4Address source) [member function] - cls.add_method('SetSource', 'void', [param('ns3::Ipv4Address', 'source')]) + cls.add_method('SetSource', + 'void', + [param('ns3::Ipv4Address', 'source')]) ## ipv4-header.h: void ns3::Ipv4Header::SetDestination(ns3::Ipv4Address destination) [member function] - cls.add_method('SetDestination', 'void', [param('ns3::Ipv4Address', 'destination')]) + cls.add_method('SetDestination', + 'void', + [param('ns3::Ipv4Address', 'destination')]) ## ipv4-header.h: uint16_t ns3::Ipv4Header::GetPayloadSize() const [member function] - cls.add_method('GetPayloadSize', 'uint16_t', [], is_const=True) + cls.add_method('GetPayloadSize', + 'uint16_t', + [], + is_const=True) ## ipv4-header.h: uint16_t ns3::Ipv4Header::GetIdentification() const [member function] - cls.add_method('GetIdentification', 'uint16_t', [], is_const=True) + cls.add_method('GetIdentification', + 'uint16_t', + [], + is_const=True) ## ipv4-header.h: uint8_t ns3::Ipv4Header::GetTos() const [member function] - cls.add_method('GetTos', 'uint8_t', [], is_const=True) + cls.add_method('GetTos', + 'uint8_t', + [], + is_const=True) ## ipv4-header.h: bool ns3::Ipv4Header::IsLastFragment() const [member function] - cls.add_method('IsLastFragment', 'bool', [], is_const=True) + cls.add_method('IsLastFragment', + 'bool', + [], + is_const=True) ## ipv4-header.h: bool ns3::Ipv4Header::IsDontFragment() const [member function] - cls.add_method('IsDontFragment', 'bool', [], is_const=True) + cls.add_method('IsDontFragment', + 'bool', + [], + is_const=True) ## ipv4-header.h: uint16_t ns3::Ipv4Header::GetFragmentOffset() const [member function] - cls.add_method('GetFragmentOffset', 'uint16_t', [], is_const=True) + cls.add_method('GetFragmentOffset', + 'uint16_t', + [], + is_const=True) ## ipv4-header.h: uint8_t ns3::Ipv4Header::GetTtl() const [member function] - cls.add_method('GetTtl', 'uint8_t', [], is_const=True) + cls.add_method('GetTtl', + 'uint8_t', + [], + is_const=True) ## ipv4-header.h: uint8_t ns3::Ipv4Header::GetProtocol() const [member function] - cls.add_method('GetProtocol', 'uint8_t', [], is_const=True) + cls.add_method('GetProtocol', + 'uint8_t', + [], + is_const=True) ## ipv4-header.h: ns3::Ipv4Address ns3::Ipv4Header::GetSource() const [member function] - cls.add_method('GetSource', 'ns3::Ipv4Address', [], is_const=True) + cls.add_method('GetSource', + 'ns3::Ipv4Address', + [], + is_const=True) ## ipv4-header.h: ns3::Ipv4Address ns3::Ipv4Header::GetDestination() const [member function] - cls.add_method('GetDestination', 'ns3::Ipv4Address', [], is_const=True) + cls.add_method('GetDestination', + 'ns3::Ipv4Address', + [], + is_const=True) ## ipv4-header.h: bool ns3::Ipv4Header::IsChecksumOk() const [member function] - cls.add_method('IsChecksumOk', 'bool', [], is_const=True) + cls.add_method('IsChecksumOk', + 'bool', + [], + is_const=True) ## ipv4-header.h: static ns3::TypeId ns3::Ipv4Header::GetTypeId() [member function] - cls.add_method('GetTypeId', 'ns3::TypeId', [], is_static=True) + cls.add_method('GetTypeId', + 'ns3::TypeId', + [], + is_static=True) ## ipv4-header.h: ns3::TypeId ns3::Ipv4Header::GetInstanceTypeId() const [member function] - cls.add_method('GetInstanceTypeId', 'ns3::TypeId', [], is_const=True, is_virtual=True) + cls.add_method('GetInstanceTypeId', + 'ns3::TypeId', + [], + is_const=True, is_virtual=True) ## ipv4-header.h: void ns3::Ipv4Header::Print(std::ostream & os) const [member function] - cls.add_method('Print', 'void', [param('std::ostream&', 'os')], is_const=True, is_virtual=True) + cls.add_method('Print', + 'void', + [param('std::ostream&', 'os')], + is_const=True, is_virtual=True) ## ipv4-header.h: uint32_t ns3::Ipv4Header::GetSerializedSize() const [member function] - cls.add_method('GetSerializedSize', 'uint32_t', [], is_const=True, is_virtual=True) + cls.add_method('GetSerializedSize', + 'uint32_t', + [], + is_const=True, is_virtual=True) ## ipv4-header.h: void ns3::Ipv4Header::Serialize(ns3::Buffer::Iterator start) const [member function] - cls.add_method('Serialize', 'void', [param('ns3::Buffer::Iterator', 'start')], is_const=True, is_virtual=True) + cls.add_method('Serialize', + 'void', + [param('ns3::Buffer::Iterator', 'start')], + is_const=True, is_virtual=True) ## ipv4-header.h: uint32_t ns3::Ipv4Header::Deserialize(ns3::Buffer::Iterator start) [member function] - cls.add_method('Deserialize', 'uint32_t', [param('ns3::Buffer::Iterator', 'start')], is_virtual=True) + cls.add_method('Deserialize', + 'uint32_t', + [param('ns3::Buffer::Iterator', 'start')], + is_virtual=True) return def register_Ns3UdpSocket_methods(root_module, cls): ## udp-socket.h: static ns3::TypeId ns3::UdpSocket::GetTypeId() [member function] - cls.add_method('GetTypeId', 'ns3::TypeId', [], is_static=True) + cls.add_method('GetTypeId', + 'ns3::TypeId', + [], + is_static=True) ## udp-socket.h: ns3::UdpSocket::UdpSocket() [constructor] - cls.add_constructor([], visibility='public') + cls.add_constructor([]) ## udp-socket.h: void ns3::UdpSocket::SetRcvBufSize(uint32_t size) [member function] - cls.add_method('SetRcvBufSize', 'void', [param('uint32_t', 'size')], is_pure_virtual=True, visibility='private', is_virtual=True) + cls.add_method('SetRcvBufSize', + 'void', + [param('uint32_t', 'size')], + is_pure_virtual=True, visibility='private', is_virtual=True) ## udp-socket.h: uint32_t ns3::UdpSocket::GetRcvBufSize() const [member function] - cls.add_method('GetRcvBufSize', 'uint32_t', [], is_pure_virtual=True, is_const=True, visibility='private', is_virtual=True) + cls.add_method('GetRcvBufSize', + 'uint32_t', + [], + is_pure_virtual=True, is_const=True, visibility='private', is_virtual=True) ## udp-socket.h: void ns3::UdpSocket::SetIpTtl(uint32_t ipTtl) [member function] - cls.add_method('SetIpTtl', 'void', [param('uint32_t', 'ipTtl')], is_pure_virtual=True, visibility='private', is_virtual=True) + cls.add_method('SetIpTtl', + 'void', + [param('uint32_t', 'ipTtl')], + is_pure_virtual=True, visibility='private', is_virtual=True) ## udp-socket.h: uint32_t ns3::UdpSocket::GetIpTtl() const [member function] - cls.add_method('GetIpTtl', 'uint32_t', [], is_pure_virtual=True, is_const=True, visibility='private', is_virtual=True) + cls.add_method('GetIpTtl', + 'uint32_t', + [], + is_pure_virtual=True, is_const=True, visibility='private', is_virtual=True) ## udp-socket.h: void ns3::UdpSocket::SetIpMulticastTtl(uint32_t ipTtl) [member function] - cls.add_method('SetIpMulticastTtl', 'void', [param('uint32_t', 'ipTtl')], is_pure_virtual=True, visibility='private', is_virtual=True) + cls.add_method('SetIpMulticastTtl', + 'void', + [param('uint32_t', 'ipTtl')], + is_pure_virtual=True, visibility='private', is_virtual=True) ## udp-socket.h: uint32_t ns3::UdpSocket::GetIpMulticastTtl() const [member function] - cls.add_method('GetIpMulticastTtl', 'uint32_t', [], is_pure_virtual=True, is_const=True, visibility='private', is_virtual=True) + cls.add_method('GetIpMulticastTtl', + 'uint32_t', + [], + is_pure_virtual=True, is_const=True, visibility='private', is_virtual=True) return def register_Ns3NetDevice_methods(root_module, cls): ## net-device.h: static ns3::TypeId ns3::NetDevice::GetTypeId() [member function] - cls.add_method('GetTypeId', 'ns3::TypeId', [], is_static=True) + cls.add_method('GetTypeId', + 'ns3::TypeId', + [], + is_static=True) ## net-device.h: void ns3::NetDevice::SetName(std::string const name) [member function] - cls.add_method('SetName', 'void', [param('std::string', 'name', is_const=True)], is_pure_virtual=True, is_virtual=True) + cls.add_method('SetName', + 'void', + [param('std::string', 'name', is_const=True)], + is_pure_virtual=True, is_virtual=True) ## net-device.h: std::string ns3::NetDevice::GetName() const [member function] - cls.add_method('GetName', 'std::string', [], is_pure_virtual=True, is_const=True, is_virtual=True) + cls.add_method('GetName', + 'std::string', + [], + is_pure_virtual=True, is_const=True, is_virtual=True) ## net-device.h: void ns3::NetDevice::SetIfIndex(uint32_t const index) [member function] - cls.add_method('SetIfIndex', 'void', [param('uint32_t', 'index', is_const=True)], is_pure_virtual=True, is_virtual=True) + cls.add_method('SetIfIndex', + 'void', + [param('uint32_t', 'index', is_const=True)], + is_pure_virtual=True, is_virtual=True) ## net-device.h: uint32_t ns3::NetDevice::GetIfIndex() const [member function] - cls.add_method('GetIfIndex', 'uint32_t', [], is_pure_virtual=True, is_const=True, is_virtual=True) + cls.add_method('GetIfIndex', + 'uint32_t', + [], + is_pure_virtual=True, is_const=True, is_virtual=True) ## net-device.h: ns3::Ptr ns3::NetDevice::GetChannel() const [member function] - cls.add_method('GetChannel', 'ns3::Ptr< ns3::Channel >', [], is_pure_virtual=True, is_const=True, is_virtual=True) + cls.add_method('GetChannel', + 'ns3::Ptr< ns3::Channel >', + [], + is_pure_virtual=True, is_const=True, is_virtual=True) ## net-device.h: ns3::Address ns3::NetDevice::GetAddress() const [member function] - cls.add_method('GetAddress', 'ns3::Address', [], is_pure_virtual=True, is_const=True, is_virtual=True) + cls.add_method('GetAddress', + 'ns3::Address', + [], + is_pure_virtual=True, is_const=True, is_virtual=True) ## net-device.h: bool ns3::NetDevice::SetMtu(uint16_t const mtu) [member function] - cls.add_method('SetMtu', 'bool', [param('uint16_t', 'mtu', is_const=True)], is_pure_virtual=True, is_virtual=True) + cls.add_method('SetMtu', + 'bool', + [param('uint16_t', 'mtu', is_const=True)], + is_pure_virtual=True, is_virtual=True) ## net-device.h: uint16_t ns3::NetDevice::GetMtu() const [member function] - cls.add_method('GetMtu', 'uint16_t', [], is_pure_virtual=True, is_const=True, is_virtual=True) + cls.add_method('GetMtu', + 'uint16_t', + [], + is_pure_virtual=True, is_const=True, is_virtual=True) ## net-device.h: bool ns3::NetDevice::IsLinkUp() const [member function] - cls.add_method('IsLinkUp', 'bool', [], is_pure_virtual=True, is_const=True, is_virtual=True) + cls.add_method('IsLinkUp', + 'bool', + [], + is_pure_virtual=True, is_const=True, is_virtual=True) ## net-device.h: void ns3::NetDevice::SetLinkChangeCallback(ns3::Callback callback) [member function] - cls.add_method('SetLinkChangeCallback', 'void', [param('ns3::Callback< void, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty >', 'callback')], is_pure_virtual=True, is_virtual=True) + cls.add_method('SetLinkChangeCallback', + 'void', + [param('ns3::Callback< void, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty >', 'callback')], + is_pure_virtual=True, is_virtual=True) ## net-device.h: bool ns3::NetDevice::IsBroadcast() const [member function] - cls.add_method('IsBroadcast', 'bool', [], is_pure_virtual=True, is_const=True, is_virtual=True) + cls.add_method('IsBroadcast', + 'bool', + [], + is_pure_virtual=True, is_const=True, is_virtual=True) ## net-device.h: ns3::Address ns3::NetDevice::GetBroadcast() const [member function] - cls.add_method('GetBroadcast', 'ns3::Address', [], is_pure_virtual=True, is_const=True, is_virtual=True) + cls.add_method('GetBroadcast', + 'ns3::Address', + [], + is_pure_virtual=True, is_const=True, is_virtual=True) ## net-device.h: bool ns3::NetDevice::IsMulticast() const [member function] - cls.add_method('IsMulticast', 'bool', [], is_pure_virtual=True, is_const=True, is_virtual=True) + cls.add_method('IsMulticast', + 'bool', + [], + is_pure_virtual=True, is_const=True, is_virtual=True) ## net-device.h: ns3::Address ns3::NetDevice::GetMulticast() const [member function] - cls.add_method('GetMulticast', 'ns3::Address', [], is_pure_virtual=True, is_const=True, is_virtual=True) + cls.add_method('GetMulticast', + 'ns3::Address', + [], + is_pure_virtual=True, is_const=True, is_virtual=True) ## net-device.h: ns3::Address ns3::NetDevice::MakeMulticastAddress(ns3::Ipv4Address multicastGroup) const [member function] - cls.add_method('MakeMulticastAddress', 'ns3::Address', [param('ns3::Ipv4Address', 'multicastGroup')], is_pure_virtual=True, is_const=True, is_virtual=True) + cls.add_method('MakeMulticastAddress', + 'ns3::Address', + [param('ns3::Ipv4Address', 'multicastGroup')], + is_pure_virtual=True, is_const=True, is_virtual=True) ## net-device.h: bool ns3::NetDevice::IsPointToPoint() const [member function] - cls.add_method('IsPointToPoint', 'bool', [], is_pure_virtual=True, is_const=True, is_virtual=True) + cls.add_method('IsPointToPoint', + 'bool', + [], + is_pure_virtual=True, is_const=True, is_virtual=True) ## net-device.h: bool ns3::NetDevice::Send(ns3::Ptr packet, ns3::Address const & dest, uint16_t protocolNumber) [member function] - cls.add_method('Send', 'bool', [param('ns3::Ptr< ns3::Packet >', 'packet'), param('ns3::Address&', 'dest', is_const=True), param('uint16_t', 'protocolNumber')], is_pure_virtual=True, is_virtual=True) + cls.add_method('Send', + 'bool', + [param('ns3::Ptr< ns3::Packet >', 'packet'), param('ns3::Address&', 'dest', is_const=True), param('uint16_t', 'protocolNumber')], + is_pure_virtual=True, is_virtual=True) ## net-device.h: bool ns3::NetDevice::SendFrom(ns3::Ptr packet, ns3::Address const & source, ns3::Address const & dest, uint16_t protocolNumber) [member function] - cls.add_method('SendFrom', 'bool', [param('ns3::Ptr< ns3::Packet >', 'packet'), param('ns3::Address&', 'source', is_const=True), param('ns3::Address&', 'dest', is_const=True), param('uint16_t', 'protocolNumber')], is_pure_virtual=True, is_virtual=True) + cls.add_method('SendFrom', + 'bool', + [param('ns3::Ptr< ns3::Packet >', 'packet'), param('ns3::Address&', 'source', is_const=True), param('ns3::Address&', 'dest', is_const=True), param('uint16_t', 'protocolNumber')], + is_virtual=True) ## net-device.h: ns3::Ptr ns3::NetDevice::GetNode() const [member function] - cls.add_method('GetNode', 'ns3::Ptr< ns3::Node >', [], is_pure_virtual=True, is_const=True, is_virtual=True) + cls.add_method('GetNode', + 'ns3::Ptr< ns3::Node >', + [], + is_pure_virtual=True, is_const=True, is_virtual=True) ## net-device.h: void ns3::NetDevice::SetNode(ns3::Ptr node) [member function] - cls.add_method('SetNode', 'void', [param('ns3::Ptr< ns3::Node >', 'node')], is_pure_virtual=True, is_virtual=True) + cls.add_method('SetNode', + 'void', + [param('ns3::Ptr< ns3::Node >', 'node')], + is_pure_virtual=True, is_virtual=True) ## net-device.h: bool ns3::NetDevice::NeedsArp() const [member function] - cls.add_method('NeedsArp', 'bool', [], is_pure_virtual=True, is_const=True, is_virtual=True) + cls.add_method('NeedsArp', + 'bool', + [], + is_pure_virtual=True, is_const=True, is_virtual=True) ## net-device.h: void ns3::NetDevice::SetReceiveCallback(ns3::Callback, ns3::Ptr, unsigned short, ns3::Address const&, ns3::empty, ns3::empty> cb) [member function] - cls.add_method('SetReceiveCallback', 'void', [param('ns3::Callback< bool, ns3::Ptr< ns3::NetDevice >, ns3::Ptr< ns3::Packet >, unsigned short, ns3::Address const&, ns3::empty, ns3::empty >', 'cb')], is_pure_virtual=True, is_virtual=True) + cls.add_method('SetReceiveCallback', + 'void', + [param('ns3::Callback< bool, ns3::Ptr< ns3::NetDevice >, ns3::Ptr< ns3::Packet >, unsigned short, ns3::Address const&, ns3::empty, ns3::empty >', 'cb')], + is_pure_virtual=True, is_virtual=True) ## net-device.h: void ns3::NetDevice::SetPromiscReceiveCallback(ns3::Callback, ns3::Ptr, unsigned short, ns3::Address const&, ns3::Address const&, ns3::NetDevice::PacketType> cb) [member function] - cls.add_method('SetPromiscReceiveCallback', 'void', [param('ns3::Callback< bool, ns3::Ptr< ns3::NetDevice >, ns3::Ptr< ns3::Packet >, unsigned short, ns3::Address const&, ns3::Address const&, ns3::NetDevice::PacketType >', 'cb')], is_virtual=True) + cls.add_method('SetPromiscReceiveCallback', + 'void', + [param('ns3::Callback< bool, ns3::Ptr< ns3::NetDevice >, ns3::Ptr< ns3::Packet >, unsigned short, ns3::Address const&, ns3::Address const&, ns3::NetDevice::PacketType >', 'cb')], + is_virtual=True) ## net-device.h: bool ns3::NetDevice::SupportsPromiscuous() const [member function] - cls.add_method('SupportsPromiscuous', 'bool', [], is_const=True, is_virtual=True) + cls.add_method('SupportsPromiscuous', + 'bool', + [], + is_const=True, is_virtual=True) cls.add_constructor([]) return def register_Ns3AddressValue_methods(root_module, cls): ## address.h: ns3::AddressValue::AddressValue() [constructor] - cls.add_constructor([], visibility='public') + cls.add_constructor([]) ## address.h: ns3::AddressValue::AddressValue(ns3::Address const & value) [constructor] - cls.add_constructor([param('ns3::Address&', 'value', is_const=True)], visibility='public') + cls.add_constructor([param('ns3::Address&', 'value', is_const=True)]) ## address.h: void ns3::AddressValue::Set(ns3::Address const & value) [member function] - cls.add_method('Set', 'void', [param('ns3::Address&', 'value', is_const=True)]) + cls.add_method('Set', + 'void', + [param('ns3::Address&', 'value', is_const=True)]) ## address.h: ns3::Address ns3::AddressValue::Get() const [member function] - cls.add_method('Get', 'ns3::Address', [], is_const=True) + cls.add_method('Get', + 'ns3::Address', + [], + is_const=True) ## address.h: ns3::Ptr ns3::AddressValue::Copy() const [member function] - cls.add_method('Copy', 'ns3::Ptr< ns3::AttributeValue >', [], is_const=True, is_virtual=True) + cls.add_method('Copy', + 'ns3::Ptr< ns3::AttributeValue >', + [], + is_const=True, is_virtual=True) ## address.h: std::string ns3::AddressValue::SerializeToString(ns3::Ptr checker) const [member function] - cls.add_method('SerializeToString', 'std::string', [param('ns3::Ptr< ns3::AttributeChecker const >', 'checker')], is_const=True, is_virtual=True) + cls.add_method('SerializeToString', + 'std::string', + [param('ns3::Ptr< ns3::AttributeChecker const >', 'checker')], + is_const=True, is_virtual=True) ## address.h: bool ns3::AddressValue::DeserializeFromString(std::string value, ns3::Ptr checker) [member function] - cls.add_method('DeserializeFromString', 'bool', [param('std::string', 'value'), param('ns3::Ptr< ns3::AttributeChecker const >', 'checker')], is_virtual=True) + cls.add_method('DeserializeFromString', + 'bool', + [param('std::string', 'value'), param('ns3::Ptr< ns3::AttributeChecker const >', 'checker')], + is_virtual=True) return def register_Ns3Node_methods(root_module, cls): ## node.h: static ns3::TypeId ns3::Node::GetTypeId() [member function] - cls.add_method('GetTypeId', 'ns3::TypeId', [], is_static=True) + cls.add_method('GetTypeId', + 'ns3::TypeId', + [], + is_static=True) ## node.h: ns3::Node::Node() [constructor] - cls.add_constructor([], visibility='public') + cls.add_constructor([]) ## node.h: ns3::Node::Node(uint32_t systemId) [constructor] - cls.add_constructor([param('uint32_t', 'systemId')], visibility='public') + cls.add_constructor([param('uint32_t', 'systemId')]) ## node.h: uint32_t ns3::Node::GetId() const [member function] - cls.add_method('GetId', 'uint32_t', [], is_const=True) + cls.add_method('GetId', + 'uint32_t', + [], + is_const=True) ## node.h: uint32_t ns3::Node::GetSystemId() const [member function] - cls.add_method('GetSystemId', 'uint32_t', [], is_const=True) + cls.add_method('GetSystemId', + 'uint32_t', + [], + is_const=True) ## node.h: uint32_t ns3::Node::AddDevice(ns3::Ptr device) [member function] - cls.add_method('AddDevice', 'uint32_t', [param('ns3::Ptr< ns3::NetDevice >', 'device')]) + cls.add_method('AddDevice', + 'uint32_t', + [param('ns3::Ptr< ns3::NetDevice >', 'device')]) ## node.h: ns3::Ptr ns3::Node::GetDevice(uint32_t index) const [member function] - cls.add_method('GetDevice', 'ns3::Ptr< ns3::NetDevice >', [param('uint32_t', 'index')], is_const=True) + cls.add_method('GetDevice', + 'ns3::Ptr< ns3::NetDevice >', + [param('uint32_t', 'index')], + is_const=True) ## node.h: uint32_t ns3::Node::GetNDevices() const [member function] - cls.add_method('GetNDevices', 'uint32_t', [], is_const=True) + cls.add_method('GetNDevices', + 'uint32_t', + [], + is_const=True) ## node.h: uint32_t ns3::Node::AddApplication(ns3::Ptr application) [member function] - cls.add_method('AddApplication', 'uint32_t', [param('ns3::Ptr< ns3::Application >', 'application')]) + cls.add_method('AddApplication', + 'uint32_t', + [param('ns3::Ptr< ns3::Application >', 'application')]) ## node.h: ns3::Ptr ns3::Node::GetApplication(uint32_t index) const [member function] - cls.add_method('GetApplication', 'ns3::Ptr< ns3::Application >', [param('uint32_t', 'index')], is_const=True) + cls.add_method('GetApplication', + 'ns3::Ptr< ns3::Application >', + [param('uint32_t', 'index')], + is_const=True) ## node.h: ns3::Ptr ns3::Node::GetFirstApplication(ns3::TypeId tid) [member function] - cls.add_method('GetFirstApplication', 'ns3::Ptr< ns3::Application >', [param('ns3::TypeId', 'tid')]) + cls.add_method('GetFirstApplication', + 'ns3::Ptr< ns3::Application >', + [param('ns3::TypeId', 'tid')]) ## node.h: uint32_t ns3::Node::GetNApplications() const [member function] - cls.add_method('GetNApplications', 'uint32_t', [], is_const=True) + cls.add_method('GetNApplications', + 'uint32_t', + [], + is_const=True) ## node.h: void ns3::Node::RegisterProtocolHandler(ns3::Callback, ns3::Ptr, unsigned short, ns3::Address const&, ns3::Address const&, ns3::NetDevice::PacketType> handler, uint16_t protocolType, ns3::Ptr device, bool promiscuous=false) [member function] - cls.add_method('RegisterProtocolHandler', 'void', [param('ns3::Callback< void, ns3::Ptr< ns3::NetDevice >, ns3::Ptr< ns3::Packet >, unsigned short, ns3::Address const&, ns3::Address const&, ns3::NetDevice::PacketType >', 'handler'), param('uint16_t', 'protocolType'), param('ns3::Ptr< ns3::NetDevice >', 'device'), param('bool', 'promiscuous', default_value='false')]) + cls.add_method('RegisterProtocolHandler', + 'void', + [param('ns3::Callback< void, ns3::Ptr< ns3::NetDevice >, ns3::Ptr< ns3::Packet >, unsigned short, ns3::Address const&, ns3::Address const&, ns3::NetDevice::PacketType >', 'handler'), param('uint16_t', 'protocolType'), param('ns3::Ptr< ns3::NetDevice >', 'device'), param('bool', 'promiscuous', default_value='false')]) ## node.h: void ns3::Node::UnregisterProtocolHandler(ns3::Callback, ns3::Ptr, unsigned short, ns3::Address const&, ns3::Address const&, ns3::NetDevice::PacketType> handler) [member function] - cls.add_method('UnregisterProtocolHandler', 'void', [param('ns3::Callback< void, ns3::Ptr< ns3::NetDevice >, ns3::Ptr< ns3::Packet >, unsigned short, ns3::Address const&, ns3::Address const&, ns3::NetDevice::PacketType >', 'handler')]) + cls.add_method('UnregisterProtocolHandler', + 'void', + [param('ns3::Callback< void, ns3::Ptr< ns3::NetDevice >, ns3::Ptr< ns3::Packet >, unsigned short, ns3::Address const&, ns3::Address const&, ns3::NetDevice::PacketType >', 'handler')]) ## node.h: void ns3::Node::DoDispose() [member function] - cls.add_method('DoDispose', 'void', [], visibility='protected', is_virtual=True) + cls.add_method('DoDispose', + 'void', + [], + visibility='protected', is_virtual=True) ## node.h: void ns3::Node::NotifyDeviceAdded(ns3::Ptr device) [member function] - cls.add_method('NotifyDeviceAdded', 'void', [param('ns3::Ptr< ns3::NetDevice >', 'device')], visibility='private', is_virtual=True) + cls.add_method('NotifyDeviceAdded', + 'void', + [param('ns3::Ptr< ns3::NetDevice >', 'device')], + visibility='private', is_virtual=True) return def register_Ns3Channel_methods(root_module, cls): ## channel.h: static ns3::TypeId ns3::Channel::GetTypeId() [member function] - cls.add_method('GetTypeId', 'ns3::TypeId', [], is_static=True) + cls.add_method('GetTypeId', + 'ns3::TypeId', + [], + is_static=True) ## channel.h: ns3::Channel::Channel() [constructor] - cls.add_constructor([], visibility='public') + cls.add_constructor([]) ## channel.h: ns3::Channel::Channel(std::string name) [constructor] - cls.add_constructor([param('std::string', 'name')], visibility='public') + cls.add_constructor([param('std::string', 'name')]) ## channel.h: void ns3::Channel::SetName(std::string arg0) [member function] - cls.add_method('SetName', 'void', [param('std::string', 'arg0')]) + cls.add_method('SetName', + 'void', + [param('std::string', 'arg0')]) ## channel.h: std::string ns3::Channel::GetName() [member function] - cls.add_method('GetName', 'std::string', []) + cls.add_method('GetName', + 'std::string', + []) ## channel.h: uint32_t ns3::Channel::GetNDevices() const [member function] - cls.add_method('GetNDevices', 'uint32_t', [], is_pure_virtual=True, is_const=True, is_virtual=True) + cls.add_method('GetNDevices', + 'uint32_t', + [], + is_pure_virtual=True, is_const=True, is_virtual=True) ## channel.h: ns3::Ptr ns3::Channel::GetDevice(uint32_t i) const [member function] - cls.add_method('GetDevice', 'ns3::Ptr< ns3::NetDevice >', [param('uint32_t', 'i')], is_pure_virtual=True, is_const=True, is_virtual=True) + cls.add_method('GetDevice', + 'ns3::Ptr< ns3::NetDevice >', + [param('uint32_t', 'i')], + is_pure_virtual=True, is_const=True, is_virtual=True) return def register_Ns3TcpSocket_methods(root_module, cls): ## tcp-socket.h: static ns3::TypeId ns3::TcpSocket::GetTypeId() [member function] - cls.add_method('GetTypeId', 'ns3::TypeId', [], is_static=True) + cls.add_method('GetTypeId', + 'ns3::TypeId', + [], + is_static=True) ## tcp-socket.h: ns3::TcpSocket::TcpSocket() [constructor] - cls.add_constructor([], visibility='public') + cls.add_constructor([]) ## tcp-socket.h: void ns3::TcpSocket::SetSndBufSize(uint32_t size) [member function] - cls.add_method('SetSndBufSize', 'void', [param('uint32_t', 'size')], is_pure_virtual=True, visibility='private', is_virtual=True) + cls.add_method('SetSndBufSize', + 'void', + [param('uint32_t', 'size')], + is_pure_virtual=True, visibility='private', is_virtual=True) ## tcp-socket.h: uint32_t ns3::TcpSocket::GetSndBufSize() const [member function] - cls.add_method('GetSndBufSize', 'uint32_t', [], is_pure_virtual=True, is_const=True, visibility='private', is_virtual=True) + cls.add_method('GetSndBufSize', + 'uint32_t', + [], + is_pure_virtual=True, is_const=True, visibility='private', is_virtual=True) ## tcp-socket.h: void ns3::TcpSocket::SetRcvBufSize(uint32_t size) [member function] - cls.add_method('SetRcvBufSize', 'void', [param('uint32_t', 'size')], is_pure_virtual=True, visibility='private', is_virtual=True) + cls.add_method('SetRcvBufSize', + 'void', + [param('uint32_t', 'size')], + is_pure_virtual=True, visibility='private', is_virtual=True) ## tcp-socket.h: uint32_t ns3::TcpSocket::GetRcvBufSize() const [member function] - cls.add_method('GetRcvBufSize', 'uint32_t', [], is_pure_virtual=True, is_const=True, visibility='private', is_virtual=True) + cls.add_method('GetRcvBufSize', + 'uint32_t', + [], + is_pure_virtual=True, is_const=True, visibility='private', is_virtual=True) ## tcp-socket.h: void ns3::TcpSocket::SetSegSize(uint32_t size) [member function] - cls.add_method('SetSegSize', 'void', [param('uint32_t', 'size')], is_pure_virtual=True, visibility='private', is_virtual=True) + cls.add_method('SetSegSize', + 'void', + [param('uint32_t', 'size')], + is_pure_virtual=True, visibility='private', is_virtual=True) ## tcp-socket.h: uint32_t ns3::TcpSocket::GetSegSize() const [member function] - cls.add_method('GetSegSize', 'uint32_t', [], is_pure_virtual=True, is_const=True, visibility='private', is_virtual=True) + cls.add_method('GetSegSize', + 'uint32_t', + [], + is_pure_virtual=True, is_const=True, visibility='private', is_virtual=True) ## tcp-socket.h: void ns3::TcpSocket::SetAdvWin(uint32_t window) [member function] - cls.add_method('SetAdvWin', 'void', [param('uint32_t', 'window')], is_pure_virtual=True, visibility='private', is_virtual=True) + cls.add_method('SetAdvWin', + 'void', + [param('uint32_t', 'window')], + is_pure_virtual=True, visibility='private', is_virtual=True) ## tcp-socket.h: uint32_t ns3::TcpSocket::GetAdvWin() const [member function] - cls.add_method('GetAdvWin', 'uint32_t', [], is_pure_virtual=True, is_const=True, visibility='private', is_virtual=True) + cls.add_method('GetAdvWin', + 'uint32_t', + [], + is_pure_virtual=True, is_const=True, visibility='private', is_virtual=True) ## tcp-socket.h: void ns3::TcpSocket::SetSSThresh(uint32_t threshold) [member function] - cls.add_method('SetSSThresh', 'void', [param('uint32_t', 'threshold')], is_pure_virtual=True, visibility='private', is_virtual=True) + cls.add_method('SetSSThresh', + 'void', + [param('uint32_t', 'threshold')], + is_pure_virtual=True, visibility='private', is_virtual=True) ## tcp-socket.h: uint32_t ns3::TcpSocket::GetSSThresh() const [member function] - cls.add_method('GetSSThresh', 'uint32_t', [], is_pure_virtual=True, is_const=True, visibility='private', is_virtual=True) + cls.add_method('GetSSThresh', + 'uint32_t', + [], + is_pure_virtual=True, is_const=True, visibility='private', is_virtual=True) ## tcp-socket.h: void ns3::TcpSocket::SetInitialCwnd(uint32_t count) [member function] - cls.add_method('SetInitialCwnd', 'void', [param('uint32_t', 'count')], is_pure_virtual=True, visibility='private', is_virtual=True) + cls.add_method('SetInitialCwnd', + 'void', + [param('uint32_t', 'count')], + is_pure_virtual=True, visibility='private', is_virtual=True) ## tcp-socket.h: uint32_t ns3::TcpSocket::GetInitialCwnd() const [member function] - cls.add_method('GetInitialCwnd', 'uint32_t', [], is_pure_virtual=True, is_const=True, visibility='private', is_virtual=True) + cls.add_method('GetInitialCwnd', + 'uint32_t', + [], + is_pure_virtual=True, is_const=True, visibility='private', is_virtual=True) ## tcp-socket.h: void ns3::TcpSocket::SetConnTimeout(ns3::Time timeout) [member function] - cls.add_method('SetConnTimeout', 'void', [param('ns3::Time', 'timeout')], is_pure_virtual=True, visibility='private', is_virtual=True) + cls.add_method('SetConnTimeout', + 'void', + [param('ns3::Time', 'timeout')], + is_pure_virtual=True, visibility='private', is_virtual=True) ## tcp-socket.h: ns3::Time ns3::TcpSocket::GetConnTimeout() const [member function] - cls.add_method('GetConnTimeout', 'ns3::Time', [], is_pure_virtual=True, is_const=True, visibility='private', is_virtual=True) + cls.add_method('GetConnTimeout', + 'ns3::Time', + [], + is_pure_virtual=True, is_const=True, visibility='private', is_virtual=True) ## tcp-socket.h: void ns3::TcpSocket::SetConnCount(uint32_t count) [member function] - cls.add_method('SetConnCount', 'void', [param('uint32_t', 'count')], is_pure_virtual=True, visibility='private', is_virtual=True) + cls.add_method('SetConnCount', + 'void', + [param('uint32_t', 'count')], + is_pure_virtual=True, visibility='private', is_virtual=True) ## tcp-socket.h: uint32_t ns3::TcpSocket::GetConnCount() const [member function] - cls.add_method('GetConnCount', 'uint32_t', [], is_pure_virtual=True, is_const=True, visibility='private', is_virtual=True) + cls.add_method('GetConnCount', + 'uint32_t', + [], + is_pure_virtual=True, is_const=True, visibility='private', is_virtual=True) ## tcp-socket.h: void ns3::TcpSocket::SetDelAckTimeout(ns3::Time timeout) [member function] - cls.add_method('SetDelAckTimeout', 'void', [param('ns3::Time', 'timeout')], is_pure_virtual=True, visibility='private', is_virtual=True) + cls.add_method('SetDelAckTimeout', + 'void', + [param('ns3::Time', 'timeout')], + is_pure_virtual=True, visibility='private', is_virtual=True) ## tcp-socket.h: ns3::Time ns3::TcpSocket::GetDelAckTimeout() const [member function] - cls.add_method('GetDelAckTimeout', 'ns3::Time', [], is_pure_virtual=True, is_const=True, visibility='private', is_virtual=True) + cls.add_method('GetDelAckTimeout', + 'ns3::Time', + [], + is_pure_virtual=True, is_const=True, visibility='private', is_virtual=True) ## tcp-socket.h: void ns3::TcpSocket::SetDelAckMaxCount(uint32_t count) [member function] - cls.add_method('SetDelAckMaxCount', 'void', [param('uint32_t', 'count')], is_pure_virtual=True, visibility='private', is_virtual=True) + cls.add_method('SetDelAckMaxCount', + 'void', + [param('uint32_t', 'count')], + is_pure_virtual=True, visibility='private', is_virtual=True) ## tcp-socket.h: uint32_t ns3::TcpSocket::GetDelAckMaxCount() const [member function] - cls.add_method('GetDelAckMaxCount', 'uint32_t', [], is_pure_virtual=True, is_const=True, visibility='private', is_virtual=True) + cls.add_method('GetDelAckMaxCount', + 'uint32_t', + [], + is_pure_virtual=True, is_const=True, visibility='private', is_virtual=True) return def register_Ns3EthernetHeader_methods(root_module, cls): ## ethernet-header.h: ns3::EthernetHeader::EthernetHeader(bool hasPreamble) [constructor] - cls.add_constructor([param('bool', 'hasPreamble')], visibility='public') + cls.add_constructor([param('bool', 'hasPreamble')]) ## ethernet-header.h: ns3::EthernetHeader::EthernetHeader() [constructor] - cls.add_constructor([], visibility='public') + cls.add_constructor([]) ## ethernet-header.h: void ns3::EthernetHeader::SetLengthType(uint16_t size) [member function] - cls.add_method('SetLengthType', 'void', [param('uint16_t', 'size')]) + cls.add_method('SetLengthType', + 'void', + [param('uint16_t', 'size')]) ## ethernet-header.h: void ns3::EthernetHeader::SetSource(ns3::Mac48Address source) [member function] - cls.add_method('SetSource', 'void', [param('ns3::Mac48Address', 'source')]) + cls.add_method('SetSource', + 'void', + [param('ns3::Mac48Address', 'source')]) ## ethernet-header.h: void ns3::EthernetHeader::SetDestination(ns3::Mac48Address destination) [member function] - cls.add_method('SetDestination', 'void', [param('ns3::Mac48Address', 'destination')]) + cls.add_method('SetDestination', + 'void', + [param('ns3::Mac48Address', 'destination')]) ## ethernet-header.h: void ns3::EthernetHeader::SetPreambleSfd(uint64_t preambleSfd) [member function] - cls.add_method('SetPreambleSfd', 'void', [param('uint64_t', 'preambleSfd')]) + cls.add_method('SetPreambleSfd', + 'void', + [param('uint64_t', 'preambleSfd')]) ## ethernet-header.h: uint16_t ns3::EthernetHeader::GetLengthType() const [member function] - cls.add_method('GetLengthType', 'uint16_t', [], is_const=True) + cls.add_method('GetLengthType', + 'uint16_t', + [], + is_const=True) ## ethernet-header.h: ns3::ethernet_header_t ns3::EthernetHeader::GetPacketType() const [member function] - cls.add_method('GetPacketType', 'ns3::ethernet_header_t', [], is_const=True) + cls.add_method('GetPacketType', + 'ns3::ethernet_header_t', + [], + is_const=True) ## ethernet-header.h: ns3::Mac48Address ns3::EthernetHeader::GetSource() const [member function] - cls.add_method('GetSource', 'ns3::Mac48Address', [], is_const=True) + cls.add_method('GetSource', + 'ns3::Mac48Address', + [], + is_const=True) ## ethernet-header.h: ns3::Mac48Address ns3::EthernetHeader::GetDestination() const [member function] - cls.add_method('GetDestination', 'ns3::Mac48Address', [], is_const=True) + cls.add_method('GetDestination', + 'ns3::Mac48Address', + [], + is_const=True) ## ethernet-header.h: uint64_t ns3::EthernetHeader::GetPreambleSfd() const [member function] - cls.add_method('GetPreambleSfd', 'uint64_t', [], is_const=True) + cls.add_method('GetPreambleSfd', + 'uint64_t', + [], + is_const=True) ## ethernet-header.h: uint32_t ns3::EthernetHeader::GetHeaderSize() const [member function] - cls.add_method('GetHeaderSize', 'uint32_t', [], is_const=True) + cls.add_method('GetHeaderSize', + 'uint32_t', + [], + is_const=True) ## ethernet-header.h: static ns3::TypeId ns3::EthernetHeader::GetTypeId() [member function] - cls.add_method('GetTypeId', 'ns3::TypeId', [], is_static=True) + cls.add_method('GetTypeId', + 'ns3::TypeId', + [], + is_static=True) ## ethernet-header.h: ns3::TypeId ns3::EthernetHeader::GetInstanceTypeId() const [member function] - cls.add_method('GetInstanceTypeId', 'ns3::TypeId', [], is_const=True, is_virtual=True) + cls.add_method('GetInstanceTypeId', + 'ns3::TypeId', + [], + is_const=True, is_virtual=True) ## ethernet-header.h: void ns3::EthernetHeader::Print(std::ostream & os) const [member function] - cls.add_method('Print', 'void', [param('std::ostream&', 'os')], is_const=True, is_virtual=True) + cls.add_method('Print', + 'void', + [param('std::ostream&', 'os')], + is_const=True, is_virtual=True) ## ethernet-header.h: uint32_t ns3::EthernetHeader::GetSerializedSize() const [member function] - cls.add_method('GetSerializedSize', 'uint32_t', [], is_const=True, is_virtual=True) + cls.add_method('GetSerializedSize', + 'uint32_t', + [], + is_const=True, is_virtual=True) ## ethernet-header.h: void ns3::EthernetHeader::Serialize(ns3::Buffer::Iterator start) const [member function] - cls.add_method('Serialize', 'void', [param('ns3::Buffer::Iterator', 'start')], is_const=True, is_virtual=True) + cls.add_method('Serialize', + 'void', + [param('ns3::Buffer::Iterator', 'start')], + is_const=True, is_virtual=True) ## ethernet-header.h: uint32_t ns3::EthernetHeader::Deserialize(ns3::Buffer::Iterator start) [member function] - cls.add_method('Deserialize', 'uint32_t', [param('ns3::Buffer::Iterator', 'start')], is_virtual=True) + cls.add_method('Deserialize', + 'uint32_t', + [param('ns3::Buffer::Iterator', 'start')], + is_virtual=True) return def register_Ns3SocketIpTtlTag_methods(root_module, cls): ## socket.h: ns3::SocketIpTtlTag::SocketIpTtlTag() [constructor] - cls.add_constructor([], visibility='public') + cls.add_constructor([]) ## socket.h: void ns3::SocketIpTtlTag::SetTtl(uint8_t ttl) [member function] - cls.add_method('SetTtl', 'void', [param('uint8_t', 'ttl')]) + cls.add_method('SetTtl', + 'void', + [param('uint8_t', 'ttl')]) ## socket.h: uint8_t ns3::SocketIpTtlTag::GetTtl() const [member function] - cls.add_method('GetTtl', 'uint8_t', [], is_const=True) + cls.add_method('GetTtl', + 'uint8_t', + [], + is_const=True) ## socket.h: static ns3::TypeId ns3::SocketIpTtlTag::GetTypeId() [member function] - cls.add_method('GetTypeId', 'ns3::TypeId', [], is_static=True) + cls.add_method('GetTypeId', + 'ns3::TypeId', + [], + is_static=True) ## socket.h: ns3::TypeId ns3::SocketIpTtlTag::GetInstanceTypeId() const [member function] - cls.add_method('GetInstanceTypeId', 'ns3::TypeId', [], is_const=True, is_virtual=True) + cls.add_method('GetInstanceTypeId', + 'ns3::TypeId', + [], + is_const=True, is_virtual=True) ## socket.h: uint32_t ns3::SocketIpTtlTag::GetSerializedSize() const [member function] - cls.add_method('GetSerializedSize', 'uint32_t', [], is_const=True, is_virtual=True) + cls.add_method('GetSerializedSize', + 'uint32_t', + [], + is_const=True, is_virtual=True) ## socket.h: void ns3::SocketIpTtlTag::Serialize(ns3::TagBuffer i) const [member function] - cls.add_method('Serialize', 'void', [param('ns3::TagBuffer', 'i')], is_const=True, is_virtual=True) + cls.add_method('Serialize', + 'void', + [param('ns3::TagBuffer', 'i')], + is_const=True, is_virtual=True) ## socket.h: void ns3::SocketIpTtlTag::Deserialize(ns3::TagBuffer i) [member function] - cls.add_method('Deserialize', 'void', [param('ns3::TagBuffer', 'i')], is_virtual=True) + cls.add_method('Deserialize', + 'void', + [param('ns3::TagBuffer', 'i')], + is_virtual=True) ## socket.h: void ns3::SocketIpTtlTag::Print(std::ostream & os) const [member function] - cls.add_method('Print', 'void', [param('std::ostream&', 'os')], is_const=True, is_virtual=True) + cls.add_method('Print', + 'void', + [param('std::ostream&', 'os')], + is_const=True, is_virtual=True) return def register_Ns3Ipv4_methods(root_module, cls): ## ipv4.h: static ns3::TypeId ns3::Ipv4::GetTypeId() [member function] - cls.add_method('GetTypeId', 'ns3::TypeId', [], is_static=True) + cls.add_method('GetTypeId', + 'ns3::TypeId', + [], + is_static=True) ## ipv4.h: ns3::Ipv4::Ipv4() [constructor] - cls.add_constructor([], visibility='public') + cls.add_constructor([]) ## ipv4.h: void ns3::Ipv4::AddRoutingProtocol(ns3::Ptr routingProtocol, int16_t priority) [member function] - cls.add_method('AddRoutingProtocol', 'void', [param('ns3::Ptr< ns3::Ipv4RoutingProtocol >', 'routingProtocol'), param('int16_t', 'priority')], is_pure_virtual=True, is_virtual=True) + cls.add_method('AddRoutingProtocol', + 'void', + [param('ns3::Ptr< ns3::Ipv4RoutingProtocol >', 'routingProtocol'), param('int16_t', 'priority')], + is_pure_virtual=True, is_virtual=True) ## ipv4.h: void ns3::Ipv4::AddHostRouteTo(ns3::Ipv4Address dest, ns3::Ipv4Address nextHop, uint32_t interface) [member function] - cls.add_method('AddHostRouteTo', 'void', [param('ns3::Ipv4Address', 'dest'), param('ns3::Ipv4Address', 'nextHop'), param('uint32_t', 'interface')], is_pure_virtual=True, is_virtual=True) + cls.add_method('AddHostRouteTo', + 'void', + [param('ns3::Ipv4Address', 'dest'), param('ns3::Ipv4Address', 'nextHop'), param('uint32_t', 'interface')], + is_pure_virtual=True, is_virtual=True) ## ipv4.h: void ns3::Ipv4::AddHostRouteTo(ns3::Ipv4Address dest, uint32_t interface) [member function] - cls.add_method('AddHostRouteTo', 'void', [param('ns3::Ipv4Address', 'dest'), param('uint32_t', 'interface')], is_pure_virtual=True, is_virtual=True) + cls.add_method('AddHostRouteTo', + 'void', + [param('ns3::Ipv4Address', 'dest'), param('uint32_t', 'interface')], + is_pure_virtual=True, is_virtual=True) ## ipv4.h: void ns3::Ipv4::AddNetworkRouteTo(ns3::Ipv4Address network, ns3::Ipv4Mask networkMask, ns3::Ipv4Address nextHop, uint32_t interface) [member function] - cls.add_method('AddNetworkRouteTo', 'void', [param('ns3::Ipv4Address', 'network'), param('ns3::Ipv4Mask', 'networkMask'), param('ns3::Ipv4Address', 'nextHop'), param('uint32_t', 'interface')], is_pure_virtual=True, is_virtual=True) + cls.add_method('AddNetworkRouteTo', + 'void', + [param('ns3::Ipv4Address', 'network'), param('ns3::Ipv4Mask', 'networkMask'), param('ns3::Ipv4Address', 'nextHop'), param('uint32_t', 'interface')], + is_pure_virtual=True, is_virtual=True) ## ipv4.h: void ns3::Ipv4::AddNetworkRouteTo(ns3::Ipv4Address network, ns3::Ipv4Mask networkMask, uint32_t interface) [member function] - cls.add_method('AddNetworkRouteTo', 'void', [param('ns3::Ipv4Address', 'network'), param('ns3::Ipv4Mask', 'networkMask'), param('uint32_t', 'interface')], is_pure_virtual=True, is_virtual=True) + cls.add_method('AddNetworkRouteTo', + 'void', + [param('ns3::Ipv4Address', 'network'), param('ns3::Ipv4Mask', 'networkMask'), param('uint32_t', 'interface')], + is_pure_virtual=True, is_virtual=True) ## ipv4.h: void ns3::Ipv4::SetDefaultRoute(ns3::Ipv4Address nextHop, uint32_t interface) [member function] - cls.add_method('SetDefaultRoute', 'void', [param('ns3::Ipv4Address', 'nextHop'), param('uint32_t', 'interface')], is_pure_virtual=True, is_virtual=True) + cls.add_method('SetDefaultRoute', + 'void', + [param('ns3::Ipv4Address', 'nextHop'), param('uint32_t', 'interface')], + is_pure_virtual=True, is_virtual=True) ## ipv4.h: uint32_t ns3::Ipv4::GetNRoutes() [member function] - cls.add_method('GetNRoutes', 'uint32_t', [], is_pure_virtual=True, is_virtual=True) + cls.add_method('GetNRoutes', + 'uint32_t', + [], + is_pure_virtual=True, is_virtual=True) ## ipv4.h: ns3::Ipv4Route ns3::Ipv4::GetRoute(uint32_t i) [member function] - cls.add_method('GetRoute', 'ns3::Ipv4Route', [param('uint32_t', 'i')], is_pure_virtual=True, is_virtual=True) + cls.add_method('GetRoute', + 'ns3::Ipv4Route', + [param('uint32_t', 'i')], + is_pure_virtual=True, is_virtual=True) ## ipv4.h: void ns3::Ipv4::RemoveRoute(uint32_t i) [member function] - cls.add_method('RemoveRoute', 'void', [param('uint32_t', 'i')], is_pure_virtual=True, is_virtual=True) + cls.add_method('RemoveRoute', + 'void', + [param('uint32_t', 'i')], + is_pure_virtual=True, is_virtual=True) ## ipv4.h: void ns3::Ipv4::AddMulticastRoute(ns3::Ipv4Address origin, ns3::Ipv4Address group, uint32_t inputInterface, std::vector > outputInterfaces) [member function] - cls.add_method('AddMulticastRoute', 'void', [param('ns3::Ipv4Address', 'origin'), param('ns3::Ipv4Address', 'group'), param('uint32_t', 'inputInterface'), param('std::vector< unsigned int, std::allocator< unsigned int > >', 'outputInterfaces')], is_pure_virtual=True, is_virtual=True) + cls.add_method('AddMulticastRoute', + 'void', + [param('ns3::Ipv4Address', 'origin'), param('ns3::Ipv4Address', 'group'), param('uint32_t', 'inputInterface'), param('std::vector< unsigned int, std::allocator< unsigned int > >', 'outputInterfaces')], + is_pure_virtual=True, is_virtual=True) ## ipv4.h: void ns3::Ipv4::RemoveMulticastRoute(ns3::Ipv4Address origin, ns3::Ipv4Address group, uint32_t inputInterface) [member function] - cls.add_method('RemoveMulticastRoute', 'void', [param('ns3::Ipv4Address', 'origin'), param('ns3::Ipv4Address', 'group'), param('uint32_t', 'inputInterface')], is_pure_virtual=True, is_virtual=True) + cls.add_method('RemoveMulticastRoute', + 'void', + [param('ns3::Ipv4Address', 'origin'), param('ns3::Ipv4Address', 'group'), param('uint32_t', 'inputInterface')], + is_pure_virtual=True, is_virtual=True) ## ipv4.h: void ns3::Ipv4::SetDefaultMulticastRoute(uint32_t outputInterface) [member function] - cls.add_method('SetDefaultMulticastRoute', 'void', [param('uint32_t', 'outputInterface')], is_pure_virtual=True, is_virtual=True) + cls.add_method('SetDefaultMulticastRoute', + 'void', + [param('uint32_t', 'outputInterface')], + is_pure_virtual=True, is_virtual=True) ## ipv4.h: uint32_t ns3::Ipv4::GetNMulticastRoutes() const [member function] - cls.add_method('GetNMulticastRoutes', 'uint32_t', [], is_pure_virtual=True, is_const=True, is_virtual=True) + cls.add_method('GetNMulticastRoutes', + 'uint32_t', + [], + is_pure_virtual=True, is_const=True, is_virtual=True) ## ipv4.h: ns3::Ipv4MulticastRoute ns3::Ipv4::GetMulticastRoute(uint32_t i) const [member function] - cls.add_method('GetMulticastRoute', 'ns3::Ipv4MulticastRoute', [param('uint32_t', 'i')], is_pure_virtual=True, is_const=True, is_virtual=True) + cls.add_method('GetMulticastRoute', + 'ns3::Ipv4MulticastRoute', + [param('uint32_t', 'i')], + is_pure_virtual=True, is_const=True, is_virtual=True) ## ipv4.h: void ns3::Ipv4::RemoveMulticastRoute(uint32_t i) [member function] - cls.add_method('RemoveMulticastRoute', 'void', [param('uint32_t', 'i')], is_pure_virtual=True, is_virtual=True) + cls.add_method('RemoveMulticastRoute', + 'void', + [param('uint32_t', 'i')], + is_pure_virtual=True, is_virtual=True) ## ipv4.h: uint32_t ns3::Ipv4::AddInterface(ns3::Ptr device) [member function] - cls.add_method('AddInterface', 'uint32_t', [param('ns3::Ptr< ns3::NetDevice >', 'device')], is_pure_virtual=True, is_virtual=True) + cls.add_method('AddInterface', + 'uint32_t', + [param('ns3::Ptr< ns3::NetDevice >', 'device')], + is_pure_virtual=True, is_virtual=True) ## ipv4.h: uint32_t ns3::Ipv4::GetNInterfaces() [member function] - cls.add_method('GetNInterfaces', 'uint32_t', [], is_pure_virtual=True, is_virtual=True) + cls.add_method('GetNInterfaces', + 'uint32_t', + [], + is_pure_virtual=True, is_virtual=True) ## ipv4.h: uint32_t ns3::Ipv4::FindInterfaceForAddr(ns3::Ipv4Address addr) const [member function] - cls.add_method('FindInterfaceForAddr', 'uint32_t', [param('ns3::Ipv4Address', 'addr')], is_pure_virtual=True, is_const=True, is_virtual=True) + cls.add_method('FindInterfaceForAddr', + 'uint32_t', + [param('ns3::Ipv4Address', 'addr')], + is_pure_virtual=True, is_const=True, is_virtual=True) ## ipv4.h: uint32_t ns3::Ipv4::FindInterfaceForAddr(ns3::Ipv4Address addr, ns3::Ipv4Mask mask) const [member function] - cls.add_method('FindInterfaceForAddr', 'uint32_t', [param('ns3::Ipv4Address', 'addr'), param('ns3::Ipv4Mask', 'mask')], is_pure_virtual=True, is_const=True, is_virtual=True) + cls.add_method('FindInterfaceForAddr', + 'uint32_t', + [param('ns3::Ipv4Address', 'addr'), param('ns3::Ipv4Mask', 'mask')], + is_pure_virtual=True, is_const=True, is_virtual=True) ## ipv4.h: int32_t ns3::Ipv4::FindInterfaceForDevice(ns3::Ptr nd) const [member function] - cls.add_method('FindInterfaceForDevice', 'int32_t', [param('ns3::Ptr< ns3::NetDevice >', 'nd')], is_pure_virtual=True, is_const=True, is_virtual=True) + cls.add_method('FindInterfaceForDevice', + 'int32_t', + [param('ns3::Ptr< ns3::NetDevice >', 'nd')], + is_pure_virtual=True, is_const=True, is_virtual=True) ## ipv4.h: ns3::Ptr ns3::Ipv4::GetNetDevice(uint32_t i) [member function] - cls.add_method('GetNetDevice', 'ns3::Ptr< ns3::NetDevice >', [param('uint32_t', 'i')], is_pure_virtual=True, is_virtual=True) + cls.add_method('GetNetDevice', + 'ns3::Ptr< ns3::NetDevice >', + [param('uint32_t', 'i')], + is_pure_virtual=True, is_virtual=True) ## ipv4.h: void ns3::Ipv4::JoinMulticastGroup(ns3::Ipv4Address origin, ns3::Ipv4Address group) [member function] - cls.add_method('JoinMulticastGroup', 'void', [param('ns3::Ipv4Address', 'origin'), param('ns3::Ipv4Address', 'group')], is_pure_virtual=True, is_virtual=True) + cls.add_method('JoinMulticastGroup', + 'void', + [param('ns3::Ipv4Address', 'origin'), param('ns3::Ipv4Address', 'group')], + is_pure_virtual=True, is_virtual=True) ## ipv4.h: void ns3::Ipv4::LeaveMulticastGroup(ns3::Ipv4Address origin, ns3::Ipv4Address group) [member function] - cls.add_method('LeaveMulticastGroup', 'void', [param('ns3::Ipv4Address', 'origin'), param('ns3::Ipv4Address', 'group')], is_pure_virtual=True, is_virtual=True) + cls.add_method('LeaveMulticastGroup', + 'void', + [param('ns3::Ipv4Address', 'origin'), param('ns3::Ipv4Address', 'group')], + is_pure_virtual=True, is_virtual=True) ## ipv4.h: void ns3::Ipv4::SetAddress(uint32_t i, ns3::Ipv4Address address) [member function] - cls.add_method('SetAddress', 'void', [param('uint32_t', 'i'), param('ns3::Ipv4Address', 'address')], is_pure_virtual=True, is_virtual=True) + cls.add_method('SetAddress', + 'void', + [param('uint32_t', 'i'), param('ns3::Ipv4Address', 'address')], + is_pure_virtual=True, is_virtual=True) ## ipv4.h: void ns3::Ipv4::SetNetworkMask(uint32_t i, ns3::Ipv4Mask mask) [member function] - cls.add_method('SetNetworkMask', 'void', [param('uint32_t', 'i'), param('ns3::Ipv4Mask', 'mask')], is_pure_virtual=True, is_virtual=True) + cls.add_method('SetNetworkMask', + 'void', + [param('uint32_t', 'i'), param('ns3::Ipv4Mask', 'mask')], + is_pure_virtual=True, is_virtual=True) ## ipv4.h: ns3::Ipv4Mask ns3::Ipv4::GetNetworkMask(uint32_t i) const [member function] - cls.add_method('GetNetworkMask', 'ns3::Ipv4Mask', [param('uint32_t', 'i')], is_pure_virtual=True, is_const=True, is_virtual=True) + cls.add_method('GetNetworkMask', + 'ns3::Ipv4Mask', + [param('uint32_t', 'i')], + is_pure_virtual=True, is_const=True, is_virtual=True) ## ipv4.h: void ns3::Ipv4::SetMetric(uint32_t i, uint16_t metric) [member function] - cls.add_method('SetMetric', 'void', [param('uint32_t', 'i'), param('uint16_t', 'metric')], is_pure_virtual=True, is_virtual=True) + cls.add_method('SetMetric', + 'void', + [param('uint32_t', 'i'), param('uint16_t', 'metric')], + is_pure_virtual=True, is_virtual=True) ## ipv4.h: uint16_t ns3::Ipv4::GetMetric(uint32_t i) const [member function] - cls.add_method('GetMetric', 'uint16_t', [param('uint32_t', 'i')], is_pure_virtual=True, is_const=True, is_virtual=True) + cls.add_method('GetMetric', + 'uint16_t', + [param('uint32_t', 'i')], + is_pure_virtual=True, is_const=True, is_virtual=True) ## ipv4.h: ns3::Ipv4Address ns3::Ipv4::GetAddress(uint32_t i) const [member function] - cls.add_method('GetAddress', 'ns3::Ipv4Address', [param('uint32_t', 'i')], is_pure_virtual=True, is_const=True, is_virtual=True) + cls.add_method('GetAddress', + 'ns3::Ipv4Address', + [param('uint32_t', 'i')], + is_pure_virtual=True, is_const=True, is_virtual=True) ## ipv4.h: ns3::Ipv4Address ns3::Ipv4::GetSourceAddress(ns3::Ipv4Address destination) const [member function] - cls.add_method('GetSourceAddress', 'ns3::Ipv4Address', [param('ns3::Ipv4Address', 'destination')], is_pure_virtual=True, is_const=True, is_virtual=True) + cls.add_method('GetSourceAddress', + 'ns3::Ipv4Address', + [param('ns3::Ipv4Address', 'destination')], + is_pure_virtual=True, is_const=True, is_virtual=True) ## ipv4.h: bool ns3::Ipv4::GetIfIndexForDestination(ns3::Ipv4Address dest, uint32_t & ifIndex) const [member function] - cls.add_method('GetIfIndexForDestination', 'bool', [param('ns3::Ipv4Address', 'dest'), param('uint32_t&', 'ifIndex')], is_pure_virtual=True, is_const=True, is_virtual=True) + cls.add_method('GetIfIndexForDestination', + 'bool', + [param('ns3::Ipv4Address', 'dest'), param('uint32_t&', 'ifIndex')], + is_pure_virtual=True, is_const=True, is_virtual=True) ## ipv4.h: uint16_t ns3::Ipv4::GetMtu(uint32_t i) const [member function] - cls.add_method('GetMtu', 'uint16_t', [param('uint32_t', 'i')], is_pure_virtual=True, is_const=True, is_virtual=True) + cls.add_method('GetMtu', + 'uint16_t', + [param('uint32_t', 'i')], + is_pure_virtual=True, is_const=True, is_virtual=True) ## ipv4.h: bool ns3::Ipv4::IsUp(uint32_t i) const [member function] - cls.add_method('IsUp', 'bool', [param('uint32_t', 'i')], is_pure_virtual=True, is_const=True, is_virtual=True) + cls.add_method('IsUp', + 'bool', + [param('uint32_t', 'i')], + is_pure_virtual=True, is_const=True, is_virtual=True) ## ipv4.h: void ns3::Ipv4::SetUp(uint32_t i) [member function] - cls.add_method('SetUp', 'void', [param('uint32_t', 'i')], is_pure_virtual=True, is_virtual=True) + cls.add_method('SetUp', + 'void', + [param('uint32_t', 'i')], + is_pure_virtual=True, is_virtual=True) ## ipv4.h: void ns3::Ipv4::SetDown(uint32_t i) [member function] - cls.add_method('SetDown', 'void', [param('uint32_t', 'i')], is_pure_virtual=True, is_virtual=True) + cls.add_method('SetDown', + 'void', + [param('uint32_t', 'i')], + is_pure_virtual=True, is_virtual=True) ## ipv4.h: uint32_t ns3::Ipv4::GetIfIndexByAddress(ns3::Ipv4Address addr, ns3::Ipv4Mask mask=ns3::Ipv4Mask(((const char*)"255.255.255.255"))) [member function] - cls.add_method('GetIfIndexByAddress', 'uint32_t', [param('ns3::Ipv4Address', 'addr'), param('ns3::Ipv4Mask', 'mask', default_value='ns3::Ipv4Mask(((const char*)"255.255.255.255"))')], is_virtual=True) + cls.add_method('GetIfIndexByAddress', + 'uint32_t', + [param('ns3::Ipv4Address', 'addr'), param('ns3::Ipv4Mask', 'mask', default_value='ns3::Ipv4Mask(((const char*)"255.255.255.255"))')], + is_virtual=True) return def register_Ns3SocketFactory_methods(root_module, cls): ## socket-factory.h: static ns3::TypeId ns3::SocketFactory::GetTypeId() [member function] - cls.add_method('GetTypeId', 'ns3::TypeId', [], is_static=True) + cls.add_method('GetTypeId', + 'ns3::TypeId', + [], + is_static=True) ## socket-factory.h: ns3::SocketFactory::SocketFactory() [constructor] - cls.add_constructor([], visibility='public') + cls.add_constructor([]) ## socket-factory.h: ns3::Ptr ns3::SocketFactory::CreateSocket() [member function] - cls.add_method('CreateSocket', 'ns3::Ptr< ns3::Socket >', [], is_pure_virtual=True, is_virtual=True) + cls.add_method('CreateSocket', + 'ns3::Ptr< ns3::Socket >', + [], + is_pure_virtual=True, is_virtual=True) return def register_Ns3DropTailQueue_methods(root_module, cls): ## drop-tail-queue.h: static ns3::TypeId ns3::DropTailQueue::GetTypeId() [member function] - cls.add_method('GetTypeId', 'ns3::TypeId', [], is_static=True) + cls.add_method('GetTypeId', + 'ns3::TypeId', + [], + is_static=True) ## drop-tail-queue.h: ns3::DropTailQueue::DropTailQueue() [constructor] - cls.add_constructor([], visibility='public') + cls.add_constructor([]) ## drop-tail-queue.h: bool ns3::DropTailQueue::DoEnqueue(ns3::Ptr p) [member function] - cls.add_method('DoEnqueue', 'bool', [param('ns3::Ptr< ns3::Packet >', 'p')], visibility='private', is_virtual=True) + cls.add_method('DoEnqueue', + 'bool', + [param('ns3::Ptr< ns3::Packet >', 'p')], + visibility='private', is_virtual=True) ## drop-tail-queue.h: ns3::Ptr ns3::DropTailQueue::DoDequeue() [member function] - cls.add_method('DoDequeue', 'ns3::Ptr< ns3::Packet >', [], visibility='private', is_virtual=True) + cls.add_method('DoDequeue', + 'ns3::Ptr< ns3::Packet >', + [], + visibility='private', is_virtual=True) ## drop-tail-queue.h: ns3::Ptr ns3::DropTailQueue::DoPeek() const [member function] - cls.add_method('DoPeek', 'ns3::Ptr< ns3::Packet >', [], is_const=True, visibility='private', is_virtual=True) + cls.add_method('DoPeek', + 'ns3::Ptr< ns3::Packet >', + [], + is_const=True, visibility='private', is_virtual=True) return def register_Ns3EthernetTrailer_methods(root_module, cls): ## ethernet-trailer.h: ns3::EthernetTrailer::EthernetTrailer() [constructor] - cls.add_constructor([], visibility='public') + cls.add_constructor([]) ## ethernet-trailer.h: static void ns3::EthernetTrailer::EnableFcs(bool enable) [member function] - cls.add_method('EnableFcs', 'void', [param('bool', 'enable')], is_static=True) + cls.add_method('EnableFcs', + 'void', + [param('bool', 'enable')], + is_static=True) ## ethernet-trailer.h: void ns3::EthernetTrailer::CalcFcs(ns3::Ptr p) [member function] - cls.add_method('CalcFcs', 'void', [param('ns3::Ptr< ns3::Packet >', 'p')]) + cls.add_method('CalcFcs', + 'void', + [param('ns3::Ptr< ns3::Packet >', 'p')]) ## ethernet-trailer.h: void ns3::EthernetTrailer::SetFcs(uint32_t fcs) [member function] - cls.add_method('SetFcs', 'void', [param('uint32_t', 'fcs')]) + cls.add_method('SetFcs', + 'void', + [param('uint32_t', 'fcs')]) ## ethernet-trailer.h: uint32_t ns3::EthernetTrailer::GetFcs() [member function] - cls.add_method('GetFcs', 'uint32_t', []) + cls.add_method('GetFcs', + 'uint32_t', + []) ## ethernet-trailer.h: bool ns3::EthernetTrailer::CheckFcs(ns3::Ptr p) const [member function] - cls.add_method('CheckFcs', 'bool', [param('ns3::Ptr< ns3::Packet >', 'p')], is_const=True) + cls.add_method('CheckFcs', + 'bool', + [param('ns3::Ptr< ns3::Packet >', 'p')], + is_const=True) ## ethernet-trailer.h: uint32_t ns3::EthernetTrailer::GetTrailerSize() const [member function] - cls.add_method('GetTrailerSize', 'uint32_t', [], is_const=True) + cls.add_method('GetTrailerSize', + 'uint32_t', + [], + is_const=True) ## ethernet-trailer.h: static ns3::TypeId ns3::EthernetTrailer::GetTypeId() [member function] - cls.add_method('GetTypeId', 'ns3::TypeId', [], is_static=True) + cls.add_method('GetTypeId', + 'ns3::TypeId', + [], + is_static=True) ## ethernet-trailer.h: ns3::TypeId ns3::EthernetTrailer::GetInstanceTypeId() const [member function] - cls.add_method('GetInstanceTypeId', 'ns3::TypeId', [], is_const=True, is_virtual=True) + cls.add_method('GetInstanceTypeId', + 'ns3::TypeId', + [], + is_const=True, is_virtual=True) ## ethernet-trailer.h: void ns3::EthernetTrailer::Print(std::ostream & os) const [member function] - cls.add_method('Print', 'void', [param('std::ostream&', 'os')], is_const=True, is_virtual=True) + cls.add_method('Print', + 'void', + [param('std::ostream&', 'os')], + is_const=True, is_virtual=True) ## ethernet-trailer.h: uint32_t ns3::EthernetTrailer::GetSerializedSize() const [member function] - cls.add_method('GetSerializedSize', 'uint32_t', [], is_const=True, is_virtual=True) + cls.add_method('GetSerializedSize', + 'uint32_t', + [], + is_const=True, is_virtual=True) ## ethernet-trailer.h: void ns3::EthernetTrailer::Serialize(ns3::Buffer::Iterator end) const [member function] - cls.add_method('Serialize', 'void', [param('ns3::Buffer::Iterator', 'end')], is_const=True, is_virtual=True) + cls.add_method('Serialize', + 'void', + [param('ns3::Buffer::Iterator', 'end')], + is_const=True, is_virtual=True) ## ethernet-trailer.h: uint32_t ns3::EthernetTrailer::Deserialize(ns3::Buffer::Iterator end) [member function] - cls.add_method('Deserialize', 'uint32_t', [param('ns3::Buffer::Iterator', 'end')], is_virtual=True) + cls.add_method('Deserialize', + 'uint32_t', + [param('ns3::Buffer::Iterator', 'end')], + is_virtual=True) return def register_Ns3LlcSnapHeader_methods(root_module, cls): ## llc-snap-header.h: ns3::LlcSnapHeader::LlcSnapHeader() [constructor] - cls.add_constructor([], visibility='public') + cls.add_constructor([]) ## llc-snap-header.h: void ns3::LlcSnapHeader::SetType(uint16_t type) [member function] - cls.add_method('SetType', 'void', [param('uint16_t', 'type')]) + cls.add_method('SetType', + 'void', + [param('uint16_t', 'type')]) ## llc-snap-header.h: uint16_t ns3::LlcSnapHeader::GetType() [member function] - cls.add_method('GetType', 'uint16_t', []) + cls.add_method('GetType', + 'uint16_t', + []) ## llc-snap-header.h: static ns3::TypeId ns3::LlcSnapHeader::GetTypeId() [member function] - cls.add_method('GetTypeId', 'ns3::TypeId', [], is_static=True) + cls.add_method('GetTypeId', + 'ns3::TypeId', + [], + is_static=True) ## llc-snap-header.h: ns3::TypeId ns3::LlcSnapHeader::GetInstanceTypeId() const [member function] - cls.add_method('GetInstanceTypeId', 'ns3::TypeId', [], is_const=True, is_virtual=True) + cls.add_method('GetInstanceTypeId', + 'ns3::TypeId', + [], + is_const=True, is_virtual=True) ## llc-snap-header.h: void ns3::LlcSnapHeader::Print(std::ostream & os) const [member function] - cls.add_method('Print', 'void', [param('std::ostream&', 'os')], is_const=True, is_virtual=True) + cls.add_method('Print', + 'void', + [param('std::ostream&', 'os')], + is_const=True, is_virtual=True) ## llc-snap-header.h: uint32_t ns3::LlcSnapHeader::GetSerializedSize() const [member function] - cls.add_method('GetSerializedSize', 'uint32_t', [], is_const=True, is_virtual=True) + cls.add_method('GetSerializedSize', + 'uint32_t', + [], + is_const=True, is_virtual=True) ## llc-snap-header.h: void ns3::LlcSnapHeader::Serialize(ns3::Buffer::Iterator start) const [member function] - cls.add_method('Serialize', 'void', [param('ns3::Buffer::Iterator', 'start')], is_const=True, is_virtual=True) + cls.add_method('Serialize', + 'void', + [param('ns3::Buffer::Iterator', 'start')], + is_const=True, is_virtual=True) ## llc-snap-header.h: uint32_t ns3::LlcSnapHeader::Deserialize(ns3::Buffer::Iterator start) [member function] - cls.add_method('Deserialize', 'uint32_t', [param('ns3::Buffer::Iterator', 'start')], is_virtual=True) + cls.add_method('Deserialize', + 'uint32_t', + [param('ns3::Buffer::Iterator', 'start')], + is_virtual=True) return def register_Ns3UdpSocketFactory_methods(root_module, cls): ## udp-socket-factory.h: static ns3::TypeId ns3::UdpSocketFactory::GetTypeId() [member function] - cls.add_method('GetTypeId', 'ns3::TypeId', [], is_static=True) + cls.add_method('GetTypeId', + 'ns3::TypeId', + [], + is_static=True) cls.add_constructor([]) return def register_Ns3SimpleNetDevice_methods(root_module, cls): ## simple-net-device.h: static ns3::TypeId ns3::SimpleNetDevice::GetTypeId() [member function] - cls.add_method('GetTypeId', 'ns3::TypeId', [], is_static=True) + cls.add_method('GetTypeId', + 'ns3::TypeId', + [], + is_static=True) ## simple-net-device.h: ns3::SimpleNetDevice::SimpleNetDevice() [constructor] - cls.add_constructor([], visibility='public') + cls.add_constructor([]) ## simple-net-device.h: void ns3::SimpleNetDevice::Receive(ns3::Ptr packet, uint16_t protocol, ns3::Mac48Address to, ns3::Mac48Address from) [member function] - cls.add_method('Receive', 'void', [param('ns3::Ptr< ns3::Packet >', 'packet'), param('uint16_t', 'protocol'), param('ns3::Mac48Address', 'to'), param('ns3::Mac48Address', 'from')]) + cls.add_method('Receive', + 'void', + [param('ns3::Ptr< ns3::Packet >', 'packet'), param('uint16_t', 'protocol'), param('ns3::Mac48Address', 'to'), param('ns3::Mac48Address', 'from')]) ## simple-net-device.h: void ns3::SimpleNetDevice::SetChannel(ns3::Ptr channel) [member function] - cls.add_method('SetChannel', 'void', [param('ns3::Ptr< ns3::SimpleChannel >', 'channel')]) + cls.add_method('SetChannel', + 'void', + [param('ns3::Ptr< ns3::SimpleChannel >', 'channel')]) ## simple-net-device.h: void ns3::SimpleNetDevice::SetAddress(ns3::Mac48Address address) [member function] - cls.add_method('SetAddress', 'void', [param('ns3::Mac48Address', 'address')]) + cls.add_method('SetAddress', + 'void', + [param('ns3::Mac48Address', 'address')]) ## simple-net-device.h: void ns3::SimpleNetDevice::SetName(std::string const name) [member function] - cls.add_method('SetName', 'void', [param('std::string', 'name', is_const=True)], is_virtual=True) + cls.add_method('SetName', + 'void', + [param('std::string', 'name', is_const=True)], + is_virtual=True) ## simple-net-device.h: std::string ns3::SimpleNetDevice::GetName() const [member function] - cls.add_method('GetName', 'std::string', [], is_const=True, is_virtual=True) + cls.add_method('GetName', + 'std::string', + [], + is_const=True, is_virtual=True) ## simple-net-device.h: void ns3::SimpleNetDevice::SetIfIndex(uint32_t const index) [member function] - cls.add_method('SetIfIndex', 'void', [param('uint32_t', 'index', is_const=True)], is_virtual=True) + cls.add_method('SetIfIndex', + 'void', + [param('uint32_t', 'index', is_const=True)], + is_virtual=True) ## simple-net-device.h: uint32_t ns3::SimpleNetDevice::GetIfIndex() const [member function] - cls.add_method('GetIfIndex', 'uint32_t', [], is_const=True, is_virtual=True) + cls.add_method('GetIfIndex', + 'uint32_t', + [], + is_const=True, is_virtual=True) ## simple-net-device.h: ns3::Ptr ns3::SimpleNetDevice::GetChannel() const [member function] - cls.add_method('GetChannel', 'ns3::Ptr< ns3::Channel >', [], is_const=True, is_virtual=True) + cls.add_method('GetChannel', + 'ns3::Ptr< ns3::Channel >', + [], + is_const=True, is_virtual=True) ## simple-net-device.h: ns3::Address ns3::SimpleNetDevice::GetAddress() const [member function] - cls.add_method('GetAddress', 'ns3::Address', [], is_const=True, is_virtual=True) + cls.add_method('GetAddress', + 'ns3::Address', + [], + is_const=True, is_virtual=True) ## simple-net-device.h: bool ns3::SimpleNetDevice::SetMtu(uint16_t const mtu) [member function] - cls.add_method('SetMtu', 'bool', [param('uint16_t', 'mtu', is_const=True)], is_virtual=True) + cls.add_method('SetMtu', + 'bool', + [param('uint16_t', 'mtu', is_const=True)], + is_virtual=True) ## simple-net-device.h: uint16_t ns3::SimpleNetDevice::GetMtu() const [member function] - cls.add_method('GetMtu', 'uint16_t', [], is_const=True, is_virtual=True) + cls.add_method('GetMtu', + 'uint16_t', + [], + is_const=True, is_virtual=True) ## simple-net-device.h: bool ns3::SimpleNetDevice::IsLinkUp() const [member function] - cls.add_method('IsLinkUp', 'bool', [], is_const=True, is_virtual=True) + cls.add_method('IsLinkUp', + 'bool', + [], + is_const=True, is_virtual=True) ## simple-net-device.h: void ns3::SimpleNetDevice::SetLinkChangeCallback(ns3::Callback callback) [member function] - cls.add_method('SetLinkChangeCallback', 'void', [param('ns3::Callback< void, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty >', 'callback')], is_virtual=True) + cls.add_method('SetLinkChangeCallback', + 'void', + [param('ns3::Callback< void, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty >', 'callback')], + is_virtual=True) ## simple-net-device.h: bool ns3::SimpleNetDevice::IsBroadcast() const [member function] - cls.add_method('IsBroadcast', 'bool', [], is_const=True, is_virtual=True) + cls.add_method('IsBroadcast', + 'bool', + [], + is_const=True, is_virtual=True) ## simple-net-device.h: ns3::Address ns3::SimpleNetDevice::GetBroadcast() const [member function] - cls.add_method('GetBroadcast', 'ns3::Address', [], is_const=True, is_virtual=True) + cls.add_method('GetBroadcast', + 'ns3::Address', + [], + is_const=True, is_virtual=True) ## simple-net-device.h: bool ns3::SimpleNetDevice::IsMulticast() const [member function] - cls.add_method('IsMulticast', 'bool', [], is_const=True, is_virtual=True) + cls.add_method('IsMulticast', + 'bool', + [], + is_const=True, is_virtual=True) ## simple-net-device.h: ns3::Address ns3::SimpleNetDevice::GetMulticast() const [member function] - cls.add_method('GetMulticast', 'ns3::Address', [], is_const=True, is_virtual=True) + cls.add_method('GetMulticast', + 'ns3::Address', + [], + is_const=True, is_virtual=True) ## simple-net-device.h: ns3::Address ns3::SimpleNetDevice::MakeMulticastAddress(ns3::Ipv4Address multicastGroup) const [member function] - cls.add_method('MakeMulticastAddress', 'ns3::Address', [param('ns3::Ipv4Address', 'multicastGroup')], is_const=True, is_virtual=True) + cls.add_method('MakeMulticastAddress', + 'ns3::Address', + [param('ns3::Ipv4Address', 'multicastGroup')], + is_const=True, is_virtual=True) ## simple-net-device.h: bool ns3::SimpleNetDevice::IsPointToPoint() const [member function] - cls.add_method('IsPointToPoint', 'bool', [], is_const=True, is_virtual=True) + cls.add_method('IsPointToPoint', + 'bool', + [], + is_const=True, is_virtual=True) ## simple-net-device.h: bool ns3::SimpleNetDevice::Send(ns3::Ptr packet, ns3::Address const & dest, uint16_t protocolNumber) [member function] - cls.add_method('Send', 'bool', [param('ns3::Ptr< ns3::Packet >', 'packet'), param('ns3::Address&', 'dest', is_const=True), param('uint16_t', 'protocolNumber')], is_virtual=True) + cls.add_method('Send', + 'bool', + [param('ns3::Ptr< ns3::Packet >', 'packet'), param('ns3::Address&', 'dest', is_const=True), param('uint16_t', 'protocolNumber')], + is_virtual=True) ## simple-net-device.h: bool ns3::SimpleNetDevice::SendFrom(ns3::Ptr packet, ns3::Address const & source, ns3::Address const & dest, uint16_t protocolNumber) [member function] - cls.add_method('SendFrom', 'bool', [param('ns3::Ptr< ns3::Packet >', 'packet'), param('ns3::Address&', 'source', is_const=True), param('ns3::Address&', 'dest', is_const=True), param('uint16_t', 'protocolNumber')], is_virtual=True) + cls.add_method('SendFrom', + 'bool', + [param('ns3::Ptr< ns3::Packet >', 'packet'), param('ns3::Address&', 'source', is_const=True), param('ns3::Address&', 'dest', is_const=True), param('uint16_t', 'protocolNumber')], + is_virtual=True) ## simple-net-device.h: ns3::Ptr ns3::SimpleNetDevice::GetNode() const [member function] - cls.add_method('GetNode', 'ns3::Ptr< ns3::Node >', [], is_const=True, is_virtual=True) + cls.add_method('GetNode', + 'ns3::Ptr< ns3::Node >', + [], + is_const=True, is_virtual=True) ## simple-net-device.h: void ns3::SimpleNetDevice::SetNode(ns3::Ptr node) [member function] - cls.add_method('SetNode', 'void', [param('ns3::Ptr< ns3::Node >', 'node')], is_virtual=True) + cls.add_method('SetNode', + 'void', + [param('ns3::Ptr< ns3::Node >', 'node')], + is_virtual=True) ## simple-net-device.h: bool ns3::SimpleNetDevice::NeedsArp() const [member function] - cls.add_method('NeedsArp', 'bool', [], is_const=True, is_virtual=True) + cls.add_method('NeedsArp', + 'bool', + [], + is_const=True, is_virtual=True) ## simple-net-device.h: void ns3::SimpleNetDevice::SetReceiveCallback(ns3::Callback, ns3::Ptr, unsigned short, ns3::Address const&, ns3::empty, ns3::empty> cb) [member function] - cls.add_method('SetReceiveCallback', 'void', [param('ns3::Callback< bool, ns3::Ptr< ns3::NetDevice >, ns3::Ptr< ns3::Packet >, unsigned short, ns3::Address const&, ns3::empty, ns3::empty >', 'cb')], is_virtual=True) + cls.add_method('SetReceiveCallback', + 'void', + [param('ns3::Callback< bool, ns3::Ptr< ns3::NetDevice >, ns3::Ptr< ns3::Packet >, unsigned short, ns3::Address const&, ns3::empty, ns3::empty >', 'cb')], + is_virtual=True) ## simple-net-device.h: void ns3::SimpleNetDevice::DoDispose() [member function] - cls.add_method('DoDispose', 'void', [], visibility='protected', is_virtual=True) + cls.add_method('DoDispose', + 'void', + [], + visibility='protected', is_virtual=True) return def register_Ns3SimpleChannel_methods(root_module, cls): ## simple-channel.h: static ns3::TypeId ns3::SimpleChannel::GetTypeId() [member function] - cls.add_method('GetTypeId', 'ns3::TypeId', [], is_static=True) + cls.add_method('GetTypeId', + 'ns3::TypeId', + [], + is_static=True) ## simple-channel.h: ns3::SimpleChannel::SimpleChannel() [constructor] - cls.add_constructor([], visibility='public') + cls.add_constructor([]) ## simple-channel.h: void ns3::SimpleChannel::Send(ns3::Ptr p, uint16_t protocol, ns3::Mac48Address to, ns3::Mac48Address from, ns3::Ptr sender) [member function] - cls.add_method('Send', 'void', [param('ns3::Ptr< ns3::Packet >', 'p'), param('uint16_t', 'protocol'), param('ns3::Mac48Address', 'to'), param('ns3::Mac48Address', 'from'), param('ns3::Ptr< ns3::SimpleNetDevice >', 'sender')]) + cls.add_method('Send', + 'void', + [param('ns3::Ptr< ns3::Packet >', 'p'), param('uint16_t', 'protocol'), param('ns3::Mac48Address', 'to'), param('ns3::Mac48Address', 'from'), param('ns3::Ptr< ns3::SimpleNetDevice >', 'sender')]) ## simple-channel.h: void ns3::SimpleChannel::Add(ns3::Ptr device) [member function] - cls.add_method('Add', 'void', [param('ns3::Ptr< ns3::SimpleNetDevice >', 'device')]) + cls.add_method('Add', + 'void', + [param('ns3::Ptr< ns3::SimpleNetDevice >', 'device')]) ## simple-channel.h: uint32_t ns3::SimpleChannel::GetNDevices() const [member function] - cls.add_method('GetNDevices', 'uint32_t', [], is_const=True, is_virtual=True) + cls.add_method('GetNDevices', + 'uint32_t', + [], + is_const=True, is_virtual=True) ## simple-channel.h: ns3::Ptr ns3::SimpleChannel::GetDevice(uint32_t i) const [member function] - cls.add_method('GetDevice', 'ns3::Ptr< ns3::NetDevice >', [param('uint32_t', 'i')], is_const=True, is_virtual=True) + cls.add_method('GetDevice', + 'ns3::Ptr< ns3::NetDevice >', + [param('uint32_t', 'i')], + is_const=True, is_virtual=True) return def register_Ns3TcpSocketFactory_methods(root_module, cls): ## tcp-socket-factory.h: static ns3::TypeId ns3::TcpSocketFactory::GetTypeId() [member function] - cls.add_method('GetTypeId', 'ns3::TypeId', [], is_static=True) + cls.add_method('GetTypeId', + 'ns3::TypeId', + [], + is_static=True) cls.add_constructor([]) return def register_Ns3PacketSocketFactory_methods(root_module, cls): ## packet-socket-factory.h: static ns3::TypeId ns3::PacketSocketFactory::GetTypeId() [member function] - cls.add_method('GetTypeId', 'ns3::TypeId', [], is_static=True) + cls.add_method('GetTypeId', + 'ns3::TypeId', + [], + is_static=True) ## packet-socket-factory.h: ns3::PacketSocketFactory::PacketSocketFactory() [constructor] - cls.add_constructor([], visibility='public') + cls.add_constructor([]) ## packet-socket-factory.h: ns3::Ptr ns3::PacketSocketFactory::CreateSocket() [member function] - cls.add_method('CreateSocket', 'ns3::Ptr< ns3::Socket >', [], is_virtual=True) + cls.add_method('CreateSocket', + 'ns3::Ptr< ns3::Socket >', + [], + is_virtual=True) return def register_functions(root_module): module = root_module ## mac48-address.h: extern ns3::Ptr ns3::MakeMac48AddressChecker() [free function] - module.add_function('MakeMac48AddressChecker', 'ns3::Ptr< ns3::AttributeChecker const >', []) + module.add_function('MakeMac48AddressChecker', + 'ns3::Ptr< ns3::AttributeChecker const >', + []) ## ipv4-address.h: extern ns3::Ptr ns3::MakeIpv4AddressChecker() [free function] - module.add_function('MakeIpv4AddressChecker', 'ns3::Ptr< ns3::AttributeChecker const >', []) + module.add_function('MakeIpv4AddressChecker', + 'ns3::Ptr< ns3::AttributeChecker const >', + []) ## address-utils.h: extern void ns3::WriteTo(ns3::Buffer::Iterator & i, ns3::Mac48Address ad) [free function] - module.add_function('WriteTo', 'void', [param('ns3::Buffer::Iterator&', 'i'), param('ns3::Mac48Address', 'ad')]) + module.add_function('WriteTo', + 'void', + [param('ns3::Buffer::Iterator&', 'i'), param('ns3::Mac48Address', 'ad')]) ## address-utils.h: extern void ns3::WriteTo(ns3::Buffer::Iterator & i, ns3::Address const & ad) [free function] - module.add_function('WriteTo', 'void', [param('ns3::Buffer::Iterator&', 'i'), param('ns3::Address&', 'ad', is_const=True)]) + module.add_function('WriteTo', + 'void', + [param('ns3::Buffer::Iterator&', 'i'), param('ns3::Address&', 'ad', is_const=True)]) ## address-utils.h: extern void ns3::WriteTo(ns3::Buffer::Iterator & i, ns3::Ipv4Address ad) [free function] - module.add_function('WriteTo', 'void', [param('ns3::Buffer::Iterator&', 'i'), param('ns3::Ipv4Address', 'ad')]) + module.add_function('WriteTo', + 'void', + [param('ns3::Buffer::Iterator&', 'i'), param('ns3::Ipv4Address', 'ad')]) ## address.h: extern ns3::Ptr ns3::MakeAddressChecker() [free function] - module.add_function('MakeAddressChecker', 'ns3::Ptr< ns3::AttributeChecker const >', []) + module.add_function('MakeAddressChecker', + 'ns3::Ptr< ns3::AttributeChecker const >', + []) ## ipv4-address.h: extern ns3::Ptr ns3::MakeIpv4MaskChecker() [free function] - module.add_function('MakeIpv4MaskChecker', 'ns3::Ptr< ns3::AttributeChecker const >', []) + module.add_function('MakeIpv4MaskChecker', + 'ns3::Ptr< ns3::AttributeChecker const >', + []) ## address-utils.h: extern void ns3::ReadFrom(ns3::Buffer::Iterator & i, ns3::Mac48Address & ad) [free function] - module.add_function('ReadFrom', 'void', [param('ns3::Buffer::Iterator&', 'i'), param('ns3::Mac48Address&', 'ad')]) + module.add_function('ReadFrom', + 'void', + [param('ns3::Buffer::Iterator&', 'i'), param('ns3::Mac48Address&', 'ad')]) ## address-utils.h: extern void ns3::ReadFrom(ns3::Buffer::Iterator & i, ns3::Address & ad, uint32_t len) [free function] - module.add_function('ReadFrom', 'void', [param('ns3::Buffer::Iterator&', 'i'), param('ns3::Address&', 'ad'), param('uint32_t', 'len')]) + module.add_function('ReadFrom', + 'void', + [param('ns3::Buffer::Iterator&', 'i'), param('ns3::Address&', 'ad'), param('uint32_t', 'len')]) ## address-utils.h: extern void ns3::ReadFrom(ns3::Buffer::Iterator & i, ns3::Ipv4Address & ad) [free function] - module.add_function('ReadFrom', 'void', [param('ns3::Buffer::Iterator&', 'i'), param('ns3::Ipv4Address&', 'ad')]) + module.add_function('ReadFrom', + 'void', + [param('ns3::Buffer::Iterator&', 'i'), param('ns3::Ipv4Address&', 'ad')]) register_functions_ns3_internal(module.get_submodule('internal'), root_module) register_functions_ns3_TimeStepPrecision(module.get_submodule('TimeStepPrecision'), root_module) register_functions_ns3_Config(module.get_submodule('Config'), root_module) diff --git a/bindings/python/ns3_module_olsr.py b/bindings/python/ns3_module_olsr.py index 0ff367f61..624e06edf 100644 --- a/bindings/python/ns3_module_olsr.py +++ b/bindings/python/ns3_module_olsr.py @@ -1,4 +1,4 @@ -from pybindgen import Module, FileCodeSink, write_preamble, param, retval +from pybindgen import Module, FileCodeSink, param, retval, cppclass def register_types(module): root_module = module.get_root() @@ -78,94 +78,189 @@ def register_methods(root_module): def register_Ns3OlsrMessageHeader_methods(root_module, cls): ## olsr-header.h: ns3::olsr::MessageHeader::MessageHeader(ns3::olsr::MessageHeader const & arg0) [copy constructor] - cls.add_constructor([param('ns3::olsr::MessageHeader&', 'arg0', is_const=True)], visibility='public') + cls.add_constructor([param('ns3::olsr::MessageHeader&', 'arg0', is_const=True)]) ## olsr-header.h: ns3::olsr::MessageHeader::MessageHeader() [constructor] - cls.add_constructor([], visibility='public') + cls.add_constructor([]) ## olsr-header.h: uint32_t ns3::olsr::MessageHeader::Deserialize(ns3::Buffer::Iterator start) [member function] - cls.add_method('Deserialize', 'uint32_t', [param('ns3::Buffer::Iterator', 'start')], is_virtual=True) + cls.add_method('Deserialize', + 'uint32_t', + [param('ns3::Buffer::Iterator', 'start')], + is_virtual=True) ## olsr-header.h: ns3::olsr::MessageHeader::Hello & ns3::olsr::MessageHeader::GetHello() [member function] - cls.add_method('GetHello', 'ns3::olsr::MessageHeader::Hello&', []) + cls.add_method('GetHello', + 'ns3::olsr::MessageHeader::Hello&', + []) ## olsr-header.h: ns3::olsr::MessageHeader::Hello const & ns3::olsr::MessageHeader::GetHello() const [member function] - cls.add_method('GetHello', retval('ns3::olsr::MessageHeader::Hello&', is_const=True), [], is_const=True) + cls.add_method('GetHello', + retval('ns3::olsr::MessageHeader::Hello&', is_const=True), + [], + is_const=True) ## olsr-header.h: ns3::olsr::MessageHeader::Hna & ns3::olsr::MessageHeader::GetHna() [member function] - cls.add_method('GetHna', 'ns3::olsr::MessageHeader::Hna&', []) + cls.add_method('GetHna', + 'ns3::olsr::MessageHeader::Hna&', + []) ## olsr-header.h: ns3::olsr::MessageHeader::Hna const & ns3::olsr::MessageHeader::GetHna() const [member function] - cls.add_method('GetHna', retval('ns3::olsr::MessageHeader::Hna&', is_const=True), [], is_const=True) + cls.add_method('GetHna', + retval('ns3::olsr::MessageHeader::Hna&', is_const=True), + [], + is_const=True) ## olsr-header.h: uint8_t ns3::olsr::MessageHeader::GetHopCount() const [member function] - cls.add_method('GetHopCount', 'uint8_t', [], is_const=True) + cls.add_method('GetHopCount', + 'uint8_t', + [], + is_const=True) ## olsr-header.h: ns3::TypeId ns3::olsr::MessageHeader::GetInstanceTypeId() const [member function] - cls.add_method('GetInstanceTypeId', 'ns3::TypeId', [], is_const=True, is_virtual=True) + cls.add_method('GetInstanceTypeId', + 'ns3::TypeId', + [], + is_const=True, is_virtual=True) ## olsr-header.h: uint16_t ns3::olsr::MessageHeader::GetMessageSequenceNumber() const [member function] - cls.add_method('GetMessageSequenceNumber', 'uint16_t', [], is_const=True) + cls.add_method('GetMessageSequenceNumber', + 'uint16_t', + [], + is_const=True) ## olsr-header.h: ns3::olsr::MessageHeader::MessageType ns3::olsr::MessageHeader::GetMessageType() const [member function] - cls.add_method('GetMessageType', 'ns3::olsr::MessageHeader::MessageType', [], is_const=True) + cls.add_method('GetMessageType', + 'ns3::olsr::MessageHeader::MessageType', + [], + is_const=True) ## olsr-header.h: ns3::olsr::MessageHeader::Mid & ns3::olsr::MessageHeader::GetMid() [member function] - cls.add_method('GetMid', 'ns3::olsr::MessageHeader::Mid&', []) + cls.add_method('GetMid', + 'ns3::olsr::MessageHeader::Mid&', + []) ## olsr-header.h: ns3::olsr::MessageHeader::Mid const & ns3::olsr::MessageHeader::GetMid() const [member function] - cls.add_method('GetMid', retval('ns3::olsr::MessageHeader::Mid&', is_const=True), [], is_const=True) + cls.add_method('GetMid', + retval('ns3::olsr::MessageHeader::Mid&', is_const=True), + [], + is_const=True) ## olsr-header.h: ns3::Ipv4Address ns3::olsr::MessageHeader::GetOriginatorAddress() const [member function] - cls.add_method('GetOriginatorAddress', 'ns3::Ipv4Address', [], is_const=True) + cls.add_method('GetOriginatorAddress', + 'ns3::Ipv4Address', + [], + is_const=True) ## olsr-header.h: uint32_t ns3::olsr::MessageHeader::GetSerializedSize() const [member function] - cls.add_method('GetSerializedSize', 'uint32_t', [], is_const=True, is_virtual=True) + cls.add_method('GetSerializedSize', + 'uint32_t', + [], + is_const=True, is_virtual=True) ## olsr-header.h: ns3::olsr::MessageHeader::Tc & ns3::olsr::MessageHeader::GetTc() [member function] - cls.add_method('GetTc', 'ns3::olsr::MessageHeader::Tc&', []) + cls.add_method('GetTc', + 'ns3::olsr::MessageHeader::Tc&', + []) ## olsr-header.h: ns3::olsr::MessageHeader::Tc const & ns3::olsr::MessageHeader::GetTc() const [member function] - cls.add_method('GetTc', retval('ns3::olsr::MessageHeader::Tc&', is_const=True), [], is_const=True) + cls.add_method('GetTc', + retval('ns3::olsr::MessageHeader::Tc&', is_const=True), + [], + is_const=True) ## olsr-header.h: uint8_t ns3::olsr::MessageHeader::GetTimeToLive() const [member function] - cls.add_method('GetTimeToLive', 'uint8_t', [], is_const=True) + cls.add_method('GetTimeToLive', + 'uint8_t', + [], + is_const=True) ## olsr-header.h: static ns3::TypeId ns3::olsr::MessageHeader::GetTypeId() [member function] - cls.add_method('GetTypeId', 'ns3::TypeId', [], is_static=True) + cls.add_method('GetTypeId', + 'ns3::TypeId', + [], + is_static=True) ## olsr-header.h: ns3::Time ns3::olsr::MessageHeader::GetVTime() const [member function] - cls.add_method('GetVTime', 'ns3::Time', [], is_const=True) + cls.add_method('GetVTime', + 'ns3::Time', + [], + is_const=True) ## olsr-header.h: void ns3::olsr::MessageHeader::Print(std::ostream & os) const [member function] - cls.add_method('Print', 'void', [param('std::ostream&', 'os')], is_const=True, is_virtual=True) + cls.add_method('Print', + 'void', + [param('std::ostream&', 'os')], + is_const=True, is_virtual=True) ## olsr-header.h: void ns3::olsr::MessageHeader::Serialize(ns3::Buffer::Iterator start) const [member function] - cls.add_method('Serialize', 'void', [param('ns3::Buffer::Iterator', 'start')], is_const=True, is_virtual=True) + cls.add_method('Serialize', + 'void', + [param('ns3::Buffer::Iterator', 'start')], + is_const=True, is_virtual=True) ## olsr-header.h: void ns3::olsr::MessageHeader::SetHopCount(uint8_t hopCount) [member function] - cls.add_method('SetHopCount', 'void', [param('uint8_t', 'hopCount')]) + cls.add_method('SetHopCount', + 'void', + [param('uint8_t', 'hopCount')]) ## olsr-header.h: void ns3::olsr::MessageHeader::SetMessageSequenceNumber(uint16_t messageSequenceNumber) [member function] - cls.add_method('SetMessageSequenceNumber', 'void', [param('uint16_t', 'messageSequenceNumber')]) + cls.add_method('SetMessageSequenceNumber', + 'void', + [param('uint16_t', 'messageSequenceNumber')]) ## olsr-header.h: void ns3::olsr::MessageHeader::SetMessageType(ns3::olsr::MessageHeader::MessageType messageType) [member function] - cls.add_method('SetMessageType', 'void', [param('ns3::olsr::MessageHeader::MessageType', 'messageType')]) + cls.add_method('SetMessageType', + 'void', + [param('ns3::olsr::MessageHeader::MessageType', 'messageType')]) ## olsr-header.h: void ns3::olsr::MessageHeader::SetOriginatorAddress(ns3::Ipv4Address originatorAddress) [member function] - cls.add_method('SetOriginatorAddress', 'void', [param('ns3::Ipv4Address', 'originatorAddress')]) + cls.add_method('SetOriginatorAddress', + 'void', + [param('ns3::Ipv4Address', 'originatorAddress')]) ## olsr-header.h: void ns3::olsr::MessageHeader::SetTimeToLive(uint8_t timeToLive) [member function] - cls.add_method('SetTimeToLive', 'void', [param('uint8_t', 'timeToLive')]) + cls.add_method('SetTimeToLive', + 'void', + [param('uint8_t', 'timeToLive')]) ## olsr-header.h: void ns3::olsr::MessageHeader::SetVTime(ns3::Time time) [member function] - cls.add_method('SetVTime', 'void', [param('ns3::Time', 'time')]) + cls.add_method('SetVTime', + 'void', + [param('ns3::Time', 'time')]) cls.add_output_stream_operator() return def register_Ns3OlsrMessageHeaderMid_methods(root_module, cls): ## olsr-header.h: ns3::olsr::MessageHeader::Mid::Mid(ns3::olsr::MessageHeader::Mid const & arg0) [copy constructor] - cls.add_constructor([param('ns3::olsr::MessageHeader::Mid&', 'arg0', is_const=True)], visibility='public') + cls.add_constructor([param('ns3::olsr::MessageHeader::Mid&', 'arg0', is_const=True)]) ## olsr-header.h: uint32_t ns3::olsr::MessageHeader::Mid::Deserialize(ns3::Buffer::Iterator start, uint32_t messageSize) [member function] - cls.add_method('Deserialize', 'uint32_t', [param('ns3::Buffer::Iterator', 'start'), param('uint32_t', 'messageSize')]) + cls.add_method('Deserialize', + 'uint32_t', + [param('ns3::Buffer::Iterator', 'start'), param('uint32_t', 'messageSize')]) ## olsr-header.h: uint32_t ns3::olsr::MessageHeader::Mid::GetSerializedSize() const [member function] - cls.add_method('GetSerializedSize', 'uint32_t', [], is_const=True) + cls.add_method('GetSerializedSize', + 'uint32_t', + [], + is_const=True) ## olsr-header.h: void ns3::olsr::MessageHeader::Mid::Print(std::ostream & os) const [member function] - cls.add_method('Print', 'void', [param('std::ostream&', 'os')], is_const=True) + cls.add_method('Print', + 'void', + [param('std::ostream&', 'os')], + is_const=True) ## olsr-header.h: void ns3::olsr::MessageHeader::Mid::Serialize(ns3::Buffer::Iterator start) const [member function] - cls.add_method('Serialize', 'void', [param('ns3::Buffer::Iterator', 'start')], is_const=True) + cls.add_method('Serialize', + 'void', + [param('ns3::Buffer::Iterator', 'start')], + is_const=True) ## olsr-header.h: ns3::olsr::MessageHeader::Mid::interfaceAddresses [variable] cls.add_instance_attribute('interfaceAddresses', 'std::vector< ns3::Ipv4Address, std::allocator< ns3::Ipv4Address > >', is_const=False) return def register_Ns3OlsrMessageHeaderHello_methods(root_module, cls): ## olsr-header.h: ns3::olsr::MessageHeader::Hello::Hello(ns3::olsr::MessageHeader::Hello const & arg0) [copy constructor] - cls.add_constructor([param('ns3::olsr::MessageHeader::Hello&', 'arg0', is_const=True)], visibility='public') + cls.add_constructor([param('ns3::olsr::MessageHeader::Hello&', 'arg0', is_const=True)]) ## olsr-header.h: uint32_t ns3::olsr::MessageHeader::Hello::Deserialize(ns3::Buffer::Iterator start, uint32_t messageSize) [member function] - cls.add_method('Deserialize', 'uint32_t', [param('ns3::Buffer::Iterator', 'start'), param('uint32_t', 'messageSize')]) + cls.add_method('Deserialize', + 'uint32_t', + [param('ns3::Buffer::Iterator', 'start'), param('uint32_t', 'messageSize')]) ## olsr-header.h: ns3::Time ns3::olsr::MessageHeader::Hello::GetHTime() const [member function] - cls.add_method('GetHTime', 'ns3::Time', [], is_const=True) + cls.add_method('GetHTime', + 'ns3::Time', + [], + is_const=True) ## olsr-header.h: uint32_t ns3::olsr::MessageHeader::Hello::GetSerializedSize() const [member function] - cls.add_method('GetSerializedSize', 'uint32_t', [], is_const=True) + cls.add_method('GetSerializedSize', + 'uint32_t', + [], + is_const=True) ## olsr-header.h: void ns3::olsr::MessageHeader::Hello::Print(std::ostream & os) const [member function] - cls.add_method('Print', 'void', [param('std::ostream&', 'os')], is_const=True) + cls.add_method('Print', + 'void', + [param('std::ostream&', 'os')], + is_const=True) ## olsr-header.h: void ns3::olsr::MessageHeader::Hello::Serialize(ns3::Buffer::Iterator start) const [member function] - cls.add_method('Serialize', 'void', [param('ns3::Buffer::Iterator', 'start')], is_const=True) + cls.add_method('Serialize', + 'void', + [param('ns3::Buffer::Iterator', 'start')], + is_const=True) ## olsr-header.h: void ns3::olsr::MessageHeader::Hello::SetHTime(ns3::Time time) [member function] - cls.add_method('SetHTime', 'void', [param('ns3::Time', 'time')]) + cls.add_method('SetHTime', + 'void', + [param('ns3::Time', 'time')]) ## olsr-header.h: ns3::olsr::MessageHeader::Hello::hTime [variable] cls.add_instance_attribute('hTime', 'uint8_t', is_const=False) ## olsr-header.h: ns3::olsr::MessageHeader::Hello::linkMessages [variable] @@ -184,15 +279,26 @@ def register_Ns3OlsrMessageHeaderHelloLinkMessage_methods(root_module, cls): def register_Ns3OlsrMessageHeaderTc_methods(root_module, cls): ## olsr-header.h: ns3::olsr::MessageHeader::Tc::Tc(ns3::olsr::MessageHeader::Tc const & arg0) [copy constructor] - cls.add_constructor([param('ns3::olsr::MessageHeader::Tc&', 'arg0', is_const=True)], visibility='public') + cls.add_constructor([param('ns3::olsr::MessageHeader::Tc&', 'arg0', is_const=True)]) ## olsr-header.h: uint32_t ns3::olsr::MessageHeader::Tc::Deserialize(ns3::Buffer::Iterator start, uint32_t messageSize) [member function] - cls.add_method('Deserialize', 'uint32_t', [param('ns3::Buffer::Iterator', 'start'), param('uint32_t', 'messageSize')]) + cls.add_method('Deserialize', + 'uint32_t', + [param('ns3::Buffer::Iterator', 'start'), param('uint32_t', 'messageSize')]) ## olsr-header.h: uint32_t ns3::olsr::MessageHeader::Tc::GetSerializedSize() const [member function] - cls.add_method('GetSerializedSize', 'uint32_t', [], is_const=True) + cls.add_method('GetSerializedSize', + 'uint32_t', + [], + is_const=True) ## olsr-header.h: void ns3::olsr::MessageHeader::Tc::Print(std::ostream & os) const [member function] - cls.add_method('Print', 'void', [param('std::ostream&', 'os')], is_const=True) + cls.add_method('Print', + 'void', + [param('std::ostream&', 'os')], + is_const=True) ## olsr-header.h: void ns3::olsr::MessageHeader::Tc::Serialize(ns3::Buffer::Iterator start) const [member function] - cls.add_method('Serialize', 'void', [param('ns3::Buffer::Iterator', 'start')], is_const=True) + cls.add_method('Serialize', + 'void', + [param('ns3::Buffer::Iterator', 'start')], + is_const=True) ## olsr-header.h: ns3::olsr::MessageHeader::Tc::ansn [variable] cls.add_instance_attribute('ansn', 'uint16_t', is_const=False) ## olsr-header.h: ns3::olsr::MessageHeader::Tc::neighborAddresses [variable] @@ -201,15 +307,26 @@ def register_Ns3OlsrMessageHeaderTc_methods(root_module, cls): def register_Ns3OlsrMessageHeaderHna_methods(root_module, cls): ## olsr-header.h: ns3::olsr::MessageHeader::Hna::Hna(ns3::olsr::MessageHeader::Hna const & arg0) [copy constructor] - cls.add_constructor([param('ns3::olsr::MessageHeader::Hna&', 'arg0', is_const=True)], visibility='public') + cls.add_constructor([param('ns3::olsr::MessageHeader::Hna&', 'arg0', is_const=True)]) ## olsr-header.h: uint32_t ns3::olsr::MessageHeader::Hna::Deserialize(ns3::Buffer::Iterator start, uint32_t messageSize) [member function] - cls.add_method('Deserialize', 'uint32_t', [param('ns3::Buffer::Iterator', 'start'), param('uint32_t', 'messageSize')]) + cls.add_method('Deserialize', + 'uint32_t', + [param('ns3::Buffer::Iterator', 'start'), param('uint32_t', 'messageSize')]) ## olsr-header.h: uint32_t ns3::olsr::MessageHeader::Hna::GetSerializedSize() const [member function] - cls.add_method('GetSerializedSize', 'uint32_t', [], is_const=True) + cls.add_method('GetSerializedSize', + 'uint32_t', + [], + is_const=True) ## olsr-header.h: void ns3::olsr::MessageHeader::Hna::Print(std::ostream & os) const [member function] - cls.add_method('Print', 'void', [param('std::ostream&', 'os')], is_const=True) + cls.add_method('Print', + 'void', + [param('std::ostream&', 'os')], + is_const=True) ## olsr-header.h: void ns3::olsr::MessageHeader::Hna::Serialize(ns3::Buffer::Iterator start) const [member function] - cls.add_method('Serialize', 'void', [param('ns3::Buffer::Iterator', 'start')], is_const=True) + cls.add_method('Serialize', + 'void', + [param('ns3::Buffer::Iterator', 'start')], + is_const=True) ## olsr-header.h: ns3::olsr::MessageHeader::Hna::associations [variable] cls.add_instance_attribute('associations', 'std::vector< ns3::olsr::MessageHeader::Hna::Association, std::allocator< ns3::olsr::MessageHeader::Hna::Association > >', is_const=False) return @@ -224,41 +341,81 @@ def register_Ns3OlsrMessageHeaderHnaAssociation_methods(root_module, cls): def register_Ns3OlsrAgent_methods(root_module, cls): ## olsr-agent.h: static ns3::TypeId ns3::olsr::Agent::GetTypeId() [member function] - cls.add_method('GetTypeId', 'ns3::TypeId', [], is_static=True) + cls.add_method('GetTypeId', + 'ns3::TypeId', + [], + is_static=True) ## olsr-agent.h: void ns3::olsr::Agent::SetNode(ns3::Ptr node) [member function] - cls.add_method('SetNode', 'void', [param('ns3::Ptr< ns3::Node >', 'node')], is_pure_virtual=True, is_virtual=True) + cls.add_method('SetNode', + 'void', + [param('ns3::Ptr< ns3::Node >', 'node')], + is_pure_virtual=True, is_virtual=True) ## olsr-agent.h: void ns3::olsr::Agent::SetMainInterface(uint32_t interface) [member function] - cls.add_method('SetMainInterface', 'void', [param('uint32_t', 'interface')], is_pure_virtual=True, is_virtual=True) + cls.add_method('SetMainInterface', + 'void', + [param('uint32_t', 'interface')], + is_pure_virtual=True, is_virtual=True) ## olsr-agent.h: void ns3::olsr::Agent::Start() [member function] - cls.add_method('Start', 'void', [], is_pure_virtual=True, is_virtual=True) + cls.add_method('Start', + 'void', + [], + is_pure_virtual=True, is_virtual=True) cls.add_constructor([]) return def register_Ns3OlsrPacketHeader_methods(root_module, cls): ## olsr-header.h: ns3::olsr::PacketHeader::PacketHeader(ns3::olsr::PacketHeader const & arg0) [copy constructor] - cls.add_constructor([param('ns3::olsr::PacketHeader&', 'arg0', is_const=True)], visibility='public') + cls.add_constructor([param('ns3::olsr::PacketHeader&', 'arg0', is_const=True)]) ## olsr-header.h: ns3::olsr::PacketHeader::PacketHeader() [constructor] - cls.add_constructor([], visibility='public') + cls.add_constructor([]) ## olsr-header.h: uint32_t ns3::olsr::PacketHeader::Deserialize(ns3::Buffer::Iterator start) [member function] - cls.add_method('Deserialize', 'uint32_t', [param('ns3::Buffer::Iterator', 'start')], is_virtual=True) + cls.add_method('Deserialize', + 'uint32_t', + [param('ns3::Buffer::Iterator', 'start')], + is_virtual=True) ## olsr-header.h: ns3::TypeId ns3::olsr::PacketHeader::GetInstanceTypeId() const [member function] - cls.add_method('GetInstanceTypeId', 'ns3::TypeId', [], is_const=True, is_virtual=True) + cls.add_method('GetInstanceTypeId', + 'ns3::TypeId', + [], + is_const=True, is_virtual=True) ## olsr-header.h: uint16_t ns3::olsr::PacketHeader::GetPacketLength() const [member function] - cls.add_method('GetPacketLength', 'uint16_t', [], is_const=True) + cls.add_method('GetPacketLength', + 'uint16_t', + [], + is_const=True) ## olsr-header.h: uint16_t ns3::olsr::PacketHeader::GetPacketSequenceNumber() const [member function] - cls.add_method('GetPacketSequenceNumber', 'uint16_t', [], is_const=True) + cls.add_method('GetPacketSequenceNumber', + 'uint16_t', + [], + is_const=True) ## olsr-header.h: uint32_t ns3::olsr::PacketHeader::GetSerializedSize() const [member function] - cls.add_method('GetSerializedSize', 'uint32_t', [], is_const=True, is_virtual=True) + cls.add_method('GetSerializedSize', + 'uint32_t', + [], + is_const=True, is_virtual=True) ## olsr-header.h: static ns3::TypeId ns3::olsr::PacketHeader::GetTypeId() [member function] - cls.add_method('GetTypeId', 'ns3::TypeId', [], is_static=True) + cls.add_method('GetTypeId', + 'ns3::TypeId', + [], + is_static=True) ## olsr-header.h: void ns3::olsr::PacketHeader::Print(std::ostream & os) const [member function] - cls.add_method('Print', 'void', [param('std::ostream&', 'os')], is_const=True, is_virtual=True) + cls.add_method('Print', + 'void', + [param('std::ostream&', 'os')], + is_const=True, is_virtual=True) ## olsr-header.h: void ns3::olsr::PacketHeader::Serialize(ns3::Buffer::Iterator start) const [member function] - cls.add_method('Serialize', 'void', [param('ns3::Buffer::Iterator', 'start')], is_const=True, is_virtual=True) + cls.add_method('Serialize', + 'void', + [param('ns3::Buffer::Iterator', 'start')], + is_const=True, is_virtual=True) ## olsr-header.h: void ns3::olsr::PacketHeader::SetPacketLength(uint16_t length) [member function] - cls.add_method('SetPacketLength', 'void', [param('uint16_t', 'length')]) + cls.add_method('SetPacketLength', + 'void', + [param('uint16_t', 'length')]) ## olsr-header.h: void ns3::olsr::PacketHeader::SetPacketSequenceNumber(uint16_t seqnum) [member function] - cls.add_method('SetPacketSequenceNumber', 'void', [param('uint16_t', 'seqnum')]) + cls.add_method('SetPacketSequenceNumber', + 'void', + [param('uint16_t', 'seqnum')]) cls.add_output_stream_operator() return @@ -281,8 +438,12 @@ def register_functions_ns3_Config(module, root_module): def register_functions_ns3_olsr(module, root_module): ## olsr-header.h: extern double ns3::olsr::EmfToSeconds(uint8_t emf) [free function] - module.add_function('EmfToSeconds', 'double', [param('uint8_t', 'emf')]) + module.add_function('EmfToSeconds', + 'double', + [param('uint8_t', 'emf')]) ## olsr-header.h: extern uint8_t ns3::olsr::SecondsToEmf(double seconds) [free function] - module.add_function('SecondsToEmf', 'uint8_t', [param('double', 'seconds')]) + module.add_function('SecondsToEmf', + 'uint8_t', + [param('double', 'seconds')]) return diff --git a/bindings/python/ns3_module_onoff.py b/bindings/python/ns3_module_onoff.py index 08aa7d9ba..5546b3eb3 100644 --- a/bindings/python/ns3_module_onoff.py +++ b/bindings/python/ns3_module_onoff.py @@ -1,4 +1,4 @@ -from pybindgen import Module, FileCodeSink, write_preamble, param, retval +from pybindgen import Module, FileCodeSink, param, retval, cppclass def register_types(module): root_module = module.get_root() @@ -52,17 +52,31 @@ def register_methods(root_module): def register_Ns3OnOffApplication_methods(root_module, cls): ## onoff-application.h: static ns3::TypeId ns3::OnOffApplication::GetTypeId() [member function] - cls.add_method('GetTypeId', 'ns3::TypeId', [], is_static=True) + cls.add_method('GetTypeId', + 'ns3::TypeId', + [], + is_static=True) ## onoff-application.h: ns3::OnOffApplication::OnOffApplication() [constructor] - cls.add_constructor([], visibility='public') + cls.add_constructor([]) ## onoff-application.h: void ns3::OnOffApplication::SetMaxBytes(uint32_t maxBytes) [member function] - cls.add_method('SetMaxBytes', 'void', [param('uint32_t', 'maxBytes')]) + cls.add_method('SetMaxBytes', + 'void', + [param('uint32_t', 'maxBytes')]) ## onoff-application.h: void ns3::OnOffApplication::DoDispose() [member function] - cls.add_method('DoDispose', 'void', [], visibility='protected', is_virtual=True) + cls.add_method('DoDispose', + 'void', + [], + visibility='protected', is_virtual=True) ## onoff-application.h: void ns3::OnOffApplication::StartApplication() [member function] - cls.add_method('StartApplication', 'void', [], visibility='private', is_virtual=True) + cls.add_method('StartApplication', + 'void', + [], + visibility='private', is_virtual=True) ## onoff-application.h: void ns3::OnOffApplication::StopApplication() [member function] - cls.add_method('StopApplication', 'void', [], visibility='private', is_virtual=True) + cls.add_method('StopApplication', + 'void', + [], + visibility='private', is_virtual=True) return def register_functions(root_module): diff --git a/bindings/python/ns3_module_packet_sink.py b/bindings/python/ns3_module_packet_sink.py index 81ff49dfb..4a0bebed3 100644 --- a/bindings/python/ns3_module_packet_sink.py +++ b/bindings/python/ns3_module_packet_sink.py @@ -1,4 +1,4 @@ -from pybindgen import Module, FileCodeSink, write_preamble, param, retval +from pybindgen import Module, FileCodeSink, param, retval, cppclass def register_types(module): root_module = module.get_root() @@ -52,15 +52,27 @@ def register_methods(root_module): def register_Ns3PacketSink_methods(root_module, cls): ## packet-sink.h: static ns3::TypeId ns3::PacketSink::GetTypeId() [member function] - cls.add_method('GetTypeId', 'ns3::TypeId', [], is_static=True) + cls.add_method('GetTypeId', + 'ns3::TypeId', + [], + is_static=True) ## packet-sink.h: ns3::PacketSink::PacketSink() [constructor] - cls.add_constructor([], visibility='public') + cls.add_constructor([]) ## packet-sink.h: void ns3::PacketSink::DoDispose() [member function] - cls.add_method('DoDispose', 'void', [], visibility='protected', is_virtual=True) + cls.add_method('DoDispose', + 'void', + [], + visibility='protected', is_virtual=True) ## packet-sink.h: void ns3::PacketSink::StartApplication() [member function] - cls.add_method('StartApplication', 'void', [], visibility='private', is_virtual=True) + cls.add_method('StartApplication', + 'void', + [], + visibility='private', is_virtual=True) ## packet-sink.h: void ns3::PacketSink::StopApplication() [member function] - cls.add_method('StopApplication', 'void', [], visibility='private', is_virtual=True) + cls.add_method('StopApplication', + 'void', + [], + visibility='private', is_virtual=True) return def register_functions(root_module): diff --git a/bindings/python/ns3_module_point_to_point.py b/bindings/python/ns3_module_point_to_point.py index 790f75862..f83aa39ae 100644 --- a/bindings/python/ns3_module_point_to_point.py +++ b/bindings/python/ns3_module_point_to_point.py @@ -1,4 +1,4 @@ -from pybindgen import Module, FileCodeSink, write_preamble, param, retval +from pybindgen import Module, FileCodeSink, param, retval, cppclass def register_types(module): root_module = module.get_root() @@ -55,86 +55,188 @@ def register_methods(root_module): def register_Ns3PointToPointChannel_methods(root_module, cls): ## point-to-point-channel.h: static ns3::TypeId ns3::PointToPointChannel::GetTypeId() [member function] - cls.add_method('GetTypeId', 'ns3::TypeId', [], is_static=True) + cls.add_method('GetTypeId', + 'ns3::TypeId', + [], + is_static=True) ## point-to-point-channel.h: ns3::PointToPointChannel::PointToPointChannel() [constructor] - cls.add_constructor([], visibility='public') + cls.add_constructor([]) ## point-to-point-channel.h: void ns3::PointToPointChannel::Attach(ns3::Ptr device) [member function] - cls.add_method('Attach', 'void', [param('ns3::Ptr< ns3::PointToPointNetDevice >', 'device')]) + cls.add_method('Attach', + 'void', + [param('ns3::Ptr< ns3::PointToPointNetDevice >', 'device')]) ## point-to-point-channel.h: bool ns3::PointToPointChannel::TransmitStart(ns3::Ptr p, ns3::Ptr src, ns3::Time txTime) [member function] - cls.add_method('TransmitStart', 'bool', [param('ns3::Ptr< ns3::Packet >', 'p'), param('ns3::Ptr< ns3::PointToPointNetDevice >', 'src'), param('ns3::Time', 'txTime')]) + cls.add_method('TransmitStart', + 'bool', + [param('ns3::Ptr< ns3::Packet >', 'p'), param('ns3::Ptr< ns3::PointToPointNetDevice >', 'src'), param('ns3::Time', 'txTime')]) ## point-to-point-channel.h: uint32_t ns3::PointToPointChannel::GetNDevices() const [member function] - cls.add_method('GetNDevices', 'uint32_t', [], is_const=True, is_virtual=True) + cls.add_method('GetNDevices', + 'uint32_t', + [], + is_const=True, is_virtual=True) ## point-to-point-channel.h: ns3::Ptr ns3::PointToPointChannel::GetPointToPointDevice(uint32_t i) const [member function] - cls.add_method('GetPointToPointDevice', 'ns3::Ptr< ns3::PointToPointNetDevice >', [param('uint32_t', 'i')], is_const=True) + cls.add_method('GetPointToPointDevice', + 'ns3::Ptr< ns3::PointToPointNetDevice >', + [param('uint32_t', 'i')], + is_const=True) ## point-to-point-channel.h: ns3::Ptr ns3::PointToPointChannel::GetDevice(uint32_t i) const [member function] - cls.add_method('GetDevice', 'ns3::Ptr< ns3::NetDevice >', [param('uint32_t', 'i')], is_const=True, is_virtual=True) + cls.add_method('GetDevice', + 'ns3::Ptr< ns3::NetDevice >', + [param('uint32_t', 'i')], + is_const=True, is_virtual=True) return def register_Ns3PointToPointNetDevice_methods(root_module, cls): ## point-to-point-net-device.h: static ns3::TypeId ns3::PointToPointNetDevice::GetTypeId() [member function] - cls.add_method('GetTypeId', 'ns3::TypeId', [], is_static=True) + cls.add_method('GetTypeId', + 'ns3::TypeId', + [], + is_static=True) ## point-to-point-net-device.h: ns3::PointToPointNetDevice::PointToPointNetDevice() [constructor] - cls.add_constructor([], visibility='public') + cls.add_constructor([]) ## point-to-point-net-device.h: void ns3::PointToPointNetDevice::SetDataRate(ns3::DataRate bps) [member function] - cls.add_method('SetDataRate', 'void', [param('ns3::DataRate', 'bps')]) + cls.add_method('SetDataRate', + 'void', + [param('ns3::DataRate', 'bps')]) ## point-to-point-net-device.h: void ns3::PointToPointNetDevice::SetInterframeGap(ns3::Time t) [member function] - cls.add_method('SetInterframeGap', 'void', [param('ns3::Time', 't')]) + cls.add_method('SetInterframeGap', + 'void', + [param('ns3::Time', 't')]) ## point-to-point-net-device.h: bool ns3::PointToPointNetDevice::Attach(ns3::Ptr ch) [member function] - cls.add_method('Attach', 'bool', [param('ns3::Ptr< ns3::PointToPointChannel >', 'ch')]) + cls.add_method('Attach', + 'bool', + [param('ns3::Ptr< ns3::PointToPointChannel >', 'ch')]) ## point-to-point-net-device.h: void ns3::PointToPointNetDevice::SetQueue(ns3::Ptr queue) [member function] - cls.add_method('SetQueue', 'void', [param('ns3::Ptr< ns3::Queue >', 'queue')]) + cls.add_method('SetQueue', + 'void', + [param('ns3::Ptr< ns3::Queue >', 'queue')]) ## point-to-point-net-device.h: void ns3::PointToPointNetDevice::SetReceiveErrorModel(ns3::Ptr em) [member function] - cls.add_method('SetReceiveErrorModel', 'void', [param('ns3::Ptr< ns3::ErrorModel >', 'em')]) + cls.add_method('SetReceiveErrorModel', + 'void', + [param('ns3::Ptr< ns3::ErrorModel >', 'em')]) ## point-to-point-net-device.h: void ns3::PointToPointNetDevice::Receive(ns3::Ptr p) [member function] - cls.add_method('Receive', 'void', [param('ns3::Ptr< ns3::Packet >', 'p')]) + cls.add_method('Receive', + 'void', + [param('ns3::Ptr< ns3::Packet >', 'p')]) ## point-to-point-net-device.h: void ns3::PointToPointNetDevice::SetAddress(ns3::Mac48Address addr) [member function] - cls.add_method('SetAddress', 'void', [param('ns3::Mac48Address', 'addr')]) + cls.add_method('SetAddress', + 'void', + [param('ns3::Mac48Address', 'addr')]) ## point-to-point-net-device.h: void ns3::PointToPointNetDevice::SetName(std::string const name) [member function] - cls.add_method('SetName', 'void', [param('std::string', 'name', is_const=True)], is_virtual=True) + cls.add_method('SetName', + 'void', + [param('std::string', 'name', is_const=True)], + is_virtual=True) ## point-to-point-net-device.h: std::string ns3::PointToPointNetDevice::GetName() const [member function] - cls.add_method('GetName', 'std::string', [], is_const=True, is_virtual=True) + cls.add_method('GetName', + 'std::string', + [], + is_const=True, is_virtual=True) ## point-to-point-net-device.h: void ns3::PointToPointNetDevice::SetIfIndex(uint32_t const index) [member function] - cls.add_method('SetIfIndex', 'void', [param('uint32_t', 'index', is_const=True)], is_virtual=True) + cls.add_method('SetIfIndex', + 'void', + [param('uint32_t', 'index', is_const=True)], + is_virtual=True) ## point-to-point-net-device.h: uint32_t ns3::PointToPointNetDevice::GetIfIndex() const [member function] - cls.add_method('GetIfIndex', 'uint32_t', [], is_const=True, is_virtual=True) + cls.add_method('GetIfIndex', + 'uint32_t', + [], + is_const=True, is_virtual=True) ## point-to-point-net-device.h: ns3::Ptr ns3::PointToPointNetDevice::GetChannel() const [member function] - cls.add_method('GetChannel', 'ns3::Ptr< ns3::Channel >', [], is_const=True, is_virtual=True) + cls.add_method('GetChannel', + 'ns3::Ptr< ns3::Channel >', + [], + is_const=True, is_virtual=True) ## point-to-point-net-device.h: ns3::Address ns3::PointToPointNetDevice::GetAddress() const [member function] - cls.add_method('GetAddress', 'ns3::Address', [], is_const=True, is_virtual=True) + cls.add_method('GetAddress', + 'ns3::Address', + [], + is_const=True, is_virtual=True) ## point-to-point-net-device.h: bool ns3::PointToPointNetDevice::SetMtu(uint16_t const mtu) [member function] - cls.add_method('SetMtu', 'bool', [param('uint16_t', 'mtu', is_const=True)], is_virtual=True) + cls.add_method('SetMtu', + 'bool', + [param('uint16_t', 'mtu', is_const=True)], + is_virtual=True) ## point-to-point-net-device.h: uint16_t ns3::PointToPointNetDevice::GetMtu() const [member function] - cls.add_method('GetMtu', 'uint16_t', [], is_const=True, is_virtual=True) + cls.add_method('GetMtu', + 'uint16_t', + [], + is_const=True, is_virtual=True) ## point-to-point-net-device.h: bool ns3::PointToPointNetDevice::IsLinkUp() const [member function] - cls.add_method('IsLinkUp', 'bool', [], is_const=True, is_virtual=True) + cls.add_method('IsLinkUp', + 'bool', + [], + is_const=True, is_virtual=True) ## point-to-point-net-device.h: void ns3::PointToPointNetDevice::SetLinkChangeCallback(ns3::Callback callback) [member function] - cls.add_method('SetLinkChangeCallback', 'void', [param('ns3::Callback< void, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty >', 'callback')], is_virtual=True) + cls.add_method('SetLinkChangeCallback', + 'void', + [param('ns3::Callback< void, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty >', 'callback')], + is_virtual=True) ## point-to-point-net-device.h: bool ns3::PointToPointNetDevice::IsBroadcast() const [member function] - cls.add_method('IsBroadcast', 'bool', [], is_const=True, is_virtual=True) + cls.add_method('IsBroadcast', + 'bool', + [], + is_const=True, is_virtual=True) ## point-to-point-net-device.h: ns3::Address ns3::PointToPointNetDevice::GetBroadcast() const [member function] - cls.add_method('GetBroadcast', 'ns3::Address', [], is_const=True, is_virtual=True) + cls.add_method('GetBroadcast', + 'ns3::Address', + [], + is_const=True, is_virtual=True) ## point-to-point-net-device.h: bool ns3::PointToPointNetDevice::IsMulticast() const [member function] - cls.add_method('IsMulticast', 'bool', [], is_const=True, is_virtual=True) + cls.add_method('IsMulticast', + 'bool', + [], + is_const=True, is_virtual=True) ## point-to-point-net-device.h: ns3::Address ns3::PointToPointNetDevice::GetMulticast() const [member function] - cls.add_method('GetMulticast', 'ns3::Address', [], is_const=True, is_virtual=True) + cls.add_method('GetMulticast', + 'ns3::Address', + [], + is_const=True, is_virtual=True) ## point-to-point-net-device.h: ns3::Address ns3::PointToPointNetDevice::MakeMulticastAddress(ns3::Ipv4Address multicastGroup) const [member function] - cls.add_method('MakeMulticastAddress', 'ns3::Address', [param('ns3::Ipv4Address', 'multicastGroup')], is_const=True, is_virtual=True) + cls.add_method('MakeMulticastAddress', + 'ns3::Address', + [param('ns3::Ipv4Address', 'multicastGroup')], + is_const=True, is_virtual=True) ## point-to-point-net-device.h: bool ns3::PointToPointNetDevice::IsPointToPoint() const [member function] - cls.add_method('IsPointToPoint', 'bool', [], is_const=True, is_virtual=True) + cls.add_method('IsPointToPoint', + 'bool', + [], + is_const=True, is_virtual=True) ## point-to-point-net-device.h: bool ns3::PointToPointNetDevice::Send(ns3::Ptr packet, ns3::Address const & dest, uint16_t protocolNumber) [member function] - cls.add_method('Send', 'bool', [param('ns3::Ptr< ns3::Packet >', 'packet'), param('ns3::Address&', 'dest', is_const=True), param('uint16_t', 'protocolNumber')], is_virtual=True) + cls.add_method('Send', + 'bool', + [param('ns3::Ptr< ns3::Packet >', 'packet'), param('ns3::Address&', 'dest', is_const=True), param('uint16_t', 'protocolNumber')], + is_virtual=True) ## point-to-point-net-device.h: bool ns3::PointToPointNetDevice::SendFrom(ns3::Ptr packet, ns3::Address const & source, ns3::Address const & dest, uint16_t protocolNumber) [member function] - cls.add_method('SendFrom', 'bool', [param('ns3::Ptr< ns3::Packet >', 'packet'), param('ns3::Address&', 'source', is_const=True), param('ns3::Address&', 'dest', is_const=True), param('uint16_t', 'protocolNumber')], is_virtual=True) + cls.add_method('SendFrom', + 'bool', + [param('ns3::Ptr< ns3::Packet >', 'packet'), param('ns3::Address&', 'source', is_const=True), param('ns3::Address&', 'dest', is_const=True), param('uint16_t', 'protocolNumber')], + is_virtual=True) ## point-to-point-net-device.h: ns3::Ptr ns3::PointToPointNetDevice::GetNode() const [member function] - cls.add_method('GetNode', 'ns3::Ptr< ns3::Node >', [], is_const=True, is_virtual=True) + cls.add_method('GetNode', + 'ns3::Ptr< ns3::Node >', + [], + is_const=True, is_virtual=True) ## point-to-point-net-device.h: void ns3::PointToPointNetDevice::SetNode(ns3::Ptr node) [member function] - cls.add_method('SetNode', 'void', [param('ns3::Ptr< ns3::Node >', 'node')], is_virtual=True) + cls.add_method('SetNode', + 'void', + [param('ns3::Ptr< ns3::Node >', 'node')], + is_virtual=True) ## point-to-point-net-device.h: bool ns3::PointToPointNetDevice::NeedsArp() const [member function] - cls.add_method('NeedsArp', 'bool', [], is_const=True, is_virtual=True) + cls.add_method('NeedsArp', + 'bool', + [], + is_const=True, is_virtual=True) ## point-to-point-net-device.h: void ns3::PointToPointNetDevice::SetReceiveCallback(ns3::Callback, ns3::Ptr, unsigned short, ns3::Address const&, ns3::empty, ns3::empty> cb) [member function] - cls.add_method('SetReceiveCallback', 'void', [param('ns3::Callback< bool, ns3::Ptr< ns3::NetDevice >, ns3::Ptr< ns3::Packet >, unsigned short, ns3::Address const&, ns3::empty, ns3::empty >', 'cb')], is_virtual=True) + cls.add_method('SetReceiveCallback', + 'void', + [param('ns3::Callback< bool, ns3::Ptr< ns3::NetDevice >, ns3::Ptr< ns3::Packet >, unsigned short, ns3::Address const&, ns3::empty, ns3::empty >', 'cb')], + is_virtual=True) ## point-to-point-net-device.h: void ns3::PointToPointNetDevice::DoDispose() [member function] - cls.add_method('DoDispose', 'void', [], visibility='private', is_virtual=True) + cls.add_method('DoDispose', + 'void', + [], + visibility='private', is_virtual=True) return def register_functions(root_module): diff --git a/bindings/python/ns3_module_simulator.py b/bindings/python/ns3_module_simulator.py index 9c837f9d0..768adf504 100644 --- a/bindings/python/ns3_module_simulator.py +++ b/bindings/python/ns3_module_simulator.py @@ -1,4 +1,4 @@ -from pybindgen import Module, FileCodeSink, write_preamble, param, retval +from pybindgen import Module, FileCodeSink, param, retval, cppclass def register_types(module): root_module = module.get_root() @@ -103,217 +103,421 @@ def register_methods(root_module): def register_Ns3Timer_methods(root_module, cls): ## timer.h: ns3::Timer::Timer() [constructor] - cls.add_constructor([], visibility='public') + cls.add_constructor([]) ## timer.h: ns3::Timer::Timer(ns3::Timer::DestroyPolicy destroyPolicy) [constructor] - cls.add_constructor([param('ns3::Timer::DestroyPolicy', 'destroyPolicy')], visibility='public') + cls.add_constructor([param('ns3::Timer::DestroyPolicy', 'destroyPolicy')]) ## timer.h: void ns3::Timer::SetDelay(ns3::Time const & delay) [member function] - cls.add_method('SetDelay', 'void', [param('ns3::Time&', 'delay', is_const=True)]) + cls.add_method('SetDelay', + 'void', + [param('ns3::Time&', 'delay', is_const=True)]) ## timer.h: ns3::Time ns3::Timer::GetDelay() const [member function] - cls.add_method('GetDelay', 'ns3::Time', [], is_const=True) + cls.add_method('GetDelay', + 'ns3::Time', + [], + is_const=True) ## timer.h: ns3::Time ns3::Timer::GetDelayLeft() const [member function] - cls.add_method('GetDelayLeft', 'ns3::Time', [], is_const=True) + cls.add_method('GetDelayLeft', + 'ns3::Time', + [], + is_const=True) ## timer.h: void ns3::Timer::Cancel() [member function] - cls.add_method('Cancel', 'void', []) + cls.add_method('Cancel', + 'void', + []) ## timer.h: void ns3::Timer::Remove() [member function] - cls.add_method('Remove', 'void', []) + cls.add_method('Remove', + 'void', + []) ## timer.h: bool ns3::Timer::IsExpired() const [member function] - cls.add_method('IsExpired', 'bool', [], is_const=True) + cls.add_method('IsExpired', + 'bool', + [], + is_const=True) ## timer.h: bool ns3::Timer::IsRunning() const [member function] - cls.add_method('IsRunning', 'bool', [], is_const=True) + cls.add_method('IsRunning', + 'bool', + [], + is_const=True) ## timer.h: bool ns3::Timer::IsSuspended() const [member function] - cls.add_method('IsSuspended', 'bool', [], is_const=True) + cls.add_method('IsSuspended', + 'bool', + [], + is_const=True) ## timer.h: ns3::Timer::State ns3::Timer::GetState() const [member function] - cls.add_method('GetState', 'ns3::Timer::State', [], is_const=True) + cls.add_method('GetState', + 'ns3::Timer::State', + [], + is_const=True) ## timer.h: void ns3::Timer::Schedule() [member function] - cls.add_method('Schedule', 'void', []) + cls.add_method('Schedule', + 'void', + []) ## timer.h: void ns3::Timer::Schedule(ns3::Time delay) [member function] - cls.add_method('Schedule', 'void', [param('ns3::Time', 'delay')]) + cls.add_method('Schedule', + 'void', + [param('ns3::Time', 'delay')]) ## timer.h: void ns3::Timer::Suspend() [member function] - cls.add_method('Suspend', 'void', []) + cls.add_method('Suspend', + 'void', + []) ## timer.h: void ns3::Timer::Resume() [member function] - cls.add_method('Resume', 'void', []) + cls.add_method('Resume', + 'void', + []) return def register_Ns3TimerImpl_methods(root_module, cls): ## timer-impl.h: ns3::EventId ns3::TimerImpl::Schedule(ns3::Time const & delay) [member function] - cls.add_method('Schedule', 'ns3::EventId', [param('ns3::Time&', 'delay', is_const=True)], is_pure_virtual=True, is_virtual=True) + cls.add_method('Schedule', + 'ns3::EventId', + [param('ns3::Time&', 'delay', is_const=True)], + is_pure_virtual=True, is_virtual=True) ## timer-impl.h: void ns3::TimerImpl::Invoke() [member function] - cls.add_method('Invoke', 'void', [], is_pure_virtual=True, is_virtual=True) + cls.add_method('Invoke', + 'void', + [], + is_pure_virtual=True, is_virtual=True) cls.add_constructor([]) return def register_Ns3Time_methods(root_module, cls): ## nstime.h: ns3::TimeUnit<1>::TimeUnit(std::string const & s) [constructor] - cls.add_constructor([param('std::string&', 's', is_const=True)], visibility='public') + cls.add_constructor([param('std::string&', 's', is_const=True)]) ## nstime.h: ns3::TimeUnit<1>::TimeUnit() [constructor] - cls.add_constructor([], visibility='public') + cls.add_constructor([]) ## nstime.h: ns3::TimeUnit<1>::TimeUnit(ns3::TimeUnit<1> const & o) [copy constructor] - cls.add_constructor([param('ns3::Time&', 'o', is_const=True)], visibility='public') + cls.add_constructor([param('ns3::Time&', 'o', is_const=True)]) ## nstime.h: ns3::TimeUnit<1>::TimeUnit(ns3::HighPrecision data) [constructor] - cls.add_constructor([param('ns3::HighPrecision', 'data')], visibility='public') + cls.add_constructor([param('ns3::HighPrecision', 'data')]) ## nstime.h: int64_t ns3::TimeUnit<1>::GetFemtoSeconds() const [member function] - cls.add_method('GetFemtoSeconds', 'int64_t', [], is_const=True) + cls.add_method('GetFemtoSeconds', + 'int64_t', + [], + is_const=True) ## nstime.h: ns3::HighPrecision const & ns3::TimeUnit<1>::GetHighPrecision() const [member function] - cls.add_method('GetHighPrecision', retval('ns3::HighPrecision&', is_const=True), [], is_const=True) + cls.add_method('GetHighPrecision', + retval('ns3::HighPrecision&', is_const=True), + [], + is_const=True) ## nstime.h: int64_t ns3::TimeUnit<1>::GetMicroSeconds() const [member function] - cls.add_method('GetMicroSeconds', 'int64_t', [], is_const=True) + cls.add_method('GetMicroSeconds', + 'int64_t', + [], + is_const=True) ## nstime.h: int64_t ns3::TimeUnit<1>::GetMilliSeconds() const [member function] - cls.add_method('GetMilliSeconds', 'int64_t', [], is_const=True) + cls.add_method('GetMilliSeconds', + 'int64_t', + [], + is_const=True) ## nstime.h: int64_t ns3::TimeUnit<1>::GetNanoSeconds() const [member function] - cls.add_method('GetNanoSeconds', 'int64_t', [], is_const=True) + cls.add_method('GetNanoSeconds', + 'int64_t', + [], + is_const=True) ## nstime.h: int64_t ns3::TimeUnit<1>::GetPicoSeconds() const [member function] - cls.add_method('GetPicoSeconds', 'int64_t', [], is_const=True) + cls.add_method('GetPicoSeconds', + 'int64_t', + [], + is_const=True) ## nstime.h: double ns3::TimeUnit<1>::GetSeconds() const [member function] - cls.add_method('GetSeconds', 'double', [], is_const=True) + cls.add_method('GetSeconds', + 'double', + [], + is_const=True) ## nstime.h: int64_t ns3::TimeUnit<1>::GetTimeStep() const [member function] - cls.add_method('GetTimeStep', 'int64_t', [], is_const=True) + cls.add_method('GetTimeStep', + 'int64_t', + [], + is_const=True) ## nstime.h: bool ns3::TimeUnit<1>::IsNegative() const [member function] - cls.add_method('IsNegative', 'bool', [], is_const=True) + cls.add_method('IsNegative', + 'bool', + [], + is_const=True) ## nstime.h: bool ns3::TimeUnit<1>::IsPositive() const [member function] - cls.add_method('IsPositive', 'bool', [], is_const=True) + cls.add_method('IsPositive', + 'bool', + [], + is_const=True) ## nstime.h: bool ns3::TimeUnit<1>::IsStrictlyNegative() const [member function] - cls.add_method('IsStrictlyNegative', 'bool', [], is_const=True) + cls.add_method('IsStrictlyNegative', + 'bool', + [], + is_const=True) ## nstime.h: bool ns3::TimeUnit<1>::IsStrictlyPositive() const [member function] - cls.add_method('IsStrictlyPositive', 'bool', [], is_const=True) + cls.add_method('IsStrictlyPositive', + 'bool', + [], + is_const=True) ## nstime.h: bool ns3::TimeUnit<1>::IsZero() const [member function] - cls.add_method('IsZero', 'bool', [], is_const=True) + cls.add_method('IsZero', + 'bool', + [], + is_const=True) ## nstime.h: ns3::HighPrecision * ns3::TimeUnit<1>::PeekHighPrecision() [member function] - cls.add_method('PeekHighPrecision', 'ns3::HighPrecision *', []) + cls.add_method('PeekHighPrecision', + 'ns3::HighPrecision *', + []) ## nstime.h: static uint64_t ns3::TimeUnit<1>::UnitsToTimestep(uint64_t unitValue, uint64_t unitFactor) [member function] - cls.add_method('UnitsToTimestep', 'uint64_t', [param('uint64_t', 'unitValue'), param('uint64_t', 'unitFactor')], is_static=True) + cls.add_method('UnitsToTimestep', + 'uint64_t', + [param('uint64_t', 'unitValue'), param('uint64_t', 'unitFactor')], + is_static=True) cls.add_output_stream_operator() return def register_Ns3Scalar_methods(root_module, cls): ## nstime.h: ns3::TimeUnit<0>::TimeUnit(double scalar) [constructor] - cls.add_constructor([param('double', 'scalar')], visibility='public') + cls.add_constructor([param('double', 'scalar')]) ## nstime.h: ns3::TimeUnit<0>::TimeUnit() [constructor] - cls.add_constructor([], visibility='public') + cls.add_constructor([]) ## nstime.h: ns3::TimeUnit<0>::TimeUnit(ns3::TimeUnit<0> const & o) [copy constructor] - cls.add_constructor([param('ns3::Scalar&', 'o', is_const=True)], visibility='public') + cls.add_constructor([param('ns3::Scalar&', 'o', is_const=True)]) ## nstime.h: ns3::TimeUnit<0>::TimeUnit(ns3::HighPrecision data) [constructor] - cls.add_constructor([param('ns3::HighPrecision', 'data')], visibility='public') + cls.add_constructor([param('ns3::HighPrecision', 'data')]) ## nstime.h: double ns3::TimeUnit<0>::GetDouble() const [member function] - cls.add_method('GetDouble', 'double', [], is_const=True) + cls.add_method('GetDouble', + 'double', + [], + is_const=True) ## nstime.h: ns3::HighPrecision const & ns3::TimeUnit<0>::GetHighPrecision() const [member function] - cls.add_method('GetHighPrecision', retval('ns3::HighPrecision&', is_const=True), [], is_const=True) + cls.add_method('GetHighPrecision', + retval('ns3::HighPrecision&', is_const=True), + [], + is_const=True) ## nstime.h: bool ns3::TimeUnit<0>::IsNegative() const [member function] - cls.add_method('IsNegative', 'bool', [], is_const=True) + cls.add_method('IsNegative', + 'bool', + [], + is_const=True) ## nstime.h: bool ns3::TimeUnit<0>::IsPositive() const [member function] - cls.add_method('IsPositive', 'bool', [], is_const=True) + cls.add_method('IsPositive', + 'bool', + [], + is_const=True) ## nstime.h: bool ns3::TimeUnit<0>::IsStrictlyNegative() const [member function] - cls.add_method('IsStrictlyNegative', 'bool', [], is_const=True) + cls.add_method('IsStrictlyNegative', + 'bool', + [], + is_const=True) ## nstime.h: bool ns3::TimeUnit<0>::IsStrictlyPositive() const [member function] - cls.add_method('IsStrictlyPositive', 'bool', [], is_const=True) + cls.add_method('IsStrictlyPositive', + 'bool', + [], + is_const=True) ## nstime.h: bool ns3::TimeUnit<0>::IsZero() const [member function] - cls.add_method('IsZero', 'bool', [], is_const=True) + cls.add_method('IsZero', + 'bool', + [], + is_const=True) ## nstime.h: ns3::HighPrecision * ns3::TimeUnit<0>::PeekHighPrecision() [member function] - cls.add_method('PeekHighPrecision', 'ns3::HighPrecision *', []) + cls.add_method('PeekHighPrecision', + 'ns3::HighPrecision *', + []) return def register_Ns3Watchdog_methods(root_module, cls): ## watchdog.h: ns3::Watchdog::Watchdog() [constructor] - cls.add_constructor([], visibility='public') + cls.add_constructor([]) ## watchdog.h: void ns3::Watchdog::Ping(ns3::Time delay) [member function] - cls.add_method('Ping', 'void', [param('ns3::Time', 'delay')]) + cls.add_method('Ping', + 'void', + [param('ns3::Time', 'delay')]) return def register_Ns3Simulator_methods(root_module, cls): ## simulator.h: static void ns3::Simulator::SetScheduler(ns3::Ptr scheduler) [member function] - cls.add_method('SetScheduler', 'void', [param('ns3::Ptr< ns3::Scheduler >', 'scheduler')], is_static=True) + cls.add_method('SetScheduler', + 'void', + [param('ns3::Ptr< ns3::Scheduler >', 'scheduler')], + is_static=True) ## simulator.h: static void ns3::Simulator::EnableLogTo(char const * filename) [member function] - cls.add_method('EnableLogTo', 'void', [param('char *', 'filename', transfer_ownership=False, is_const=True)], is_static=True) + cls.add_method('EnableLogTo', + 'void', + [param('char *', 'filename', transfer_ownership=False, is_const=True)], + is_static=True) ## simulator.h: static void ns3::Simulator::Destroy() [member function] - cls.add_method('Destroy', 'void', [], is_static=True) + cls.add_method('Destroy', + 'void', + [], + is_static=True) ## simulator.h: static bool ns3::Simulator::IsFinished() [member function] - cls.add_method('IsFinished', 'bool', [], is_static=True) + cls.add_method('IsFinished', + 'bool', + [], + is_static=True) ## simulator.h: static ns3::Time ns3::Simulator::Next() [member function] - cls.add_method('Next', 'ns3::Time', [], is_static=True) + cls.add_method('Next', + 'ns3::Time', + [], + is_static=True) ## simulator.h: static void ns3::Simulator::Run() [member function] - cls.add_method('Run', 'void', [], is_static=True) + cls.add_method('Run', + 'void', + [], + is_static=True) ## simulator.h: static void ns3::Simulator::Stop() [member function] - cls.add_method('Stop', 'void', [], is_static=True) + cls.add_method('Stop', + 'void', + [], + is_static=True) ## simulator.h: static void ns3::Simulator::Stop(ns3::Time const & time) [member function] - cls.add_method('Stop', 'void', [param('ns3::Time&', 'time', is_const=True)], is_static=True) + cls.add_method('Stop', + 'void', + [param('ns3::Time&', 'time', is_const=True)], + is_static=True) ## simulator.h: static void ns3::Simulator::Remove(ns3::EventId const & id) [member function] - cls.add_method('Remove', 'void', [param('ns3::EventId&', 'id', is_const=True)], is_static=True) + cls.add_method('Remove', + 'void', + [param('ns3::EventId&', 'id', is_const=True)], + is_static=True) ## simulator.h: static void ns3::Simulator::Cancel(ns3::EventId const & id) [member function] - cls.add_method('Cancel', 'void', [param('ns3::EventId&', 'id', is_const=True)], is_static=True) + cls.add_method('Cancel', + 'void', + [param('ns3::EventId&', 'id', is_const=True)], + is_static=True) ## simulator.h: static bool ns3::Simulator::IsExpired(ns3::EventId const & id) [member function] - cls.add_method('IsExpired', 'bool', [param('ns3::EventId&', 'id', is_const=True)], is_static=True) + cls.add_method('IsExpired', + 'bool', + [param('ns3::EventId&', 'id', is_const=True)], + is_static=True) ## simulator.h: static ns3::Time ns3::Simulator::Now() [member function] - cls.add_method('Now', 'ns3::Time', [], is_static=True) + cls.add_method('Now', + 'ns3::Time', + [], + is_static=True) ## simulator.h: static ns3::Time ns3::Simulator::GetDelayLeft(ns3::EventId const & id) [member function] - cls.add_method('GetDelayLeft', 'ns3::Time', [param('ns3::EventId&', 'id', is_const=True)], is_static=True) + cls.add_method('GetDelayLeft', + 'ns3::Time', + [param('ns3::EventId&', 'id', is_const=True)], + is_static=True) ## simulator.h: static ns3::Time ns3::Simulator::GetMaximumSimulationTime() [member function] - cls.add_method('GetMaximumSimulationTime', 'ns3::Time', [], is_static=True) + cls.add_method('GetMaximumSimulationTime', + 'ns3::Time', + [], + is_static=True) return def register_Ns3EventId_methods(root_module, cls): ## event-id.h: ns3::EventId::EventId(ns3::EventId const & arg0) [copy constructor] - cls.add_constructor([param('ns3::EventId&', 'arg0', is_const=True)], visibility='public') + cls.add_constructor([param('ns3::EventId&', 'arg0', is_const=True)]) ## event-id.h: ns3::EventId::EventId() [constructor] - cls.add_constructor([], visibility='public') + cls.add_constructor([]) ## event-id.h: ns3::EventId::EventId(ns3::Ptr const & impl, uint64_t ts, uint32_t uid) [constructor] - cls.add_constructor([param('ns3::Ptr< ns3::EventImpl >&', 'impl', is_const=True), param('uint64_t', 'ts'), param('uint32_t', 'uid')], visibility='public') + cls.add_constructor([param('ns3::Ptr< ns3::EventImpl >&', 'impl', is_const=True), param('uint64_t', 'ts'), param('uint32_t', 'uid')]) ## event-id.h: void ns3::EventId::Cancel() [member function] - cls.add_method('Cancel', 'void', []) + cls.add_method('Cancel', + 'void', + []) ## event-id.h: bool ns3::EventId::IsExpired() const [member function] - cls.add_method('IsExpired', 'bool', [], is_const=True) + cls.add_method('IsExpired', + 'bool', + [], + is_const=True) ## event-id.h: bool ns3::EventId::IsRunning() const [member function] - cls.add_method('IsRunning', 'bool', [], is_const=True) + cls.add_method('IsRunning', + 'bool', + [], + is_const=True) ## event-id.h: ns3::EventImpl * ns3::EventId::PeekEventImpl() const [member function] - cls.add_method('PeekEventImpl', 'ns3::EventImpl *', [], is_const=True) + cls.add_method('PeekEventImpl', + 'ns3::EventImpl *', + [], + is_const=True) ## event-id.h: uint64_t ns3::EventId::GetTs() const [member function] - cls.add_method('GetTs', 'uint64_t', [], is_const=True) + cls.add_method('GetTs', + 'uint64_t', + [], + is_const=True) ## event-id.h: uint32_t ns3::EventId::GetUid() const [member function] - cls.add_method('GetUid', 'uint32_t', [], is_const=True) + cls.add_method('GetUid', + 'uint32_t', + [], + is_const=True) return def register_Ns3EventImpl_methods(root_module, cls): ## event-impl.h: ns3::EventImpl::EventImpl() [constructor] - cls.add_constructor([], visibility='public') + cls.add_constructor([]) ## event-impl.h: void ns3::EventImpl::Ref() const [member function] - cls.add_method('Ref', 'void', [], is_const=True) + cls.add_method('Ref', + 'void', + [], + is_const=True) ## event-impl.h: void ns3::EventImpl::Unref() const [member function] - cls.add_method('Unref', 'void', [], is_const=True) + cls.add_method('Unref', + 'void', + [], + is_const=True) ## event-impl.h: void ns3::EventImpl::Invoke() [member function] - cls.add_method('Invoke', 'void', []) + cls.add_method('Invoke', + 'void', + []) ## event-impl.h: void ns3::EventImpl::Cancel() [member function] - cls.add_method('Cancel', 'void', []) + cls.add_method('Cancel', + 'void', + []) ## event-impl.h: bool ns3::EventImpl::IsCancelled() [member function] - cls.add_method('IsCancelled', 'bool', []) + cls.add_method('IsCancelled', + 'bool', + []) ## event-impl.h: void ns3::EventImpl::Notify() [member function] - cls.add_method('Notify', 'void', [], is_pure_virtual=True, visibility='protected', is_virtual=True) + cls.add_method('Notify', + 'void', + [], + is_pure_virtual=True, visibility='protected', is_virtual=True) return def register_Ns3HighPrecision_methods(root_module, cls): ## high-precision-128.h: ns3::HighPrecision::HighPrecision(ns3::HighPrecision const & arg0) [copy constructor] - cls.add_constructor([param('ns3::HighPrecision&', 'arg0', is_const=True)], visibility='public') + cls.add_constructor([param('ns3::HighPrecision&', 'arg0', is_const=True)]) ## high-precision-128.h: ns3::HighPrecision::HighPrecision() [constructor] - cls.add_constructor([], visibility='public') + cls.add_constructor([]) ## high-precision-128.h: ns3::HighPrecision::HighPrecision(int64_t value, bool dummy) [constructor] - cls.add_constructor([param('int64_t', 'value'), param('bool', 'dummy')], visibility='public') + cls.add_constructor([param('int64_t', 'value'), param('bool', 'dummy')]) ## high-precision-128.h: ns3::HighPrecision::HighPrecision(double value) [constructor] - cls.add_constructor([param('double', 'value')], visibility='public') + cls.add_constructor([param('double', 'value')]) ## high-precision-128.h: static void ns3::HighPrecision::PrintStats() [member function] - cls.add_method('PrintStats', 'void', [], is_static=True) + cls.add_method('PrintStats', + 'void', + [], + is_static=True) ## high-precision-128.h: int64_t ns3::HighPrecision::GetInteger() const [member function] - cls.add_method('GetInteger', 'int64_t', [], is_const=True) + cls.add_method('GetInteger', + 'int64_t', + [], + is_const=True) ## high-precision-128.h: double ns3::HighPrecision::GetDouble() const [member function] - cls.add_method('GetDouble', 'double', [], is_const=True) + cls.add_method('GetDouble', + 'double', + [], + is_const=True) ## high-precision-128.h: bool ns3::HighPrecision::Add(ns3::HighPrecision const & o) [member function] - cls.add_method('Add', 'bool', [param('ns3::HighPrecision&', 'o', is_const=True)]) + cls.add_method('Add', + 'bool', + [param('ns3::HighPrecision&', 'o', is_const=True)]) ## high-precision-128.h: bool ns3::HighPrecision::Sub(ns3::HighPrecision const & o) [member function] - cls.add_method('Sub', 'bool', [param('ns3::HighPrecision&', 'o', is_const=True)]) + cls.add_method('Sub', + 'bool', + [param('ns3::HighPrecision&', 'o', is_const=True)]) ## high-precision-128.h: bool ns3::HighPrecision::Mul(ns3::HighPrecision const & o) [member function] - cls.add_method('Mul', 'bool', [param('ns3::HighPrecision&', 'o', is_const=True)]) + cls.add_method('Mul', + 'bool', + [param('ns3::HighPrecision&', 'o', is_const=True)]) ## high-precision-128.h: bool ns3::HighPrecision::Div(ns3::HighPrecision const & o) [member function] - cls.add_method('Div', 'bool', [param('ns3::HighPrecision&', 'o', is_const=True)]) + cls.add_method('Div', + 'bool', + [param('ns3::HighPrecision&', 'o', is_const=True)]) ## high-precision-128.h: int ns3::HighPrecision::Compare(ns3::HighPrecision const & o) const [member function] - cls.add_method('Compare', 'int', [param('ns3::HighPrecision&', 'o', is_const=True)], is_const=True) + cls.add_method('Compare', + 'int', + [param('ns3::HighPrecision&', 'o', is_const=True)], + is_const=True) ## high-precision-128.h: static ns3::HighPrecision ns3::HighPrecision::Zero() [member function] - cls.add_method('Zero', 'ns3::HighPrecision', [], is_static=True) + cls.add_method('Zero', + 'ns3::HighPrecision', + [], + is_static=True) return def register_Ns3TimeChecker_methods(root_module, cls): @@ -322,17 +526,35 @@ def register_Ns3TimeChecker_methods(root_module, cls): def register_Ns3Scheduler_methods(root_module, cls): ## scheduler.h: static ns3::TypeId ns3::Scheduler::GetTypeId() [member function] - cls.add_method('GetTypeId', 'ns3::TypeId', [], is_static=True) + cls.add_method('GetTypeId', + 'ns3::TypeId', + [], + is_static=True) ## scheduler.h: void ns3::Scheduler::Insert(ns3::EventId const & id) [member function] - cls.add_method('Insert', 'void', [param('ns3::EventId&', 'id', is_const=True)], is_pure_virtual=True, is_virtual=True) + cls.add_method('Insert', + 'void', + [param('ns3::EventId&', 'id', is_const=True)], + is_pure_virtual=True, is_virtual=True) ## scheduler.h: bool ns3::Scheduler::IsEmpty() const [member function] - cls.add_method('IsEmpty', 'bool', [], is_pure_virtual=True, is_const=True, is_virtual=True) + cls.add_method('IsEmpty', + 'bool', + [], + is_pure_virtual=True, is_const=True, is_virtual=True) ## scheduler.h: ns3::EventId ns3::Scheduler::PeekNext() const [member function] - cls.add_method('PeekNext', 'ns3::EventId', [], is_pure_virtual=True, is_const=True, is_virtual=True) + cls.add_method('PeekNext', + 'ns3::EventId', + [], + is_pure_virtual=True, is_const=True, is_virtual=True) ## scheduler.h: ns3::EventId ns3::Scheduler::RemoveNext() [member function] - cls.add_method('RemoveNext', 'ns3::EventId', [], is_pure_virtual=True, is_virtual=True) + cls.add_method('RemoveNext', + 'ns3::EventId', + [], + is_pure_virtual=True, is_virtual=True) ## scheduler.h: bool ns3::Scheduler::Remove(ns3::EventId const & id) [member function] - cls.add_method('Remove', 'bool', [param('ns3::EventId&', 'id', is_const=True)], is_pure_virtual=True, is_virtual=True) + cls.add_method('Remove', + 'bool', + [param('ns3::EventId&', 'id', is_const=True)], + is_pure_virtual=True, is_virtual=True) cls.add_constructor([]) return @@ -346,92 +568,175 @@ def register_Ns3SchedulerEventKey_methods(root_module, cls): def register_Ns3TimeValue_methods(root_module, cls): ## nstime.h: ns3::TimeValue::TimeValue() [constructor] - cls.add_constructor([], visibility='public') + cls.add_constructor([]) ## nstime.h: ns3::TimeValue::TimeValue(ns3::Time const & value) [constructor] - cls.add_constructor([param('ns3::Time&', 'value', is_const=True)], visibility='public') + cls.add_constructor([param('ns3::Time&', 'value', is_const=True)]) ## nstime.h: void ns3::TimeValue::Set(ns3::Time const & value) [member function] - cls.add_method('Set', 'void', [param('ns3::Time&', 'value', is_const=True)]) + cls.add_method('Set', + 'void', + [param('ns3::Time&', 'value', is_const=True)]) ## nstime.h: ns3::Time ns3::TimeValue::Get() const [member function] - cls.add_method('Get', 'ns3::Time', [], is_const=True) + cls.add_method('Get', + 'ns3::Time', + [], + is_const=True) ## nstime.h: ns3::Ptr ns3::TimeValue::Copy() const [member function] - cls.add_method('Copy', 'ns3::Ptr< ns3::AttributeValue >', [], is_const=True, is_virtual=True) + cls.add_method('Copy', + 'ns3::Ptr< ns3::AttributeValue >', + [], + is_const=True, is_virtual=True) ## nstime.h: std::string ns3::TimeValue::SerializeToString(ns3::Ptr checker) const [member function] - cls.add_method('SerializeToString', 'std::string', [param('ns3::Ptr< ns3::AttributeChecker const >', 'checker')], is_const=True, is_virtual=True) + cls.add_method('SerializeToString', + 'std::string', + [param('ns3::Ptr< ns3::AttributeChecker const >', 'checker')], + is_const=True, is_virtual=True) ## nstime.h: bool ns3::TimeValue::DeserializeFromString(std::string value, ns3::Ptr checker) [member function] - cls.add_method('DeserializeFromString', 'bool', [param('std::string', 'value'), param('ns3::Ptr< ns3::AttributeChecker const >', 'checker')], is_virtual=True) + cls.add_method('DeserializeFromString', + 'bool', + [param('std::string', 'value'), param('ns3::Ptr< ns3::AttributeChecker const >', 'checker')], + is_virtual=True) return def register_Ns3HeapScheduler_methods(root_module, cls): ## heap-scheduler.h: ns3::HeapScheduler::HeapScheduler() [constructor] - cls.add_constructor([], visibility='public') + cls.add_constructor([]) ## heap-scheduler.h: void ns3::HeapScheduler::Insert(ns3::EventId const & id) [member function] - cls.add_method('Insert', 'void', [param('ns3::EventId&', 'id', is_const=True)], is_virtual=True) + cls.add_method('Insert', + 'void', + [param('ns3::EventId&', 'id', is_const=True)], + is_virtual=True) ## heap-scheduler.h: bool ns3::HeapScheduler::IsEmpty() const [member function] - cls.add_method('IsEmpty', 'bool', [], is_const=True, is_virtual=True) + cls.add_method('IsEmpty', + 'bool', + [], + is_const=True, is_virtual=True) ## heap-scheduler.h: ns3::EventId ns3::HeapScheduler::PeekNext() const [member function] - cls.add_method('PeekNext', 'ns3::EventId', [], is_const=True, is_virtual=True) + cls.add_method('PeekNext', + 'ns3::EventId', + [], + is_const=True, is_virtual=True) ## heap-scheduler.h: ns3::EventId ns3::HeapScheduler::RemoveNext() [member function] - cls.add_method('RemoveNext', 'ns3::EventId', [], is_virtual=True) + cls.add_method('RemoveNext', + 'ns3::EventId', + [], + is_virtual=True) ## heap-scheduler.h: bool ns3::HeapScheduler::Remove(ns3::EventId const & ev) [member function] - cls.add_method('Remove', 'bool', [param('ns3::EventId&', 'ev', is_const=True)], is_virtual=True) + cls.add_method('Remove', + 'bool', + [param('ns3::EventId&', 'ev', is_const=True)], + is_virtual=True) return def register_Ns3ListScheduler_methods(root_module, cls): ## list-scheduler.h: ns3::ListScheduler::ListScheduler() [constructor] - cls.add_constructor([], visibility='public') + cls.add_constructor([]) ## list-scheduler.h: void ns3::ListScheduler::Insert(ns3::EventId const & id) [member function] - cls.add_method('Insert', 'void', [param('ns3::EventId&', 'id', is_const=True)], is_virtual=True) + cls.add_method('Insert', + 'void', + [param('ns3::EventId&', 'id', is_const=True)], + is_virtual=True) ## list-scheduler.h: bool ns3::ListScheduler::IsEmpty() const [member function] - cls.add_method('IsEmpty', 'bool', [], is_const=True, is_virtual=True) + cls.add_method('IsEmpty', + 'bool', + [], + is_const=True, is_virtual=True) ## list-scheduler.h: ns3::EventId ns3::ListScheduler::PeekNext() const [member function] - cls.add_method('PeekNext', 'ns3::EventId', [], is_const=True, is_virtual=True) + cls.add_method('PeekNext', + 'ns3::EventId', + [], + is_const=True, is_virtual=True) ## list-scheduler.h: ns3::EventId ns3::ListScheduler::RemoveNext() [member function] - cls.add_method('RemoveNext', 'ns3::EventId', [], is_virtual=True) + cls.add_method('RemoveNext', + 'ns3::EventId', + [], + is_virtual=True) ## list-scheduler.h: bool ns3::ListScheduler::Remove(ns3::EventId const & ev) [member function] - cls.add_method('Remove', 'bool', [param('ns3::EventId&', 'ev', is_const=True)], is_virtual=True) + cls.add_method('Remove', + 'bool', + [param('ns3::EventId&', 'ev', is_const=True)], + is_virtual=True) return def register_Ns3MapScheduler_methods(root_module, cls): ## map-scheduler.h: ns3::MapScheduler::MapScheduler() [constructor] - cls.add_constructor([], visibility='public') + cls.add_constructor([]) ## map-scheduler.h: void ns3::MapScheduler::Insert(ns3::EventId const & id) [member function] - cls.add_method('Insert', 'void', [param('ns3::EventId&', 'id', is_const=True)], is_virtual=True) + cls.add_method('Insert', + 'void', + [param('ns3::EventId&', 'id', is_const=True)], + is_virtual=True) ## map-scheduler.h: bool ns3::MapScheduler::IsEmpty() const [member function] - cls.add_method('IsEmpty', 'bool', [], is_const=True, is_virtual=True) + cls.add_method('IsEmpty', + 'bool', + [], + is_const=True, is_virtual=True) ## map-scheduler.h: ns3::EventId ns3::MapScheduler::PeekNext() const [member function] - cls.add_method('PeekNext', 'ns3::EventId', [], is_const=True, is_virtual=True) + cls.add_method('PeekNext', + 'ns3::EventId', + [], + is_const=True, is_virtual=True) ## map-scheduler.h: ns3::EventId ns3::MapScheduler::RemoveNext() [member function] - cls.add_method('RemoveNext', 'ns3::EventId', [], is_virtual=True) + cls.add_method('RemoveNext', + 'ns3::EventId', + [], + is_virtual=True) ## map-scheduler.h: bool ns3::MapScheduler::Remove(ns3::EventId const & ev) [member function] - cls.add_method('Remove', 'bool', [param('ns3::EventId&', 'ev', is_const=True)], is_virtual=True) + cls.add_method('Remove', + 'bool', + [param('ns3::EventId&', 'ev', is_const=True)], + is_virtual=True) return def register_functions(root_module): module = root_module ## high-precision.h: extern ns3::HighPrecision ns3::Max(ns3::HighPrecision const & a, ns3::HighPrecision const & b) [free function] - module.add_function('Max', 'ns3::HighPrecision', [param('ns3::HighPrecision&', 'a', is_const=True), param('ns3::HighPrecision&', 'b', is_const=True)]) + module.add_function('Max', + 'ns3::HighPrecision', + [param('ns3::HighPrecision&', 'a', is_const=True), param('ns3::HighPrecision&', 'b', is_const=True)]) ## nstime.h: extern ns3::Time ns3::FemtoSeconds(uint64_t fs) [free function] - module.add_function('FemtoSeconds', 'ns3::Time', [param('uint64_t', 'fs')]) + module.add_function('FemtoSeconds', + 'ns3::Time', + [param('uint64_t', 'fs')]) ## nstime.h: extern ns3::Time ns3::MicroSeconds(uint64_t us) [free function] - module.add_function('MicroSeconds', 'ns3::Time', [param('uint64_t', 'us')]) + module.add_function('MicroSeconds', + 'ns3::Time', + [param('uint64_t', 'us')]) ## simulator.h: extern ns3::Time ns3::Now() [free function] - module.add_function('Now', 'ns3::Time', []) + module.add_function('Now', + 'ns3::Time', + []) ## nstime.h: extern ns3::Time ns3::MilliSeconds(uint64_t ms) [free function] - module.add_function('MilliSeconds', 'ns3::Time', [param('uint64_t', 'ms')]) + module.add_function('MilliSeconds', + 'ns3::Time', + [param('uint64_t', 'ms')]) ## nstime.h: extern ns3::Time ns3::NanoSeconds(uint64_t ns) [free function] - module.add_function('NanoSeconds', 'ns3::Time', [param('uint64_t', 'ns')]) + module.add_function('NanoSeconds', + 'ns3::Time', + [param('uint64_t', 'ns')]) ## high-precision.h: extern ns3::HighPrecision ns3::Abs(ns3::HighPrecision const & value) [free function] - module.add_function('Abs', 'ns3::HighPrecision', [param('ns3::HighPrecision&', 'value', is_const=True)]) + module.add_function('Abs', + 'ns3::HighPrecision', + [param('ns3::HighPrecision&', 'value', is_const=True)]) ## nstime.h: extern ns3::Ptr ns3::MakeTimeChecker() [free function] - module.add_function('MakeTimeChecker', 'ns3::Ptr< ns3::AttributeChecker const >', []) + module.add_function('MakeTimeChecker', + 'ns3::Ptr< ns3::AttributeChecker const >', + []) ## nstime.h: extern ns3::Time ns3::Seconds(double seconds) [free function] - module.add_function('Seconds', 'ns3::Time', [param('double', 'seconds')]) + module.add_function('Seconds', + 'ns3::Time', + [param('double', 'seconds')]) ## nstime.h: extern ns3::Time ns3::PicoSeconds(uint64_t ps) [free function] - module.add_function('PicoSeconds', 'ns3::Time', [param('uint64_t', 'ps')]) + module.add_function('PicoSeconds', + 'ns3::Time', + [param('uint64_t', 'ps')]) ## high-precision.h: extern ns3::HighPrecision ns3::Min(ns3::HighPrecision const & a, ns3::HighPrecision const & b) [free function] - module.add_function('Min', 'ns3::HighPrecision', [param('ns3::HighPrecision&', 'a', is_const=True), param('ns3::HighPrecision&', 'b', is_const=True)]) + module.add_function('Min', + 'ns3::HighPrecision', + [param('ns3::HighPrecision&', 'a', is_const=True), param('ns3::HighPrecision&', 'b', is_const=True)]) ## nstime.h: extern ns3::Time ns3::TimeStep(uint64_t ts) [free function] - module.add_function('TimeStep', 'ns3::Time', [param('uint64_t', 'ts')]) + module.add_function('TimeStep', + 'ns3::Time', + [param('uint64_t', 'ts')]) register_functions_ns3_internal(module.get_submodule('internal'), root_module) register_functions_ns3_TimeStepPrecision(module.get_submodule('TimeStepPrecision'), root_module) register_functions_ns3_Config(module.get_submodule('Config'), root_module) @@ -443,9 +748,13 @@ def register_functions_ns3_internal(module, root_module): def register_functions_ns3_TimeStepPrecision(module, root_module): ## nstime.h: extern void ns3::TimeStepPrecision::Set(ns3::TimeStepPrecision::precision_t precision) [free function] - module.add_function('Set', 'void', [param('ns3::TimeStepPrecision::precision_t', 'precision')]) + module.add_function('Set', + 'void', + [param('ns3::TimeStepPrecision::precision_t', 'precision')]) ## nstime.h: extern ns3::TimeStepPrecision::precision_t ns3::TimeStepPrecision::Get() [free function] - module.add_function('Get', 'ns3::TimeStepPrecision::precision_t', []) + module.add_function('Get', + 'ns3::TimeStepPrecision::precision_t', + []) return def register_functions_ns3_Config(module, root_module): diff --git a/bindings/python/ns3_module_udp_echo.py b/bindings/python/ns3_module_udp_echo.py index 91c273684..e5c31a797 100644 --- a/bindings/python/ns3_module_udp_echo.py +++ b/bindings/python/ns3_module_udp_echo.py @@ -1,4 +1,4 @@ -from pybindgen import Module, FileCodeSink, write_preamble, param, retval +from pybindgen import Module, FileCodeSink, param, retval, cppclass def register_types(module): root_module = module.get_root() @@ -55,30 +55,56 @@ def register_methods(root_module): def register_Ns3UdpEchoClient_methods(root_module, cls): ## udp-echo-client.h: static ns3::TypeId ns3::UdpEchoClient::GetTypeId() [member function] - cls.add_method('GetTypeId', 'ns3::TypeId', [], is_static=True) + cls.add_method('GetTypeId', + 'ns3::TypeId', + [], + is_static=True) ## udp-echo-client.h: ns3::UdpEchoClient::UdpEchoClient() [constructor] - cls.add_constructor([], visibility='public') + cls.add_constructor([]) ## udp-echo-client.h: void ns3::UdpEchoClient::SetRemote(ns3::Ipv4Address ip, uint16_t port) [member function] - cls.add_method('SetRemote', 'void', [param('ns3::Ipv4Address', 'ip'), param('uint16_t', 'port')]) + cls.add_method('SetRemote', + 'void', + [param('ns3::Ipv4Address', 'ip'), param('uint16_t', 'port')]) ## udp-echo-client.h: void ns3::UdpEchoClient::DoDispose() [member function] - cls.add_method('DoDispose', 'void', [], visibility='protected', is_virtual=True) + cls.add_method('DoDispose', + 'void', + [], + visibility='protected', is_virtual=True) ## udp-echo-client.h: void ns3::UdpEchoClient::StartApplication() [member function] - cls.add_method('StartApplication', 'void', [], visibility='private', is_virtual=True) + cls.add_method('StartApplication', + 'void', + [], + visibility='private', is_virtual=True) ## udp-echo-client.h: void ns3::UdpEchoClient::StopApplication() [member function] - cls.add_method('StopApplication', 'void', [], visibility='private', is_virtual=True) + cls.add_method('StopApplication', + 'void', + [], + visibility='private', is_virtual=True) return def register_Ns3UdpEchoServer_methods(root_module, cls): ## udp-echo-server.h: static ns3::TypeId ns3::UdpEchoServer::GetTypeId() [member function] - cls.add_method('GetTypeId', 'ns3::TypeId', [], is_static=True) + cls.add_method('GetTypeId', + 'ns3::TypeId', + [], + is_static=True) ## udp-echo-server.h: ns3::UdpEchoServer::UdpEchoServer() [constructor] - cls.add_constructor([], visibility='public') + cls.add_constructor([]) ## udp-echo-server.h: void ns3::UdpEchoServer::DoDispose() [member function] - cls.add_method('DoDispose', 'void', [], visibility='protected', is_virtual=True) + cls.add_method('DoDispose', + 'void', + [], + visibility='protected', is_virtual=True) ## udp-echo-server.h: void ns3::UdpEchoServer::StartApplication() [member function] - cls.add_method('StartApplication', 'void', [], visibility='private', is_virtual=True) + cls.add_method('StartApplication', + 'void', + [], + visibility='private', is_virtual=True) ## udp-echo-server.h: void ns3::UdpEchoServer::StopApplication() [member function] - cls.add_method('StopApplication', 'void', [], visibility='private', is_virtual=True) + cls.add_method('StopApplication', + 'void', + [], + visibility='private', is_virtual=True) return def register_functions(root_module): diff --git a/bindings/python/ns3_module_wifi.py b/bindings/python/ns3_module_wifi.py index e33d20093..14c660114 100644 --- a/bindings/python/ns3_module_wifi.py +++ b/bindings/python/ns3_module_wifi.py @@ -1,4 +1,4 @@ -from pybindgen import Module, FileCodeSink, write_preamble, param, retval +from pybindgen import Module, FileCodeSink, param, retval, cppclass def register_types(module): root_module = module.get_root() @@ -183,102 +183,222 @@ def register_methods(root_module): def register_Ns3WifiRemoteStation_methods(root_module, cls): ## wifi-remote-station-manager.h: static ns3::TypeId ns3::WifiRemoteStation::GetTypeId() [member function] - cls.add_method('GetTypeId', 'ns3::TypeId', [], is_static=True) + cls.add_method('GetTypeId', + 'ns3::TypeId', + [], + is_static=True) ## wifi-remote-station-manager.h: ns3::WifiRemoteStation::WifiRemoteStation() [constructor] - cls.add_constructor([], visibility='public') + cls.add_constructor([]) ## wifi-remote-station-manager.h: void ns3::WifiRemoteStation::Reset() [member function] - cls.add_method('Reset', 'void', []) + cls.add_method('Reset', + 'void', + []) ## wifi-remote-station-manager.h: void ns3::WifiRemoteStation::AddSupportedMode(ns3::WifiMode mode) [member function] - cls.add_method('AddSupportedMode', 'void', [param('ns3::WifiMode', 'mode')]) + cls.add_method('AddSupportedMode', + 'void', + [param('ns3::WifiMode', 'mode')]) ## wifi-remote-station-manager.h: bool ns3::WifiRemoteStation::IsBrandNew() const [member function] - cls.add_method('IsBrandNew', 'bool', [], is_const=True) + cls.add_method('IsBrandNew', + 'bool', + [], + is_const=True) ## wifi-remote-station-manager.h: bool ns3::WifiRemoteStation::IsAssociated() const [member function] - cls.add_method('IsAssociated', 'bool', [], is_const=True) + cls.add_method('IsAssociated', + 'bool', + [], + is_const=True) ## wifi-remote-station-manager.h: bool ns3::WifiRemoteStation::IsWaitAssocTxOk() const [member function] - cls.add_method('IsWaitAssocTxOk', 'bool', [], is_const=True) + cls.add_method('IsWaitAssocTxOk', + 'bool', + [], + is_const=True) ## wifi-remote-station-manager.h: void ns3::WifiRemoteStation::RecordWaitAssocTxOk() [member function] - cls.add_method('RecordWaitAssocTxOk', 'void', []) + cls.add_method('RecordWaitAssocTxOk', + 'void', + []) ## wifi-remote-station-manager.h: void ns3::WifiRemoteStation::RecordGotAssocTxOk() [member function] - cls.add_method('RecordGotAssocTxOk', 'void', []) + cls.add_method('RecordGotAssocTxOk', + 'void', + []) ## wifi-remote-station-manager.h: void ns3::WifiRemoteStation::RecordGotAssocTxFailed() [member function] - cls.add_method('RecordGotAssocTxFailed', 'void', []) + cls.add_method('RecordGotAssocTxFailed', + 'void', + []) ## wifi-remote-station-manager.h: void ns3::WifiRemoteStation::RecordDisassociated() [member function] - cls.add_method('RecordDisassociated', 'void', []) + cls.add_method('RecordDisassociated', + 'void', + []) ## wifi-remote-station-manager.h: void ns3::WifiRemoteStation::PrepareForQueue(ns3::Ptr packet, uint32_t fullPacketSize) [member function] - cls.add_method('PrepareForQueue', 'void', [param('ns3::Ptr< const ns3::Packet >', 'packet'), param('uint32_t', 'fullPacketSize')]) + cls.add_method('PrepareForQueue', + 'void', + [param('ns3::Ptr< const ns3::Packet >', 'packet'), param('uint32_t', 'fullPacketSize')]) ## wifi-remote-station-manager.h: ns3::WifiMode ns3::WifiRemoteStation::GetDataMode(ns3::Ptr packet, uint32_t fullPacketSize) [member function] - cls.add_method('GetDataMode', 'ns3::WifiMode', [param('ns3::Ptr< const ns3::Packet >', 'packet'), param('uint32_t', 'fullPacketSize')]) + cls.add_method('GetDataMode', + 'ns3::WifiMode', + [param('ns3::Ptr< const ns3::Packet >', 'packet'), param('uint32_t', 'fullPacketSize')]) ## wifi-remote-station-manager.h: ns3::WifiMode ns3::WifiRemoteStation::GetRtsMode(ns3::Ptr packet) [member function] - cls.add_method('GetRtsMode', 'ns3::WifiMode', [param('ns3::Ptr< const ns3::Packet >', 'packet')]) + cls.add_method('GetRtsMode', + 'ns3::WifiMode', + [param('ns3::Ptr< const ns3::Packet >', 'packet')]) ## wifi-remote-station-manager.h: void ns3::WifiRemoteStation::ReportRtsFailed() [member function] - cls.add_method('ReportRtsFailed', 'void', []) + cls.add_method('ReportRtsFailed', + 'void', + []) ## wifi-remote-station-manager.h: void ns3::WifiRemoteStation::ReportDataFailed() [member function] - cls.add_method('ReportDataFailed', 'void', []) + cls.add_method('ReportDataFailed', + 'void', + []) ## wifi-remote-station-manager.h: void ns3::WifiRemoteStation::ReportRtsOk(double ctsSnr, ns3::WifiMode ctsMode, double rtsSnr) [member function] - cls.add_method('ReportRtsOk', 'void', [param('double', 'ctsSnr'), param('ns3::WifiMode', 'ctsMode'), param('double', 'rtsSnr')]) + cls.add_method('ReportRtsOk', + 'void', + [param('double', 'ctsSnr'), param('ns3::WifiMode', 'ctsMode'), param('double', 'rtsSnr')]) ## wifi-remote-station-manager.h: void ns3::WifiRemoteStation::ReportDataOk(double ackSnr, ns3::WifiMode ackMode, double dataSnr) [member function] - cls.add_method('ReportDataOk', 'void', [param('double', 'ackSnr'), param('ns3::WifiMode', 'ackMode'), param('double', 'dataSnr')]) + cls.add_method('ReportDataOk', + 'void', + [param('double', 'ackSnr'), param('ns3::WifiMode', 'ackMode'), param('double', 'dataSnr')]) ## wifi-remote-station-manager.h: void ns3::WifiRemoteStation::ReportFinalRtsFailed() [member function] - cls.add_method('ReportFinalRtsFailed', 'void', []) + cls.add_method('ReportFinalRtsFailed', + 'void', + []) ## wifi-remote-station-manager.h: void ns3::WifiRemoteStation::ReportFinalDataFailed() [member function] - cls.add_method('ReportFinalDataFailed', 'void', []) + cls.add_method('ReportFinalDataFailed', + 'void', + []) ## wifi-remote-station-manager.h: void ns3::WifiRemoteStation::ReportRxOk(double rxSnr, ns3::WifiMode txMode) [member function] - cls.add_method('ReportRxOk', 'void', [param('double', 'rxSnr'), param('ns3::WifiMode', 'txMode')]) + cls.add_method('ReportRxOk', + 'void', + [param('double', 'rxSnr'), param('ns3::WifiMode', 'txMode')]) ## wifi-remote-station-manager.h: bool ns3::WifiRemoteStation::NeedRts(ns3::Ptr packet) [member function] - cls.add_method('NeedRts', 'bool', [param('ns3::Ptr< const ns3::Packet >', 'packet')], is_virtual=True) + cls.add_method('NeedRts', + 'bool', + [param('ns3::Ptr< const ns3::Packet >', 'packet')], + is_virtual=True) ## wifi-remote-station-manager.h: bool ns3::WifiRemoteStation::NeedRtsRetransmission(ns3::Ptr packet) [member function] - cls.add_method('NeedRtsRetransmission', 'bool', [param('ns3::Ptr< const ns3::Packet >', 'packet')], is_virtual=True) + cls.add_method('NeedRtsRetransmission', + 'bool', + [param('ns3::Ptr< const ns3::Packet >', 'packet')], + is_virtual=True) ## wifi-remote-station-manager.h: bool ns3::WifiRemoteStation::NeedDataRetransmission(ns3::Ptr packet) [member function] - cls.add_method('NeedDataRetransmission', 'bool', [param('ns3::Ptr< const ns3::Packet >', 'packet')], is_virtual=True) + cls.add_method('NeedDataRetransmission', + 'bool', + [param('ns3::Ptr< const ns3::Packet >', 'packet')], + is_virtual=True) ## wifi-remote-station-manager.h: bool ns3::WifiRemoteStation::NeedFragmentation(ns3::Ptr packet) [member function] - cls.add_method('NeedFragmentation', 'bool', [param('ns3::Ptr< const ns3::Packet >', 'packet')], is_virtual=True) + cls.add_method('NeedFragmentation', + 'bool', + [param('ns3::Ptr< const ns3::Packet >', 'packet')], + is_virtual=True) ## wifi-remote-station-manager.h: uint32_t ns3::WifiRemoteStation::GetNFragments(ns3::Ptr packet) [member function] - cls.add_method('GetNFragments', 'uint32_t', [param('ns3::Ptr< const ns3::Packet >', 'packet')], is_virtual=True) + cls.add_method('GetNFragments', + 'uint32_t', + [param('ns3::Ptr< const ns3::Packet >', 'packet')], + is_virtual=True) ## wifi-remote-station-manager.h: uint32_t ns3::WifiRemoteStation::GetFragmentSize(ns3::Ptr packet, uint32_t fragmentNumber) [member function] - cls.add_method('GetFragmentSize', 'uint32_t', [param('ns3::Ptr< const ns3::Packet >', 'packet'), param('uint32_t', 'fragmentNumber')], is_virtual=True) + cls.add_method('GetFragmentSize', + 'uint32_t', + [param('ns3::Ptr< const ns3::Packet >', 'packet'), param('uint32_t', 'fragmentNumber')], + is_virtual=True) ## wifi-remote-station-manager.h: bool ns3::WifiRemoteStation::IsLastFragment(ns3::Ptr packet, uint32_t fragmentNumber) [member function] - cls.add_method('IsLastFragment', 'bool', [param('ns3::Ptr< const ns3::Packet >', 'packet'), param('uint32_t', 'fragmentNumber')], is_virtual=True) + cls.add_method('IsLastFragment', + 'bool', + [param('ns3::Ptr< const ns3::Packet >', 'packet'), param('uint32_t', 'fragmentNumber')], + is_virtual=True) ## wifi-remote-station-manager.h: ns3::WifiMode ns3::WifiRemoteStation::GetCtsMode(ns3::WifiMode rtsMode) [member function] - cls.add_method('GetCtsMode', 'ns3::WifiMode', [param('ns3::WifiMode', 'rtsMode')]) + cls.add_method('GetCtsMode', + 'ns3::WifiMode', + [param('ns3::WifiMode', 'rtsMode')]) ## wifi-remote-station-manager.h: ns3::WifiMode ns3::WifiRemoteStation::GetAckMode(ns3::WifiMode dataMode) [member function] - cls.add_method('GetAckMode', 'ns3::WifiMode', [param('ns3::WifiMode', 'dataMode')]) + cls.add_method('GetAckMode', + 'ns3::WifiMode', + [param('ns3::WifiMode', 'dataMode')]) ## wifi-remote-station-manager.h: void ns3::WifiRemoteStation::DoReportRtsFailed() [member function] - cls.add_method('DoReportRtsFailed', 'void', [], is_pure_virtual=True, visibility='protected', is_virtual=True) + cls.add_method('DoReportRtsFailed', + 'void', + [], + is_pure_virtual=True, visibility='protected', is_virtual=True) ## wifi-remote-station-manager.h: void ns3::WifiRemoteStation::DoReportDataFailed() [member function] - cls.add_method('DoReportDataFailed', 'void', [], is_pure_virtual=True, visibility='protected', is_virtual=True) + cls.add_method('DoReportDataFailed', + 'void', + [], + is_pure_virtual=True, visibility='protected', is_virtual=True) ## wifi-remote-station-manager.h: void ns3::WifiRemoteStation::DoReportRtsOk(double ctsSnr, ns3::WifiMode ctsMode, double rtsSnr) [member function] - cls.add_method('DoReportRtsOk', 'void', [param('double', 'ctsSnr'), param('ns3::WifiMode', 'ctsMode'), param('double', 'rtsSnr')], is_pure_virtual=True, visibility='protected', is_virtual=True) + cls.add_method('DoReportRtsOk', + 'void', + [param('double', 'ctsSnr'), param('ns3::WifiMode', 'ctsMode'), param('double', 'rtsSnr')], + is_pure_virtual=True, visibility='protected', is_virtual=True) ## wifi-remote-station-manager.h: void ns3::WifiRemoteStation::DoReportDataOk(double ackSnr, ns3::WifiMode ackMode, double dataSnr) [member function] - cls.add_method('DoReportDataOk', 'void', [param('double', 'ackSnr'), param('ns3::WifiMode', 'ackMode'), param('double', 'dataSnr')], is_pure_virtual=True, visibility='protected', is_virtual=True) + cls.add_method('DoReportDataOk', + 'void', + [param('double', 'ackSnr'), param('ns3::WifiMode', 'ackMode'), param('double', 'dataSnr')], + is_pure_virtual=True, visibility='protected', is_virtual=True) ## wifi-remote-station-manager.h: void ns3::WifiRemoteStation::DoReportFinalRtsFailed() [member function] - cls.add_method('DoReportFinalRtsFailed', 'void', [], is_pure_virtual=True, visibility='protected', is_virtual=True) + cls.add_method('DoReportFinalRtsFailed', + 'void', + [], + is_pure_virtual=True, visibility='protected', is_virtual=True) ## wifi-remote-station-manager.h: void ns3::WifiRemoteStation::DoReportFinalDataFailed() [member function] - cls.add_method('DoReportFinalDataFailed', 'void', [], is_pure_virtual=True, visibility='protected', is_virtual=True) + cls.add_method('DoReportFinalDataFailed', + 'void', + [], + is_pure_virtual=True, visibility='protected', is_virtual=True) ## wifi-remote-station-manager.h: void ns3::WifiRemoteStation::DoReportRxOk(double rxSnr, ns3::WifiMode txMode) [member function] - cls.add_method('DoReportRxOk', 'void', [param('double', 'rxSnr'), param('ns3::WifiMode', 'txMode')], is_pure_virtual=True, visibility='protected', is_virtual=True) + cls.add_method('DoReportRxOk', + 'void', + [param('double', 'rxSnr'), param('ns3::WifiMode', 'txMode')], + is_pure_virtual=True, visibility='protected', is_virtual=True) ## wifi-remote-station-manager.h: uint32_t ns3::WifiRemoteStation::GetNSupportedModes() const [member function] - cls.add_method('GetNSupportedModes', 'uint32_t', [], is_const=True, visibility='protected') + cls.add_method('GetNSupportedModes', + 'uint32_t', + [], + is_const=True, visibility='protected') ## wifi-remote-station-manager.h: ns3::WifiMode ns3::WifiRemoteStation::GetSupportedMode(uint32_t i) const [member function] - cls.add_method('GetSupportedMode', 'ns3::WifiMode', [param('uint32_t', 'i')], is_const=True, visibility='protected') + cls.add_method('GetSupportedMode', + 'ns3::WifiMode', + [param('uint32_t', 'i')], + is_const=True, visibility='protected') ## wifi-remote-station-manager.h: ns3::Ptr ns3::WifiRemoteStation::GetManager() const [member function] - cls.add_method('GetManager', 'ns3::Ptr< ns3::WifiRemoteStationManager >', [], is_pure_virtual=True, is_const=True, visibility='private', is_virtual=True) + cls.add_method('GetManager', + 'ns3::Ptr< ns3::WifiRemoteStationManager >', + [], + is_pure_virtual=True, is_const=True, visibility='private', is_virtual=True) ## wifi-remote-station-manager.h: ns3::WifiMode ns3::WifiRemoteStation::DoGetDataMode(uint32_t size) [member function] - cls.add_method('DoGetDataMode', 'ns3::WifiMode', [param('uint32_t', 'size')], is_pure_virtual=True, visibility='private', is_virtual=True) + cls.add_method('DoGetDataMode', + 'ns3::WifiMode', + [param('uint32_t', 'size')], + is_pure_virtual=True, visibility='private', is_virtual=True) ## wifi-remote-station-manager.h: ns3::WifiMode ns3::WifiRemoteStation::DoGetRtsMode() [member function] - cls.add_method('DoGetRtsMode', 'ns3::WifiMode', [], is_pure_virtual=True, visibility='private', is_virtual=True) + cls.add_method('DoGetRtsMode', + 'ns3::WifiMode', + [], + is_pure_virtual=True, visibility='private', is_virtual=True) return def register_Ns3WifiPhyListener_methods(root_module, cls): ## wifi-phy.h: void ns3::WifiPhyListener::NotifyRxStart(ns3::Time duration) [member function] - cls.add_method('NotifyRxStart', 'void', [param('ns3::Time', 'duration')], is_pure_virtual=True, is_virtual=True) + cls.add_method('NotifyRxStart', + 'void', + [param('ns3::Time', 'duration')], + is_pure_virtual=True, is_virtual=True) ## wifi-phy.h: void ns3::WifiPhyListener::NotifyRxEndOk() [member function] - cls.add_method('NotifyRxEndOk', 'void', [], is_pure_virtual=True, is_virtual=True) + cls.add_method('NotifyRxEndOk', + 'void', + [], + is_pure_virtual=True, is_virtual=True) ## wifi-phy.h: void ns3::WifiPhyListener::NotifyRxEndError() [member function] - cls.add_method('NotifyRxEndError', 'void', [], is_pure_virtual=True, is_virtual=True) + cls.add_method('NotifyRxEndError', + 'void', + [], + is_pure_virtual=True, is_virtual=True) ## wifi-phy.h: void ns3::WifiPhyListener::NotifyTxStart(ns3::Time duration) [member function] - cls.add_method('NotifyTxStart', 'void', [param('ns3::Time', 'duration')], is_pure_virtual=True, is_virtual=True) + cls.add_method('NotifyTxStart', + 'void', + [param('ns3::Time', 'duration')], + is_pure_virtual=True, is_virtual=True) ## wifi-phy.h: void ns3::WifiPhyListener::NotifyCcaBusyStart(ns3::Time duration) [member function] - cls.add_method('NotifyCcaBusyStart', 'void', [param('ns3::Time', 'duration')], is_pure_virtual=True, is_virtual=True) + cls.add_method('NotifyCcaBusyStart', + 'void', + [param('ns3::Time', 'duration')], + is_pure_virtual=True, is_virtual=True) cls.add_constructor([]) return @@ -296,53 +416,107 @@ def register_Ns3ThresholdsItem_methods(root_module, cls): def register_Ns3SupportedRates_methods(root_module, cls): ## supported-rates.h: ns3::SupportedRates::SupportedRates(ns3::SupportedRates const & arg0) [copy constructor] - cls.add_constructor([param('ns3::SupportedRates&', 'arg0', is_const=True)], visibility='public') + cls.add_constructor([param('ns3::SupportedRates&', 'arg0', is_const=True)]) ## supported-rates.h: ns3::SupportedRates::SupportedRates() [constructor] - cls.add_constructor([], visibility='public') + cls.add_constructor([]) ## supported-rates.h: void ns3::SupportedRates::AddSupportedRate(uint32_t bs) [member function] - cls.add_method('AddSupportedRate', 'void', [param('uint32_t', 'bs')]) + cls.add_method('AddSupportedRate', + 'void', + [param('uint32_t', 'bs')]) ## supported-rates.h: ns3::Buffer::Iterator ns3::SupportedRates::Deserialize(ns3::Buffer::Iterator start) [member function] - cls.add_method('Deserialize', 'ns3::Buffer::Iterator', [param('ns3::Buffer::Iterator', 'start')]) + cls.add_method('Deserialize', + 'ns3::Buffer::Iterator', + [param('ns3::Buffer::Iterator', 'start')]) ## supported-rates.h: uint8_t ns3::SupportedRates::GetNRates() const [member function] - cls.add_method('GetNRates', 'uint8_t', [], is_const=True) + cls.add_method('GetNRates', + 'uint8_t', + [], + is_const=True) ## supported-rates.h: uint32_t ns3::SupportedRates::GetRate(uint8_t i) const [member function] - cls.add_method('GetRate', 'uint32_t', [param('uint8_t', 'i')], is_const=True) + cls.add_method('GetRate', + 'uint32_t', + [param('uint8_t', 'i')], + is_const=True) ## supported-rates.h: uint32_t ns3::SupportedRates::GetSerializedSize() const [member function] - cls.add_method('GetSerializedSize', 'uint32_t', [], is_const=True) + cls.add_method('GetSerializedSize', + 'uint32_t', + [], + is_const=True) ## supported-rates.h: bool ns3::SupportedRates::IsBasicRate(uint32_t bs) const [member function] - cls.add_method('IsBasicRate', 'bool', [param('uint32_t', 'bs')], is_const=True) + cls.add_method('IsBasicRate', + 'bool', + [param('uint32_t', 'bs')], + is_const=True) ## supported-rates.h: bool ns3::SupportedRates::IsSupportedRate(uint32_t bs) const [member function] - cls.add_method('IsSupportedRate', 'bool', [param('uint32_t', 'bs')], is_const=True) + cls.add_method('IsSupportedRate', + 'bool', + [param('uint32_t', 'bs')], + is_const=True) ## supported-rates.h: ns3::Buffer::Iterator ns3::SupportedRates::Serialize(ns3::Buffer::Iterator start) const [member function] - cls.add_method('Serialize', 'ns3::Buffer::Iterator', [param('ns3::Buffer::Iterator', 'start')], is_const=True) + cls.add_method('Serialize', + 'ns3::Buffer::Iterator', + [param('ns3::Buffer::Iterator', 'start')], + is_const=True) ## supported-rates.h: void ns3::SupportedRates::SetBasicRate(uint32_t bs) [member function] - cls.add_method('SetBasicRate', 'void', [param('uint32_t', 'bs')]) + cls.add_method('SetBasicRate', + 'void', + [param('uint32_t', 'bs')]) cls.add_output_stream_operator() return def register_Ns3IdealWifiRemoteStation_methods(root_module, cls): ## ideal-wifi-manager.h: ns3::IdealWifiRemoteStation::IdealWifiRemoteStation(ns3::Ptr stations) [constructor] - cls.add_constructor([param('ns3::Ptr< ns3::IdealWifiManager >', 'stations')], visibility='public') + cls.add_constructor([param('ns3::Ptr< ns3::IdealWifiManager >', 'stations')]) ## ideal-wifi-manager.h: void ns3::IdealWifiRemoteStation::DoReportRxOk(double rxSnr, ns3::WifiMode txMode) [member function] - cls.add_method('DoReportRxOk', 'void', [param('double', 'rxSnr'), param('ns3::WifiMode', 'txMode')], visibility='protected', is_virtual=True) + cls.add_method('DoReportRxOk', + 'void', + [param('double', 'rxSnr'), param('ns3::WifiMode', 'txMode')], + visibility='protected', is_virtual=True) ## ideal-wifi-manager.h: void ns3::IdealWifiRemoteStation::DoReportRtsFailed() [member function] - cls.add_method('DoReportRtsFailed', 'void', [], visibility='protected', is_virtual=True) + cls.add_method('DoReportRtsFailed', + 'void', + [], + visibility='protected', is_virtual=True) ## ideal-wifi-manager.h: void ns3::IdealWifiRemoteStation::DoReportDataFailed() [member function] - cls.add_method('DoReportDataFailed', 'void', [], visibility='protected', is_virtual=True) + cls.add_method('DoReportDataFailed', + 'void', + [], + visibility='protected', is_virtual=True) ## ideal-wifi-manager.h: void ns3::IdealWifiRemoteStation::DoReportRtsOk(double ctsSnr, ns3::WifiMode ctsMode, double rtsSnr) [member function] - cls.add_method('DoReportRtsOk', 'void', [param('double', 'ctsSnr'), param('ns3::WifiMode', 'ctsMode'), param('double', 'rtsSnr')], visibility='protected', is_virtual=True) + cls.add_method('DoReportRtsOk', + 'void', + [param('double', 'ctsSnr'), param('ns3::WifiMode', 'ctsMode'), param('double', 'rtsSnr')], + visibility='protected', is_virtual=True) ## ideal-wifi-manager.h: void ns3::IdealWifiRemoteStation::DoReportDataOk(double ackSnr, ns3::WifiMode ackMode, double dataSnr) [member function] - cls.add_method('DoReportDataOk', 'void', [param('double', 'ackSnr'), param('ns3::WifiMode', 'ackMode'), param('double', 'dataSnr')], visibility='protected', is_virtual=True) + cls.add_method('DoReportDataOk', + 'void', + [param('double', 'ackSnr'), param('ns3::WifiMode', 'ackMode'), param('double', 'dataSnr')], + visibility='protected', is_virtual=True) ## ideal-wifi-manager.h: void ns3::IdealWifiRemoteStation::DoReportFinalRtsFailed() [member function] - cls.add_method('DoReportFinalRtsFailed', 'void', [], visibility='protected', is_virtual=True) + cls.add_method('DoReportFinalRtsFailed', + 'void', + [], + visibility='protected', is_virtual=True) ## ideal-wifi-manager.h: void ns3::IdealWifiRemoteStation::DoReportFinalDataFailed() [member function] - cls.add_method('DoReportFinalDataFailed', 'void', [], visibility='protected', is_virtual=True) + cls.add_method('DoReportFinalDataFailed', + 'void', + [], + visibility='protected', is_virtual=True) ## ideal-wifi-manager.h: ns3::Ptr ns3::IdealWifiRemoteStation::GetManager() const [member function] - cls.add_method('GetManager', 'ns3::Ptr< ns3::WifiRemoteStationManager >', [], is_const=True, visibility='private', is_virtual=True) + cls.add_method('GetManager', + 'ns3::Ptr< ns3::WifiRemoteStationManager >', + [], + is_const=True, visibility='private', is_virtual=True) ## ideal-wifi-manager.h: ns3::WifiMode ns3::IdealWifiRemoteStation::DoGetDataMode(uint32_t size) [member function] - cls.add_method('DoGetDataMode', 'ns3::WifiMode', [param('uint32_t', 'size')], visibility='private', is_virtual=True) + cls.add_method('DoGetDataMode', + 'ns3::WifiMode', + [param('uint32_t', 'size')], + visibility='private', is_virtual=True) ## ideal-wifi-manager.h: ns3::WifiMode ns3::IdealWifiRemoteStation::DoGetRtsMode() [member function] - cls.add_method('DoGetRtsMode', 'ns3::WifiMode', [], visibility='private', is_virtual=True) + cls.add_method('DoGetRtsMode', + 'ns3::WifiMode', + [], + visibility='private', is_virtual=True) return def register_Ns3WifiModeChecker_methods(root_module, cls): @@ -351,132 +525,265 @@ def register_Ns3WifiModeChecker_methods(root_module, cls): def register_Ns3WifiModeFactory_methods(root_module, cls): ## wifi-mode.h: static ns3::WifiMode ns3::WifiModeFactory::CreateBpsk(std::string uniqueName, bool isMandatory, uint32_t bandwidth, uint32_t dataRate, uint32_t phyRate) [member function] - cls.add_method('CreateBpsk', 'ns3::WifiMode', [param('std::string', 'uniqueName'), param('bool', 'isMandatory'), param('uint32_t', 'bandwidth'), param('uint32_t', 'dataRate'), param('uint32_t', 'phyRate')], is_static=True) + cls.add_method('CreateBpsk', + 'ns3::WifiMode', + [param('std::string', 'uniqueName'), param('bool', 'isMandatory'), param('uint32_t', 'bandwidth'), param('uint32_t', 'dataRate'), param('uint32_t', 'phyRate')], + is_static=True) ## wifi-mode.h: static ns3::WifiMode ns3::WifiModeFactory::CreateQam(std::string uniqueName, bool isMandatory, uint32_t bandwidth, uint32_t dataRate, uint32_t phyRate, uint8_t constellationSize) [member function] - cls.add_method('CreateQam', 'ns3::WifiMode', [param('std::string', 'uniqueName'), param('bool', 'isMandatory'), param('uint32_t', 'bandwidth'), param('uint32_t', 'dataRate'), param('uint32_t', 'phyRate'), param('uint8_t', 'constellationSize')], is_static=True) + cls.add_method('CreateQam', + 'ns3::WifiMode', + [param('std::string', 'uniqueName'), param('bool', 'isMandatory'), param('uint32_t', 'bandwidth'), param('uint32_t', 'dataRate'), param('uint32_t', 'phyRate'), param('uint8_t', 'constellationSize')], + is_static=True) return def register_Ns3OnoeWifiRemoteStation_methods(root_module, cls): ## onoe-wifi-manager.h: ns3::OnoeWifiRemoteStation::OnoeWifiRemoteStation(ns3::Ptr stations) [constructor] - cls.add_constructor([param('ns3::Ptr< ns3::OnoeWifiManager >', 'stations')], visibility='public') + cls.add_constructor([param('ns3::Ptr< ns3::OnoeWifiManager >', 'stations')]) ## onoe-wifi-manager.h: void ns3::OnoeWifiRemoteStation::DoReportRxOk(double rxSnr, ns3::WifiMode txMode) [member function] - cls.add_method('DoReportRxOk', 'void', [param('double', 'rxSnr'), param('ns3::WifiMode', 'txMode')], visibility='protected', is_virtual=True) + cls.add_method('DoReportRxOk', + 'void', + [param('double', 'rxSnr'), param('ns3::WifiMode', 'txMode')], + visibility='protected', is_virtual=True) ## onoe-wifi-manager.h: void ns3::OnoeWifiRemoteStation::DoReportRtsFailed() [member function] - cls.add_method('DoReportRtsFailed', 'void', [], visibility='protected', is_virtual=True) + cls.add_method('DoReportRtsFailed', + 'void', + [], + visibility='protected', is_virtual=True) ## onoe-wifi-manager.h: void ns3::OnoeWifiRemoteStation::DoReportDataFailed() [member function] - cls.add_method('DoReportDataFailed', 'void', [], visibility='protected', is_virtual=True) + cls.add_method('DoReportDataFailed', + 'void', + [], + visibility='protected', is_virtual=True) ## onoe-wifi-manager.h: void ns3::OnoeWifiRemoteStation::DoReportRtsOk(double ctsSnr, ns3::WifiMode ctsMode, double rtsSnr) [member function] - cls.add_method('DoReportRtsOk', 'void', [param('double', 'ctsSnr'), param('ns3::WifiMode', 'ctsMode'), param('double', 'rtsSnr')], visibility='protected', is_virtual=True) + cls.add_method('DoReportRtsOk', + 'void', + [param('double', 'ctsSnr'), param('ns3::WifiMode', 'ctsMode'), param('double', 'rtsSnr')], + visibility='protected', is_virtual=True) ## onoe-wifi-manager.h: void ns3::OnoeWifiRemoteStation::DoReportDataOk(double ackSnr, ns3::WifiMode ackMode, double dataSnr) [member function] - cls.add_method('DoReportDataOk', 'void', [param('double', 'ackSnr'), param('ns3::WifiMode', 'ackMode'), param('double', 'dataSnr')], visibility='protected', is_virtual=True) + cls.add_method('DoReportDataOk', + 'void', + [param('double', 'ackSnr'), param('ns3::WifiMode', 'ackMode'), param('double', 'dataSnr')], + visibility='protected', is_virtual=True) ## onoe-wifi-manager.h: void ns3::OnoeWifiRemoteStation::DoReportFinalRtsFailed() [member function] - cls.add_method('DoReportFinalRtsFailed', 'void', [], visibility='protected', is_virtual=True) + cls.add_method('DoReportFinalRtsFailed', + 'void', + [], + visibility='protected', is_virtual=True) ## onoe-wifi-manager.h: void ns3::OnoeWifiRemoteStation::DoReportFinalDataFailed() [member function] - cls.add_method('DoReportFinalDataFailed', 'void', [], visibility='protected', is_virtual=True) + cls.add_method('DoReportFinalDataFailed', + 'void', + [], + visibility='protected', is_virtual=True) ## onoe-wifi-manager.h: ns3::Ptr ns3::OnoeWifiRemoteStation::GetManager() const [member function] - cls.add_method('GetManager', 'ns3::Ptr< ns3::WifiRemoteStationManager >', [], is_const=True, visibility='private', is_virtual=True) + cls.add_method('GetManager', + 'ns3::Ptr< ns3::WifiRemoteStationManager >', + [], + is_const=True, visibility='private', is_virtual=True) ## onoe-wifi-manager.h: ns3::WifiMode ns3::OnoeWifiRemoteStation::DoGetDataMode(uint32_t size) [member function] - cls.add_method('DoGetDataMode', 'ns3::WifiMode', [param('uint32_t', 'size')], visibility='private', is_virtual=True) + cls.add_method('DoGetDataMode', + 'ns3::WifiMode', + [param('uint32_t', 'size')], + visibility='private', is_virtual=True) ## onoe-wifi-manager.h: ns3::WifiMode ns3::OnoeWifiRemoteStation::DoGetRtsMode() [member function] - cls.add_method('DoGetRtsMode', 'ns3::WifiMode', [], visibility='private', is_virtual=True) + cls.add_method('DoGetRtsMode', + 'ns3::WifiMode', + [], + visibility='private', is_virtual=True) return def register_Ns3RraaWifiRemoteStation_methods(root_module, cls): ## rraa-wifi-manager.h: ns3::RraaWifiRemoteStation::RraaWifiRemoteStation(ns3::Ptr stations) [constructor] - cls.add_constructor([param('ns3::Ptr< ns3::RraaWifiManager >', 'stations')], visibility='public') + cls.add_constructor([param('ns3::Ptr< ns3::RraaWifiManager >', 'stations')]) ## rraa-wifi-manager.h: bool ns3::RraaWifiRemoteStation::NeedRts(ns3::Ptr packet) [member function] - cls.add_method('NeedRts', 'bool', [param('ns3::Ptr< const ns3::Packet >', 'packet')], is_virtual=True) + cls.add_method('NeedRts', + 'bool', + [param('ns3::Ptr< const ns3::Packet >', 'packet')], + is_virtual=True) ## rraa-wifi-manager.h: void ns3::RraaWifiRemoteStation::DoReportRxOk(double rxSnr, ns3::WifiMode txMode) [member function] - cls.add_method('DoReportRxOk', 'void', [param('double', 'rxSnr'), param('ns3::WifiMode', 'txMode')], visibility='protected', is_virtual=True) + cls.add_method('DoReportRxOk', + 'void', + [param('double', 'rxSnr'), param('ns3::WifiMode', 'txMode')], + visibility='protected', is_virtual=True) ## rraa-wifi-manager.h: void ns3::RraaWifiRemoteStation::DoReportRtsFailed() [member function] - cls.add_method('DoReportRtsFailed', 'void', [], visibility='protected', is_virtual=True) + cls.add_method('DoReportRtsFailed', + 'void', + [], + visibility='protected', is_virtual=True) ## rraa-wifi-manager.h: void ns3::RraaWifiRemoteStation::DoReportDataFailed() [member function] - cls.add_method('DoReportDataFailed', 'void', [], visibility='protected', is_virtual=True) + cls.add_method('DoReportDataFailed', + 'void', + [], + visibility='protected', is_virtual=True) ## rraa-wifi-manager.h: void ns3::RraaWifiRemoteStation::DoReportRtsOk(double ctsSnr, ns3::WifiMode ctsMode, double rtsSnr) [member function] - cls.add_method('DoReportRtsOk', 'void', [param('double', 'ctsSnr'), param('ns3::WifiMode', 'ctsMode'), param('double', 'rtsSnr')], visibility='protected', is_virtual=True) + cls.add_method('DoReportRtsOk', + 'void', + [param('double', 'ctsSnr'), param('ns3::WifiMode', 'ctsMode'), param('double', 'rtsSnr')], + visibility='protected', is_virtual=True) ## rraa-wifi-manager.h: void ns3::RraaWifiRemoteStation::DoReportDataOk(double ackSnr, ns3::WifiMode ackMode, double dataSnr) [member function] - cls.add_method('DoReportDataOk', 'void', [param('double', 'ackSnr'), param('ns3::WifiMode', 'ackMode'), param('double', 'dataSnr')], visibility='protected', is_virtual=True) + cls.add_method('DoReportDataOk', + 'void', + [param('double', 'ackSnr'), param('ns3::WifiMode', 'ackMode'), param('double', 'dataSnr')], + visibility='protected', is_virtual=True) ## rraa-wifi-manager.h: void ns3::RraaWifiRemoteStation::DoReportFinalRtsFailed() [member function] - cls.add_method('DoReportFinalRtsFailed', 'void', [], visibility='protected', is_virtual=True) + cls.add_method('DoReportFinalRtsFailed', + 'void', + [], + visibility='protected', is_virtual=True) ## rraa-wifi-manager.h: void ns3::RraaWifiRemoteStation::DoReportFinalDataFailed() [member function] - cls.add_method('DoReportFinalDataFailed', 'void', [], visibility='protected', is_virtual=True) + cls.add_method('DoReportFinalDataFailed', + 'void', + [], + visibility='protected', is_virtual=True) ## rraa-wifi-manager.h: ns3::Ptr ns3::RraaWifiRemoteStation::GetManager() const [member function] - cls.add_method('GetManager', 'ns3::Ptr< ns3::WifiRemoteStationManager >', [], is_const=True, visibility='private', is_virtual=True) + cls.add_method('GetManager', + 'ns3::Ptr< ns3::WifiRemoteStationManager >', + [], + is_const=True, visibility='private', is_virtual=True) ## rraa-wifi-manager.h: ns3::WifiMode ns3::RraaWifiRemoteStation::DoGetDataMode(uint32_t size) [member function] - cls.add_method('DoGetDataMode', 'ns3::WifiMode', [param('uint32_t', 'size')], visibility='private', is_virtual=True) + cls.add_method('DoGetDataMode', + 'ns3::WifiMode', + [param('uint32_t', 'size')], + visibility='private', is_virtual=True) ## rraa-wifi-manager.h: ns3::WifiMode ns3::RraaWifiRemoteStation::DoGetRtsMode() [member function] - cls.add_method('DoGetRtsMode', 'ns3::WifiMode', [], visibility='private', is_virtual=True) + cls.add_method('DoGetRtsMode', + 'ns3::WifiMode', + [], + visibility='private', is_virtual=True) return def register_Ns3Ssid_methods(root_module, cls): ## ssid.h: ns3::Ssid::Ssid(ns3::Ssid const & arg0) [copy constructor] - cls.add_constructor([param('ns3::Ssid&', 'arg0', is_const=True)], visibility='public') + cls.add_constructor([param('ns3::Ssid&', 'arg0', is_const=True)]) ## ssid.h: ns3::Ssid::Ssid() [constructor] - cls.add_constructor([], visibility='public') + cls.add_constructor([]) ## ssid.h: ns3::Ssid::Ssid(char const * ssid) [constructor] - cls.add_constructor([param('char *', 'ssid', transfer_ownership=False, is_const=True)], visibility='public') + cls.add_constructor([param('char *', 'ssid', transfer_ownership=False, is_const=True)]) ## ssid.h: ns3::Ssid::Ssid(char const * ssid, uint8_t length) [constructor] - cls.add_constructor([param('char *', 'ssid', transfer_ownership=False, is_const=True), param('uint8_t', 'length')], visibility='public') + cls.add_constructor([param('char *', 'ssid', transfer_ownership=False, is_const=True), param('uint8_t', 'length')]) ## ssid.h: ns3::Buffer::Iterator ns3::Ssid::Deserialize(ns3::Buffer::Iterator i) [member function] - cls.add_method('Deserialize', 'ns3::Buffer::Iterator', [param('ns3::Buffer::Iterator', 'i')]) + cls.add_method('Deserialize', + 'ns3::Buffer::Iterator', + [param('ns3::Buffer::Iterator', 'i')]) ## ssid.h: uint32_t ns3::Ssid::GetLength() const [member function] - cls.add_method('GetLength', 'uint32_t', [], is_const=True) + cls.add_method('GetLength', + 'uint32_t', + [], + is_const=True) ## ssid.h: uint32_t ns3::Ssid::GetSerializedSize() const [member function] - cls.add_method('GetSerializedSize', 'uint32_t', [], is_const=True) + cls.add_method('GetSerializedSize', + 'uint32_t', + [], + is_const=True) ## ssid.h: bool ns3::Ssid::IsBroadcast() const [member function] - cls.add_method('IsBroadcast', 'bool', [], is_const=True) + cls.add_method('IsBroadcast', + 'bool', + [], + is_const=True) ## ssid.h: bool ns3::Ssid::IsEqual(ns3::Ssid const & o) const [member function] - cls.add_method('IsEqual', 'bool', [param('ns3::Ssid&', 'o', is_const=True)], is_const=True) + cls.add_method('IsEqual', + 'bool', + [param('ns3::Ssid&', 'o', is_const=True)], + is_const=True) ## ssid.h: char * ns3::Ssid::PeekString() const [member function] - cls.add_method('PeekString', 'char *', [], is_const=True) + cls.add_method('PeekString', + 'char *', + [], + is_const=True) ## ssid.h: ns3::Buffer::Iterator ns3::Ssid::Serialize(ns3::Buffer::Iterator i) const [member function] - cls.add_method('Serialize', 'ns3::Buffer::Iterator', [param('ns3::Buffer::Iterator', 'i')], is_const=True) + cls.add_method('Serialize', + 'ns3::Buffer::Iterator', + [param('ns3::Buffer::Iterator', 'i')], + is_const=True) cls.add_output_stream_operator() return def register_Ns3WifiMode_methods(root_module, cls): ## wifi-mode.h: ns3::WifiMode::WifiMode(ns3::WifiMode const & arg0) [copy constructor] - cls.add_constructor([param('ns3::WifiMode&', 'arg0', is_const=True)], visibility='public') + cls.add_constructor([param('ns3::WifiMode&', 'arg0', is_const=True)]) ## wifi-mode.h: ns3::WifiMode::WifiMode() [constructor] - cls.add_constructor([], visibility='public') + cls.add_constructor([]) ## wifi-mode.h: uint32_t ns3::WifiMode::GetBandwidth() const [member function] - cls.add_method('GetBandwidth', 'uint32_t', [], is_const=True) + cls.add_method('GetBandwidth', + 'uint32_t', + [], + is_const=True) ## wifi-mode.h: uint8_t ns3::WifiMode::GetConstellationSize() const [member function] - cls.add_method('GetConstellationSize', 'uint8_t', [], is_const=True) + cls.add_method('GetConstellationSize', + 'uint8_t', + [], + is_const=True) ## wifi-mode.h: uint32_t ns3::WifiMode::GetDataRate() const [member function] - cls.add_method('GetDataRate', 'uint32_t', [], is_const=True) + cls.add_method('GetDataRate', + 'uint32_t', + [], + is_const=True) ## wifi-mode.h: ns3::WifiMode::ModulationType ns3::WifiMode::GetModulationType() const [member function] - cls.add_method('GetModulationType', 'ns3::WifiMode::ModulationType', [], is_const=True) + cls.add_method('GetModulationType', + 'ns3::WifiMode::ModulationType', + [], + is_const=True) ## wifi-mode.h: uint32_t ns3::WifiMode::GetPhyRate() const [member function] - cls.add_method('GetPhyRate', 'uint32_t', [], is_const=True) + cls.add_method('GetPhyRate', + 'uint32_t', + [], + is_const=True) ## wifi-mode.h: uint32_t ns3::WifiMode::GetUid() const [member function] - cls.add_method('GetUid', 'uint32_t', [], is_const=True) + cls.add_method('GetUid', + 'uint32_t', + [], + is_const=True) ## wifi-mode.h: std::string ns3::WifiMode::GetUniqueName() const [member function] - cls.add_method('GetUniqueName', 'std::string', [], is_const=True) + cls.add_method('GetUniqueName', + 'std::string', + [], + is_const=True) ## wifi-mode.h: bool ns3::WifiMode::IsMandatory() const [member function] - cls.add_method('IsMandatory', 'bool', [], is_const=True) + cls.add_method('IsMandatory', + 'bool', + [], + is_const=True) ## wifi-mode.h: bool ns3::WifiMode::IsModulationBpsk() const [member function] - cls.add_method('IsModulationBpsk', 'bool', [], is_const=True) + cls.add_method('IsModulationBpsk', + 'bool', + [], + is_const=True) ## wifi-mode.h: bool ns3::WifiMode::IsModulationQam() const [member function] - cls.add_method('IsModulationQam', 'bool', [], is_const=True) + cls.add_method('IsModulationQam', + 'bool', + [], + is_const=True) cls.add_output_stream_operator() return def register_Ns3SsidValue_methods(root_module, cls): ## ssid.h: ns3::SsidValue::SsidValue() [constructor] - cls.add_constructor([], visibility='public') + cls.add_constructor([]) ## ssid.h: ns3::SsidValue::SsidValue(ns3::Ssid const & value) [constructor] - cls.add_constructor([param('ns3::Ssid&', 'value', is_const=True)], visibility='public') + cls.add_constructor([param('ns3::Ssid&', 'value', is_const=True)]) ## ssid.h: void ns3::SsidValue::Set(ns3::Ssid const & value) [member function] - cls.add_method('Set', 'void', [param('ns3::Ssid&', 'value', is_const=True)]) + cls.add_method('Set', + 'void', + [param('ns3::Ssid&', 'value', is_const=True)]) ## ssid.h: ns3::Ssid ns3::SsidValue::Get() const [member function] - cls.add_method('Get', 'ns3::Ssid', [], is_const=True) + cls.add_method('Get', + 'ns3::Ssid', + [], + is_const=True) ## ssid.h: ns3::Ptr ns3::SsidValue::Copy() const [member function] - cls.add_method('Copy', 'ns3::Ptr< ns3::AttributeValue >', [], is_const=True, is_virtual=True) + cls.add_method('Copy', + 'ns3::Ptr< ns3::AttributeValue >', + [], + is_const=True, is_virtual=True) ## ssid.h: std::string ns3::SsidValue::SerializeToString(ns3::Ptr checker) const [member function] - cls.add_method('SerializeToString', 'std::string', [param('ns3::Ptr< ns3::AttributeChecker const >', 'checker')], is_const=True, is_virtual=True) + cls.add_method('SerializeToString', + 'std::string', + [param('ns3::Ptr< ns3::AttributeChecker const >', 'checker')], + is_const=True, is_virtual=True) ## ssid.h: bool ns3::SsidValue::DeserializeFromString(std::string value, ns3::Ptr checker) [member function] - cls.add_method('DeserializeFromString', 'bool', [param('std::string', 'value'), param('ns3::Ptr< ns3::AttributeChecker const >', 'checker')], is_virtual=True) + cls.add_method('DeserializeFromString', + 'bool', + [param('std::string', 'value'), param('ns3::Ptr< ns3::AttributeChecker const >', 'checker')], + is_virtual=True) return def register_Ns3SsidChecker_methods(root_module, cls): @@ -485,734 +792,1543 @@ def register_Ns3SsidChecker_methods(root_module, cls): def register_Ns3ConstantRateWifiRemoteStation_methods(root_module, cls): ## constant-rate-wifi-manager.h: ns3::ConstantRateWifiRemoteStation::ConstantRateWifiRemoteStation(ns3::Ptr stations) [constructor] - cls.add_constructor([param('ns3::Ptr< ns3::ConstantRateWifiManager >', 'stations')], visibility='public') + cls.add_constructor([param('ns3::Ptr< ns3::ConstantRateWifiManager >', 'stations')]) ## constant-rate-wifi-manager.h: void ns3::ConstantRateWifiRemoteStation::DoReportRxOk(double rxSnr, ns3::WifiMode txMode) [member function] - cls.add_method('DoReportRxOk', 'void', [param('double', 'rxSnr'), param('ns3::WifiMode', 'txMode')], visibility='protected', is_virtual=True) + cls.add_method('DoReportRxOk', + 'void', + [param('double', 'rxSnr'), param('ns3::WifiMode', 'txMode')], + visibility='protected', is_virtual=True) ## constant-rate-wifi-manager.h: void ns3::ConstantRateWifiRemoteStation::DoReportRtsFailed() [member function] - cls.add_method('DoReportRtsFailed', 'void', [], visibility='protected', is_virtual=True) + cls.add_method('DoReportRtsFailed', + 'void', + [], + visibility='protected', is_virtual=True) ## constant-rate-wifi-manager.h: void ns3::ConstantRateWifiRemoteStation::DoReportDataFailed() [member function] - cls.add_method('DoReportDataFailed', 'void', [], visibility='protected', is_virtual=True) + cls.add_method('DoReportDataFailed', + 'void', + [], + visibility='protected', is_virtual=True) ## constant-rate-wifi-manager.h: void ns3::ConstantRateWifiRemoteStation::DoReportRtsOk(double ctsSnr, ns3::WifiMode ctsMode, double rtsSnr) [member function] - cls.add_method('DoReportRtsOk', 'void', [param('double', 'ctsSnr'), param('ns3::WifiMode', 'ctsMode'), param('double', 'rtsSnr')], visibility='protected', is_virtual=True) + cls.add_method('DoReportRtsOk', + 'void', + [param('double', 'ctsSnr'), param('ns3::WifiMode', 'ctsMode'), param('double', 'rtsSnr')], + visibility='protected', is_virtual=True) ## constant-rate-wifi-manager.h: void ns3::ConstantRateWifiRemoteStation::DoReportDataOk(double ackSnr, ns3::WifiMode ackMode, double dataSnr) [member function] - cls.add_method('DoReportDataOk', 'void', [param('double', 'ackSnr'), param('ns3::WifiMode', 'ackMode'), param('double', 'dataSnr')], visibility='protected', is_virtual=True) + cls.add_method('DoReportDataOk', + 'void', + [param('double', 'ackSnr'), param('ns3::WifiMode', 'ackMode'), param('double', 'dataSnr')], + visibility='protected', is_virtual=True) ## constant-rate-wifi-manager.h: void ns3::ConstantRateWifiRemoteStation::DoReportFinalRtsFailed() [member function] - cls.add_method('DoReportFinalRtsFailed', 'void', [], visibility='protected', is_virtual=True) + cls.add_method('DoReportFinalRtsFailed', + 'void', + [], + visibility='protected', is_virtual=True) ## constant-rate-wifi-manager.h: void ns3::ConstantRateWifiRemoteStation::DoReportFinalDataFailed() [member function] - cls.add_method('DoReportFinalDataFailed', 'void', [], visibility='protected', is_virtual=True) + cls.add_method('DoReportFinalDataFailed', + 'void', + [], + visibility='protected', is_virtual=True) ## constant-rate-wifi-manager.h: ns3::Ptr ns3::ConstantRateWifiRemoteStation::GetManager() const [member function] - cls.add_method('GetManager', 'ns3::Ptr< ns3::WifiRemoteStationManager >', [], is_const=True, visibility='private', is_virtual=True) + cls.add_method('GetManager', + 'ns3::Ptr< ns3::WifiRemoteStationManager >', + [], + is_const=True, visibility='private', is_virtual=True) ## constant-rate-wifi-manager.h: ns3::WifiMode ns3::ConstantRateWifiRemoteStation::DoGetDataMode(uint32_t size) [member function] - cls.add_method('DoGetDataMode', 'ns3::WifiMode', [param('uint32_t', 'size')], visibility='private', is_virtual=True) + cls.add_method('DoGetDataMode', + 'ns3::WifiMode', + [param('uint32_t', 'size')], + visibility='private', is_virtual=True) ## constant-rate-wifi-manager.h: ns3::WifiMode ns3::ConstantRateWifiRemoteStation::DoGetRtsMode() [member function] - cls.add_method('DoGetRtsMode', 'ns3::WifiMode', [], visibility='private', is_virtual=True) + cls.add_method('DoGetRtsMode', + 'ns3::WifiMode', + [], + visibility='private', is_virtual=True) return def register_Ns3PropagationLossModel_methods(root_module, cls): ## propagation-loss-model.h: static ns3::TypeId ns3::PropagationLossModel::GetTypeId() [member function] - cls.add_method('GetTypeId', 'ns3::TypeId', [], is_static=True) + cls.add_method('GetTypeId', + 'ns3::TypeId', + [], + is_static=True) ## propagation-loss-model.h: double ns3::PropagationLossModel::GetLoss(ns3::Ptr a, ns3::Ptr b) const [member function] - cls.add_method('GetLoss', 'double', [param('ns3::Ptr< ns3::MobilityModel >', 'a'), param('ns3::Ptr< ns3::MobilityModel >', 'b')], is_pure_virtual=True, is_const=True, is_virtual=True) + cls.add_method('GetLoss', + 'double', + [param('ns3::Ptr< ns3::MobilityModel >', 'a'), param('ns3::Ptr< ns3::MobilityModel >', 'b')], + is_pure_virtual=True, is_const=True, is_virtual=True) cls.add_constructor([]) return def register_Ns3ArfWifiRemoteStation_methods(root_module, cls): ## arf-wifi-manager.h: ns3::ArfWifiRemoteStation::ArfWifiRemoteStation(ns3::Ptr stations, int minTimerTimeout, int minSuccessThreshold) [constructor] - cls.add_constructor([param('ns3::Ptr< ns3::ArfWifiManager >', 'stations'), param('int', 'minTimerTimeout'), param('int', 'minSuccessThreshold')], visibility='public') + cls.add_constructor([param('ns3::Ptr< ns3::ArfWifiManager >', 'stations'), param('int', 'minTimerTimeout'), param('int', 'minSuccessThreshold')]) ## arf-wifi-manager.h: void ns3::ArfWifiRemoteStation::DoReportRxOk(double rxSnr, ns3::WifiMode txMode) [member function] - cls.add_method('DoReportRxOk', 'void', [param('double', 'rxSnr'), param('ns3::WifiMode', 'txMode')], visibility='protected', is_virtual=True) + cls.add_method('DoReportRxOk', + 'void', + [param('double', 'rxSnr'), param('ns3::WifiMode', 'txMode')], + visibility='protected', is_virtual=True) ## arf-wifi-manager.h: void ns3::ArfWifiRemoteStation::DoReportRtsFailed() [member function] - cls.add_method('DoReportRtsFailed', 'void', [], visibility='protected', is_virtual=True) + cls.add_method('DoReportRtsFailed', + 'void', + [], + visibility='protected', is_virtual=True) ## arf-wifi-manager.h: void ns3::ArfWifiRemoteStation::DoReportDataFailed() [member function] - cls.add_method('DoReportDataFailed', 'void', [], visibility='protected', is_virtual=True) + cls.add_method('DoReportDataFailed', + 'void', + [], + visibility='protected', is_virtual=True) ## arf-wifi-manager.h: void ns3::ArfWifiRemoteStation::DoReportRtsOk(double ctsSnr, ns3::WifiMode ctsMode, double rtsSnr) [member function] - cls.add_method('DoReportRtsOk', 'void', [param('double', 'ctsSnr'), param('ns3::WifiMode', 'ctsMode'), param('double', 'rtsSnr')], visibility='protected', is_virtual=True) + cls.add_method('DoReportRtsOk', + 'void', + [param('double', 'ctsSnr'), param('ns3::WifiMode', 'ctsMode'), param('double', 'rtsSnr')], + visibility='protected', is_virtual=True) ## arf-wifi-manager.h: void ns3::ArfWifiRemoteStation::DoReportDataOk(double ackSnr, ns3::WifiMode ackMode, double dataSnr) [member function] - cls.add_method('DoReportDataOk', 'void', [param('double', 'ackSnr'), param('ns3::WifiMode', 'ackMode'), param('double', 'dataSnr')], visibility='protected', is_virtual=True) + cls.add_method('DoReportDataOk', + 'void', + [param('double', 'ackSnr'), param('ns3::WifiMode', 'ackMode'), param('double', 'dataSnr')], + visibility='protected', is_virtual=True) ## arf-wifi-manager.h: void ns3::ArfWifiRemoteStation::DoReportFinalRtsFailed() [member function] - cls.add_method('DoReportFinalRtsFailed', 'void', [], visibility='protected', is_virtual=True) + cls.add_method('DoReportFinalRtsFailed', + 'void', + [], + visibility='protected', is_virtual=True) ## arf-wifi-manager.h: void ns3::ArfWifiRemoteStation::DoReportFinalDataFailed() [member function] - cls.add_method('DoReportFinalDataFailed', 'void', [], visibility='protected', is_virtual=True) + cls.add_method('DoReportFinalDataFailed', + 'void', + [], + visibility='protected', is_virtual=True) ## arf-wifi-manager.h: uint32_t ns3::ArfWifiRemoteStation::GetMinTimerTimeout() [member function] - cls.add_method('GetMinTimerTimeout', 'uint32_t', [], visibility='protected') + cls.add_method('GetMinTimerTimeout', + 'uint32_t', + [], + visibility='protected') ## arf-wifi-manager.h: uint32_t ns3::ArfWifiRemoteStation::GetMinSuccessThreshold() [member function] - cls.add_method('GetMinSuccessThreshold', 'uint32_t', [], visibility='protected') + cls.add_method('GetMinSuccessThreshold', + 'uint32_t', + [], + visibility='protected') ## arf-wifi-manager.h: uint32_t ns3::ArfWifiRemoteStation::GetTimerTimeout() [member function] - cls.add_method('GetTimerTimeout', 'uint32_t', [], visibility='protected') + cls.add_method('GetTimerTimeout', + 'uint32_t', + [], + visibility='protected') ## arf-wifi-manager.h: uint32_t ns3::ArfWifiRemoteStation::GetSuccessThreshold() [member function] - cls.add_method('GetSuccessThreshold', 'uint32_t', [], visibility='protected') + cls.add_method('GetSuccessThreshold', + 'uint32_t', + [], + visibility='protected') ## arf-wifi-manager.h: void ns3::ArfWifiRemoteStation::SetTimerTimeout(uint32_t timerTimeout) [member function] - cls.add_method('SetTimerTimeout', 'void', [param('uint32_t', 'timerTimeout')], visibility='protected') + cls.add_method('SetTimerTimeout', + 'void', + [param('uint32_t', 'timerTimeout')], + visibility='protected') ## arf-wifi-manager.h: void ns3::ArfWifiRemoteStation::SetSuccessThreshold(uint32_t successThreshold) [member function] - cls.add_method('SetSuccessThreshold', 'void', [param('uint32_t', 'successThreshold')], visibility='protected') + cls.add_method('SetSuccessThreshold', + 'void', + [param('uint32_t', 'successThreshold')], + visibility='protected') ## arf-wifi-manager.h: ns3::Ptr ns3::ArfWifiRemoteStation::GetManager() const [member function] - cls.add_method('GetManager', 'ns3::Ptr< ns3::WifiRemoteStationManager >', [], is_const=True, visibility='private', is_virtual=True) + cls.add_method('GetManager', + 'ns3::Ptr< ns3::WifiRemoteStationManager >', + [], + is_const=True, visibility='private', is_virtual=True) ## arf-wifi-manager.h: ns3::WifiMode ns3::ArfWifiRemoteStation::DoGetDataMode(uint32_t size) [member function] - cls.add_method('DoGetDataMode', 'ns3::WifiMode', [param('uint32_t', 'size')], visibility='private', is_virtual=True) + cls.add_method('DoGetDataMode', + 'ns3::WifiMode', + [param('uint32_t', 'size')], + visibility='private', is_virtual=True) ## arf-wifi-manager.h: ns3::WifiMode ns3::ArfWifiRemoteStation::DoGetRtsMode() [member function] - cls.add_method('DoGetRtsMode', 'ns3::WifiMode', [], visibility='private', is_virtual=True) + cls.add_method('DoGetRtsMode', + 'ns3::WifiMode', + [], + visibility='private', is_virtual=True) ## arf-wifi-manager.h: void ns3::ArfWifiRemoteStation::ReportRecoveryFailure() [member function] - cls.add_method('ReportRecoveryFailure', 'void', [], visibility='private', is_virtual=True) + cls.add_method('ReportRecoveryFailure', + 'void', + [], + visibility='private', is_virtual=True) ## arf-wifi-manager.h: void ns3::ArfWifiRemoteStation::ReportFailure() [member function] - cls.add_method('ReportFailure', 'void', [], visibility='private', is_virtual=True) + cls.add_method('ReportFailure', + 'void', + [], + visibility='private', is_virtual=True) return def register_Ns3WifiMac_methods(root_module, cls): ## wifi-mac.h: static ns3::TypeId ns3::WifiMac::GetTypeId() [member function] - cls.add_method('GetTypeId', 'ns3::TypeId', [], is_static=True) + cls.add_method('GetTypeId', + 'ns3::TypeId', + [], + is_static=True) ## wifi-mac.h: void ns3::WifiMac::SetSlot(ns3::Time slotTime) [member function] - cls.add_method('SetSlot', 'void', [param('ns3::Time', 'slotTime')], is_pure_virtual=True, is_virtual=True) + cls.add_method('SetSlot', + 'void', + [param('ns3::Time', 'slotTime')], + is_pure_virtual=True, is_virtual=True) ## wifi-mac.h: void ns3::WifiMac::SetSifs(ns3::Time sifs) [member function] - cls.add_method('SetSifs', 'void', [param('ns3::Time', 'sifs')], is_pure_virtual=True, is_virtual=True) + cls.add_method('SetSifs', + 'void', + [param('ns3::Time', 'sifs')], + is_pure_virtual=True, is_virtual=True) ## wifi-mac.h: void ns3::WifiMac::SetEifsNoDifs(ns3::Time eifsNoDifs) [member function] - cls.add_method('SetEifsNoDifs', 'void', [param('ns3::Time', 'eifsNoDifs')], is_pure_virtual=True, is_virtual=True) + cls.add_method('SetEifsNoDifs', + 'void', + [param('ns3::Time', 'eifsNoDifs')], + is_pure_virtual=True, is_virtual=True) ## wifi-mac.h: void ns3::WifiMac::SetPifs(ns3::Time pifs) [member function] - cls.add_method('SetPifs', 'void', [param('ns3::Time', 'pifs')]) + cls.add_method('SetPifs', + 'void', + [param('ns3::Time', 'pifs')]) ## wifi-mac.h: void ns3::WifiMac::SetCtsTimeout(ns3::Time ctsTimeout) [member function] - cls.add_method('SetCtsTimeout', 'void', [param('ns3::Time', 'ctsTimeout')]) + cls.add_method('SetCtsTimeout', + 'void', + [param('ns3::Time', 'ctsTimeout')]) ## wifi-mac.h: void ns3::WifiMac::SetAckTimeout(ns3::Time ackTimeout) [member function] - cls.add_method('SetAckTimeout', 'void', [param('ns3::Time', 'ackTimeout')]) + cls.add_method('SetAckTimeout', + 'void', + [param('ns3::Time', 'ackTimeout')]) ## wifi-mac.h: void ns3::WifiMac::SetMaxPropagationDelay(ns3::Time delay) [member function] - cls.add_method('SetMaxPropagationDelay', 'void', [param('ns3::Time', 'delay')]) + cls.add_method('SetMaxPropagationDelay', + 'void', + [param('ns3::Time', 'delay')]) ## wifi-mac.h: ns3::Time ns3::WifiMac::GetPifs() const [member function] - cls.add_method('GetPifs', 'ns3::Time', [], is_const=True) + cls.add_method('GetPifs', + 'ns3::Time', + [], + is_const=True) ## wifi-mac.h: ns3::Time ns3::WifiMac::GetSifs() const [member function] - cls.add_method('GetSifs', 'ns3::Time', [], is_pure_virtual=True, is_const=True, is_virtual=True) + cls.add_method('GetSifs', + 'ns3::Time', + [], + is_pure_virtual=True, is_const=True, is_virtual=True) ## wifi-mac.h: ns3::Time ns3::WifiMac::GetSlot() const [member function] - cls.add_method('GetSlot', 'ns3::Time', [], is_pure_virtual=True, is_const=True, is_virtual=True) + cls.add_method('GetSlot', + 'ns3::Time', + [], + is_pure_virtual=True, is_const=True, is_virtual=True) ## wifi-mac.h: ns3::Time ns3::WifiMac::GetEifsNoDifs() const [member function] - cls.add_method('GetEifsNoDifs', 'ns3::Time', [], is_pure_virtual=True, is_const=True, is_virtual=True) + cls.add_method('GetEifsNoDifs', + 'ns3::Time', + [], + is_pure_virtual=True, is_const=True, is_virtual=True) ## wifi-mac.h: ns3::Time ns3::WifiMac::GetCtsTimeout() const [member function] - cls.add_method('GetCtsTimeout', 'ns3::Time', [], is_const=True) + cls.add_method('GetCtsTimeout', + 'ns3::Time', + [], + is_const=True) ## wifi-mac.h: ns3::Time ns3::WifiMac::GetAckTimeout() const [member function] - cls.add_method('GetAckTimeout', 'ns3::Time', [], is_const=True) + cls.add_method('GetAckTimeout', + 'ns3::Time', + [], + is_const=True) ## wifi-mac.h: ns3::Time ns3::WifiMac::GetMsduLifetime() const [member function] - cls.add_method('GetMsduLifetime', 'ns3::Time', [], is_const=True) + cls.add_method('GetMsduLifetime', + 'ns3::Time', + [], + is_const=True) ## wifi-mac.h: ns3::Time ns3::WifiMac::GetMaxPropagationDelay() const [member function] - cls.add_method('GetMaxPropagationDelay', 'ns3::Time', [], is_const=True) + cls.add_method('GetMaxPropagationDelay', + 'ns3::Time', + [], + is_const=True) ## wifi-mac.h: uint32_t ns3::WifiMac::GetMaxMsduSize() const [member function] - cls.add_method('GetMaxMsduSize', 'uint32_t', [], is_const=True) + cls.add_method('GetMaxMsduSize', + 'uint32_t', + [], + is_const=True) ## wifi-mac.h: ns3::Mac48Address ns3::WifiMac::GetAddress() const [member function] - cls.add_method('GetAddress', 'ns3::Mac48Address', [], is_pure_virtual=True, is_const=True, is_virtual=True) + cls.add_method('GetAddress', + 'ns3::Mac48Address', + [], + is_pure_virtual=True, is_const=True, is_virtual=True) ## wifi-mac.h: ns3::Ssid ns3::WifiMac::GetSsid() const [member function] - cls.add_method('GetSsid', 'ns3::Ssid', [], is_pure_virtual=True, is_const=True, is_virtual=True) + cls.add_method('GetSsid', + 'ns3::Ssid', + [], + is_pure_virtual=True, is_const=True, is_virtual=True) ## wifi-mac.h: ns3::Mac48Address ns3::WifiMac::GetBssid() const [member function] - cls.add_method('GetBssid', 'ns3::Mac48Address', [], is_pure_virtual=True, is_const=True, is_virtual=True) + cls.add_method('GetBssid', + 'ns3::Mac48Address', + [], + is_pure_virtual=True, is_const=True, is_virtual=True) ## wifi-mac.h: void ns3::WifiMac::SetAddress(ns3::Mac48Address address) [member function] - cls.add_method('SetAddress', 'void', [param('ns3::Mac48Address', 'address')], is_pure_virtual=True, is_virtual=True) + cls.add_method('SetAddress', + 'void', + [param('ns3::Mac48Address', 'address')], + is_pure_virtual=True, is_virtual=True) ## wifi-mac.h: void ns3::WifiMac::SetSsid(ns3::Ssid ssid) [member function] - cls.add_method('SetSsid', 'void', [param('ns3::Ssid', 'ssid')], is_pure_virtual=True, is_virtual=True) + cls.add_method('SetSsid', + 'void', + [param('ns3::Ssid', 'ssid')], + is_pure_virtual=True, is_virtual=True) ## wifi-mac.h: void ns3::WifiMac::Enqueue(ns3::Ptr packet, ns3::Mac48Address to) [member function] - cls.add_method('Enqueue', 'void', [param('ns3::Ptr< const ns3::Packet >', 'packet'), param('ns3::Mac48Address', 'to')], is_pure_virtual=True, visibility='private', is_virtual=True) + cls.add_method('Enqueue', + 'void', + [param('ns3::Ptr< const ns3::Packet >', 'packet'), param('ns3::Mac48Address', 'to')], + is_pure_virtual=True, visibility='private', is_virtual=True) ## wifi-mac.h: void ns3::WifiMac::SetWifiPhy(ns3::Ptr phy) [member function] - cls.add_method('SetWifiPhy', 'void', [param('ns3::Ptr< ns3::WifiPhy >', 'phy')], is_pure_virtual=True, visibility='private', is_virtual=True) + cls.add_method('SetWifiPhy', + 'void', + [param('ns3::Ptr< ns3::WifiPhy >', 'phy')], + is_pure_virtual=True, visibility='private', is_virtual=True) ## wifi-mac.h: void ns3::WifiMac::SetWifiRemoteStationManager(ns3::Ptr stationManager) [member function] - cls.add_method('SetWifiRemoteStationManager', 'void', [param('ns3::Ptr< ns3::WifiRemoteStationManager >', 'stationManager')], is_pure_virtual=True, visibility='private', is_virtual=True) + cls.add_method('SetWifiRemoteStationManager', + 'void', + [param('ns3::Ptr< ns3::WifiRemoteStationManager >', 'stationManager')], + is_pure_virtual=True, visibility='private', is_virtual=True) ## wifi-mac.h: void ns3::WifiMac::SetForwardUpCallback(ns3::Callback, ns3::Mac48Address const&, ns3::empty, ns3::empty, ns3::empty, ns3::empty> upCallback) [member function] - cls.add_method('SetForwardUpCallback', 'void', [param('ns3::Callback< void, ns3::Ptr< ns3::Packet >, ns3::Mac48Address const&, ns3::empty, ns3::empty, ns3::empty, ns3::empty >', 'upCallback')], is_pure_virtual=True, visibility='private', is_virtual=True) + cls.add_method('SetForwardUpCallback', + 'void', + [param('ns3::Callback< void, ns3::Ptr< ns3::Packet >, ns3::Mac48Address const&, ns3::empty, ns3::empty, ns3::empty, ns3::empty >', 'upCallback')], + is_pure_virtual=True, visibility='private', is_virtual=True) ## wifi-mac.h: void ns3::WifiMac::SetLinkUpCallback(ns3::Callback linkUp) [member function] - cls.add_method('SetLinkUpCallback', 'void', [param('ns3::Callback< void, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty >', 'linkUp')], is_pure_virtual=True, visibility='private', is_virtual=True) + cls.add_method('SetLinkUpCallback', + 'void', + [param('ns3::Callback< void, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty >', 'linkUp')], + is_pure_virtual=True, visibility='private', is_virtual=True) ## wifi-mac.h: void ns3::WifiMac::SetLinkDownCallback(ns3::Callback linkDown) [member function] - cls.add_method('SetLinkDownCallback', 'void', [param('ns3::Callback< void, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty >', 'linkDown')], is_pure_virtual=True, visibility='private', is_virtual=True) + cls.add_method('SetLinkDownCallback', + 'void', + [param('ns3::Callback< void, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty >', 'linkDown')], + is_pure_virtual=True, visibility='private', is_virtual=True) cls.add_constructor([]) return def register_Ns3NqapWifiMac_methods(root_module, cls): ## nqap-wifi-mac.h: static ns3::TypeId ns3::NqapWifiMac::GetTypeId() [member function] - cls.add_method('GetTypeId', 'ns3::TypeId', [], is_static=True) + cls.add_method('GetTypeId', + 'ns3::TypeId', + [], + is_static=True) ## nqap-wifi-mac.h: ns3::NqapWifiMac::NqapWifiMac() [constructor] - cls.add_constructor([], visibility='public') + cls.add_constructor([]) ## nqap-wifi-mac.h: void ns3::NqapWifiMac::SetSlot(ns3::Time slotTime) [member function] - cls.add_method('SetSlot', 'void', [param('ns3::Time', 'slotTime')], is_virtual=True) + cls.add_method('SetSlot', + 'void', + [param('ns3::Time', 'slotTime')], + is_virtual=True) ## nqap-wifi-mac.h: void ns3::NqapWifiMac::SetSifs(ns3::Time sifs) [member function] - cls.add_method('SetSifs', 'void', [param('ns3::Time', 'sifs')], is_virtual=True) + cls.add_method('SetSifs', + 'void', + [param('ns3::Time', 'sifs')], + is_virtual=True) ## nqap-wifi-mac.h: void ns3::NqapWifiMac::SetEifsNoDifs(ns3::Time eifsNoDifs) [member function] - cls.add_method('SetEifsNoDifs', 'void', [param('ns3::Time', 'eifsNoDifs')], is_virtual=True) + cls.add_method('SetEifsNoDifs', + 'void', + [param('ns3::Time', 'eifsNoDifs')], + is_virtual=True) ## nqap-wifi-mac.h: ns3::Time ns3::NqapWifiMac::GetSlot() const [member function] - cls.add_method('GetSlot', 'ns3::Time', [], is_const=True, is_virtual=True) + cls.add_method('GetSlot', + 'ns3::Time', + [], + is_const=True, is_virtual=True) ## nqap-wifi-mac.h: ns3::Time ns3::NqapWifiMac::GetSifs() const [member function] - cls.add_method('GetSifs', 'ns3::Time', [], is_const=True, is_virtual=True) + cls.add_method('GetSifs', + 'ns3::Time', + [], + is_const=True, is_virtual=True) ## nqap-wifi-mac.h: ns3::Time ns3::NqapWifiMac::GetEifsNoDifs() const [member function] - cls.add_method('GetEifsNoDifs', 'ns3::Time', [], is_const=True, is_virtual=True) + cls.add_method('GetEifsNoDifs', + 'ns3::Time', + [], + is_const=True, is_virtual=True) ## nqap-wifi-mac.h: void ns3::NqapWifiMac::SetWifiPhy(ns3::Ptr phy) [member function] - cls.add_method('SetWifiPhy', 'void', [param('ns3::Ptr< ns3::WifiPhy >', 'phy')], is_virtual=True) + cls.add_method('SetWifiPhy', + 'void', + [param('ns3::Ptr< ns3::WifiPhy >', 'phy')], + is_virtual=True) ## nqap-wifi-mac.h: void ns3::NqapWifiMac::SetWifiRemoteStationManager(ns3::Ptr stationManager) [member function] - cls.add_method('SetWifiRemoteStationManager', 'void', [param('ns3::Ptr< ns3::WifiRemoteStationManager >', 'stationManager')], is_virtual=True) + cls.add_method('SetWifiRemoteStationManager', + 'void', + [param('ns3::Ptr< ns3::WifiRemoteStationManager >', 'stationManager')], + is_virtual=True) ## nqap-wifi-mac.h: void ns3::NqapWifiMac::Enqueue(ns3::Ptr packet, ns3::Mac48Address to) [member function] - cls.add_method('Enqueue', 'void', [param('ns3::Ptr< const ns3::Packet >', 'packet'), param('ns3::Mac48Address', 'to')], is_virtual=True) + cls.add_method('Enqueue', + 'void', + [param('ns3::Ptr< const ns3::Packet >', 'packet'), param('ns3::Mac48Address', 'to')], + is_virtual=True) ## nqap-wifi-mac.h: void ns3::NqapWifiMac::SetForwardUpCallback(ns3::Callback, ns3::Mac48Address const&, ns3::empty, ns3::empty, ns3::empty, ns3::empty> upCallback) [member function] - cls.add_method('SetForwardUpCallback', 'void', [param('ns3::Callback< void, ns3::Ptr< ns3::Packet >, ns3::Mac48Address const&, ns3::empty, ns3::empty, ns3::empty, ns3::empty >', 'upCallback')], is_virtual=True) + cls.add_method('SetForwardUpCallback', + 'void', + [param('ns3::Callback< void, ns3::Ptr< ns3::Packet >, ns3::Mac48Address const&, ns3::empty, ns3::empty, ns3::empty, ns3::empty >', 'upCallback')], + is_virtual=True) ## nqap-wifi-mac.h: void ns3::NqapWifiMac::SetLinkUpCallback(ns3::Callback linkUp) [member function] - cls.add_method('SetLinkUpCallback', 'void', [param('ns3::Callback< void, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty >', 'linkUp')], is_virtual=True) + cls.add_method('SetLinkUpCallback', + 'void', + [param('ns3::Callback< void, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty >', 'linkUp')], + is_virtual=True) ## nqap-wifi-mac.h: void ns3::NqapWifiMac::SetLinkDownCallback(ns3::Callback linkDown) [member function] - cls.add_method('SetLinkDownCallback', 'void', [param('ns3::Callback< void, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty >', 'linkDown')], is_virtual=True) + cls.add_method('SetLinkDownCallback', + 'void', + [param('ns3::Callback< void, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty >', 'linkDown')], + is_virtual=True) ## nqap-wifi-mac.h: ns3::Mac48Address ns3::NqapWifiMac::GetAddress() const [member function] - cls.add_method('GetAddress', 'ns3::Mac48Address', [], is_const=True, is_virtual=True) + cls.add_method('GetAddress', + 'ns3::Mac48Address', + [], + is_const=True, is_virtual=True) ## nqap-wifi-mac.h: ns3::Ssid ns3::NqapWifiMac::GetSsid() const [member function] - cls.add_method('GetSsid', 'ns3::Ssid', [], is_const=True, is_virtual=True) + cls.add_method('GetSsid', + 'ns3::Ssid', + [], + is_const=True, is_virtual=True) ## nqap-wifi-mac.h: ns3::Mac48Address ns3::NqapWifiMac::GetBssid() const [member function] - cls.add_method('GetBssid', 'ns3::Mac48Address', [], is_const=True, is_virtual=True) + cls.add_method('GetBssid', + 'ns3::Mac48Address', + [], + is_const=True, is_virtual=True) ## nqap-wifi-mac.h: void ns3::NqapWifiMac::SetAddress(ns3::Mac48Address address) [member function] - cls.add_method('SetAddress', 'void', [param('ns3::Mac48Address', 'address')], is_virtual=True) + cls.add_method('SetAddress', + 'void', + [param('ns3::Mac48Address', 'address')], + is_virtual=True) ## nqap-wifi-mac.h: void ns3::NqapWifiMac::SetSsid(ns3::Ssid ssid) [member function] - cls.add_method('SetSsid', 'void', [param('ns3::Ssid', 'ssid')], is_virtual=True) + cls.add_method('SetSsid', + 'void', + [param('ns3::Ssid', 'ssid')], + is_virtual=True) ## nqap-wifi-mac.h: void ns3::NqapWifiMac::SetBeaconInterval(ns3::Time interval) [member function] - cls.add_method('SetBeaconInterval', 'void', [param('ns3::Time', 'interval')]) + cls.add_method('SetBeaconInterval', + 'void', + [param('ns3::Time', 'interval')]) ## nqap-wifi-mac.h: ns3::Time ns3::NqapWifiMac::GetBeaconInterval() const [member function] - cls.add_method('GetBeaconInterval', 'ns3::Time', [], is_const=True) + cls.add_method('GetBeaconInterval', + 'ns3::Time', + [], + is_const=True) ## nqap-wifi-mac.h: void ns3::NqapWifiMac::StartBeaconing() [member function] - cls.add_method('StartBeaconing', 'void', []) + cls.add_method('StartBeaconing', + 'void', + []) ## nqap-wifi-mac.h: void ns3::NqapWifiMac::DoDispose() [member function] - cls.add_method('DoDispose', 'void', [], visibility='private', is_virtual=True) + cls.add_method('DoDispose', + 'void', + [], + visibility='private', is_virtual=True) return def register_Ns3AmrrWifiRemoteStation_methods(root_module, cls): ## amrr-wifi-manager.h: ns3::AmrrWifiRemoteStation::AmrrWifiRemoteStation(ns3::Ptr stations) [constructor] - cls.add_constructor([param('ns3::Ptr< ns3::AmrrWifiManager >', 'stations')], visibility='public') + cls.add_constructor([param('ns3::Ptr< ns3::AmrrWifiManager >', 'stations')]) ## amrr-wifi-manager.h: void ns3::AmrrWifiRemoteStation::DoReportRxOk(double rxSnr, ns3::WifiMode txMode) [member function] - cls.add_method('DoReportRxOk', 'void', [param('double', 'rxSnr'), param('ns3::WifiMode', 'txMode')], visibility='protected', is_virtual=True) + cls.add_method('DoReportRxOk', + 'void', + [param('double', 'rxSnr'), param('ns3::WifiMode', 'txMode')], + visibility='protected', is_virtual=True) ## amrr-wifi-manager.h: void ns3::AmrrWifiRemoteStation::DoReportRtsFailed() [member function] - cls.add_method('DoReportRtsFailed', 'void', [], visibility='protected', is_virtual=True) + cls.add_method('DoReportRtsFailed', + 'void', + [], + visibility='protected', is_virtual=True) ## amrr-wifi-manager.h: void ns3::AmrrWifiRemoteStation::DoReportDataFailed() [member function] - cls.add_method('DoReportDataFailed', 'void', [], visibility='protected', is_virtual=True) + cls.add_method('DoReportDataFailed', + 'void', + [], + visibility='protected', is_virtual=True) ## amrr-wifi-manager.h: void ns3::AmrrWifiRemoteStation::DoReportRtsOk(double ctsSnr, ns3::WifiMode ctsMode, double rtsSnr) [member function] - cls.add_method('DoReportRtsOk', 'void', [param('double', 'ctsSnr'), param('ns3::WifiMode', 'ctsMode'), param('double', 'rtsSnr')], visibility='protected', is_virtual=True) + cls.add_method('DoReportRtsOk', + 'void', + [param('double', 'ctsSnr'), param('ns3::WifiMode', 'ctsMode'), param('double', 'rtsSnr')], + visibility='protected', is_virtual=True) ## amrr-wifi-manager.h: void ns3::AmrrWifiRemoteStation::DoReportDataOk(double ackSnr, ns3::WifiMode ackMode, double dataSnr) [member function] - cls.add_method('DoReportDataOk', 'void', [param('double', 'ackSnr'), param('ns3::WifiMode', 'ackMode'), param('double', 'dataSnr')], visibility='protected', is_virtual=True) + cls.add_method('DoReportDataOk', + 'void', + [param('double', 'ackSnr'), param('ns3::WifiMode', 'ackMode'), param('double', 'dataSnr')], + visibility='protected', is_virtual=True) ## amrr-wifi-manager.h: void ns3::AmrrWifiRemoteStation::DoReportFinalRtsFailed() [member function] - cls.add_method('DoReportFinalRtsFailed', 'void', [], visibility='protected', is_virtual=True) + cls.add_method('DoReportFinalRtsFailed', + 'void', + [], + visibility='protected', is_virtual=True) ## amrr-wifi-manager.h: void ns3::AmrrWifiRemoteStation::DoReportFinalDataFailed() [member function] - cls.add_method('DoReportFinalDataFailed', 'void', [], visibility='protected', is_virtual=True) + cls.add_method('DoReportFinalDataFailed', + 'void', + [], + visibility='protected', is_virtual=True) ## amrr-wifi-manager.h: ns3::Ptr ns3::AmrrWifiRemoteStation::GetManager() const [member function] - cls.add_method('GetManager', 'ns3::Ptr< ns3::WifiRemoteStationManager >', [], is_const=True, visibility='private', is_virtual=True) + cls.add_method('GetManager', + 'ns3::Ptr< ns3::WifiRemoteStationManager >', + [], + is_const=True, visibility='private', is_virtual=True) ## amrr-wifi-manager.h: ns3::WifiMode ns3::AmrrWifiRemoteStation::DoGetDataMode(uint32_t size) [member function] - cls.add_method('DoGetDataMode', 'ns3::WifiMode', [param('uint32_t', 'size')], visibility='private', is_virtual=True) + cls.add_method('DoGetDataMode', + 'ns3::WifiMode', + [param('uint32_t', 'size')], + visibility='private', is_virtual=True) ## amrr-wifi-manager.h: ns3::WifiMode ns3::AmrrWifiRemoteStation::DoGetRtsMode() [member function] - cls.add_method('DoGetRtsMode', 'ns3::WifiMode', [], visibility='private', is_virtual=True) + cls.add_method('DoGetRtsMode', + 'ns3::WifiMode', + [], + visibility='private', is_virtual=True) return def register_Ns3CompositePropagationLossModel_methods(root_module, cls): ## composite-propagation-loss-model.h: static ns3::TypeId ns3::CompositePropagationLossModel::GetTypeId() [member function] - cls.add_method('GetTypeId', 'ns3::TypeId', [], is_static=True) + cls.add_method('GetTypeId', + 'ns3::TypeId', + [], + is_static=True) ## composite-propagation-loss-model.h: ns3::CompositePropagationLossModel::CompositePropagationLossModel() [constructor] - cls.add_constructor([], visibility='public') + cls.add_constructor([]) ## composite-propagation-loss-model.h: double ns3::CompositePropagationLossModel::GetLoss(ns3::Ptr a, ns3::Ptr b) const [member function] - cls.add_method('GetLoss', 'double', [param('ns3::Ptr< ns3::MobilityModel >', 'a'), param('ns3::Ptr< ns3::MobilityModel >', 'b')], is_const=True, is_virtual=True) + cls.add_method('GetLoss', + 'double', + [param('ns3::Ptr< ns3::MobilityModel >', 'a'), param('ns3::Ptr< ns3::MobilityModel >', 'b')], + is_const=True, is_virtual=True) ## composite-propagation-loss-model.h: void ns3::CompositePropagationLossModel::AddPropagationLossModel(ns3::Ptr pl) [member function] - cls.add_method('AddPropagationLossModel', 'void', [param('ns3::Ptr< ns3::PropagationLossModel >', 'pl')]) + cls.add_method('AddPropagationLossModel', + 'void', + [param('ns3::Ptr< ns3::PropagationLossModel >', 'pl')]) ## composite-propagation-loss-model.h: void ns3::CompositePropagationLossModel::AddDefaults() [member function] - cls.add_method('AddDefaults', 'void', [], visibility='protected', is_virtual=True) + cls.add_method('AddDefaults', + 'void', + [], + visibility='protected', is_virtual=True) return def register_Ns3FriisPropagationLossModel_methods(root_module, cls): ## propagation-loss-model.h: static ns3::TypeId ns3::FriisPropagationLossModel::GetTypeId() [member function] - cls.add_method('GetTypeId', 'ns3::TypeId', [], is_static=True) + cls.add_method('GetTypeId', + 'ns3::TypeId', + [], + is_static=True) ## propagation-loss-model.h: ns3::FriisPropagationLossModel::FriisPropagationLossModel() [constructor] - cls.add_constructor([], visibility='public') + cls.add_constructor([]) ## propagation-loss-model.h: void ns3::FriisPropagationLossModel::SetLambda(double frequency, double speed) [member function] - cls.add_method('SetLambda', 'void', [param('double', 'frequency'), param('double', 'speed')]) + cls.add_method('SetLambda', + 'void', + [param('double', 'frequency'), param('double', 'speed')]) ## propagation-loss-model.h: void ns3::FriisPropagationLossModel::SetLambda(double lambda) [member function] - cls.add_method('SetLambda', 'void', [param('double', 'lambda')]) + cls.add_method('SetLambda', + 'void', + [param('double', 'lambda')]) ## propagation-loss-model.h: void ns3::FriisPropagationLossModel::SetSystemLoss(double systemLoss) [member function] - cls.add_method('SetSystemLoss', 'void', [param('double', 'systemLoss')]) + cls.add_method('SetSystemLoss', + 'void', + [param('double', 'systemLoss')]) ## propagation-loss-model.h: void ns3::FriisPropagationLossModel::SetMinDistance(double minDistance) [member function] - cls.add_method('SetMinDistance', 'void', [param('double', 'minDistance')]) + cls.add_method('SetMinDistance', + 'void', + [param('double', 'minDistance')]) ## propagation-loss-model.h: double ns3::FriisPropagationLossModel::GetMinDistance() const [member function] - cls.add_method('GetMinDistance', 'double', [], is_const=True) + cls.add_method('GetMinDistance', + 'double', + [], + is_const=True) ## propagation-loss-model.h: double ns3::FriisPropagationLossModel::GetLambda() const [member function] - cls.add_method('GetLambda', 'double', [], is_const=True) + cls.add_method('GetLambda', + 'double', + [], + is_const=True) ## propagation-loss-model.h: double ns3::FriisPropagationLossModel::GetSystemLoss() const [member function] - cls.add_method('GetSystemLoss', 'double', [], is_const=True) + cls.add_method('GetSystemLoss', + 'double', + [], + is_const=True) ## propagation-loss-model.h: double ns3::FriisPropagationLossModel::GetLoss(ns3::Ptr a, ns3::Ptr b) const [member function] - cls.add_method('GetLoss', 'double', [param('ns3::Ptr< ns3::MobilityModel >', 'a'), param('ns3::Ptr< ns3::MobilityModel >', 'b')], is_const=True, is_virtual=True) + cls.add_method('GetLoss', + 'double', + [param('ns3::Ptr< ns3::MobilityModel >', 'a'), param('ns3::Ptr< ns3::MobilityModel >', 'b')], + is_const=True, is_virtual=True) return def register_Ns3WifiRemoteStationManager_methods(root_module, cls): ## wifi-remote-station-manager.h: static ns3::TypeId ns3::WifiRemoteStationManager::GetTypeId() [member function] - cls.add_method('GetTypeId', 'ns3::TypeId', [], is_static=True) + cls.add_method('GetTypeId', + 'ns3::TypeId', + [], + is_static=True) ## wifi-remote-station-manager.h: ns3::WifiRemoteStationManager::WifiRemoteStationManager() [constructor] - cls.add_constructor([], visibility='public') + cls.add_constructor([]) ## wifi-remote-station-manager.h: void ns3::WifiRemoteStationManager::SetupPhy(ns3::Ptr phy) [member function] - cls.add_method('SetupPhy', 'void', [param('ns3::Ptr< ns3::WifiPhy >', 'phy')], is_virtual=True) + cls.add_method('SetupPhy', + 'void', + [param('ns3::Ptr< ns3::WifiPhy >', 'phy')], + is_virtual=True) ## wifi-remote-station-manager.h: uint32_t ns3::WifiRemoteStationManager::GetMaxSsrc() const [member function] - cls.add_method('GetMaxSsrc', 'uint32_t', [], is_const=True) + cls.add_method('GetMaxSsrc', + 'uint32_t', + [], + is_const=True) ## wifi-remote-station-manager.h: uint32_t ns3::WifiRemoteStationManager::GetMaxSlrc() const [member function] - cls.add_method('GetMaxSlrc', 'uint32_t', [], is_const=True) + cls.add_method('GetMaxSlrc', + 'uint32_t', + [], + is_const=True) ## wifi-remote-station-manager.h: uint32_t ns3::WifiRemoteStationManager::GetRtsCtsThreshold() const [member function] - cls.add_method('GetRtsCtsThreshold', 'uint32_t', [], is_const=True) + cls.add_method('GetRtsCtsThreshold', + 'uint32_t', + [], + is_const=True) ## wifi-remote-station-manager.h: uint32_t ns3::WifiRemoteStationManager::GetFragmentationThreshold() const [member function] - cls.add_method('GetFragmentationThreshold', 'uint32_t', [], is_const=True) + cls.add_method('GetFragmentationThreshold', + 'uint32_t', + [], + is_const=True) ## wifi-remote-station-manager.h: void ns3::WifiRemoteStationManager::SetMaxSsrc(uint32_t maxSsrc) [member function] - cls.add_method('SetMaxSsrc', 'void', [param('uint32_t', 'maxSsrc')]) + cls.add_method('SetMaxSsrc', + 'void', + [param('uint32_t', 'maxSsrc')]) ## wifi-remote-station-manager.h: void ns3::WifiRemoteStationManager::SetMaxSlrc(uint32_t maxSlrc) [member function] - cls.add_method('SetMaxSlrc', 'void', [param('uint32_t', 'maxSlrc')]) + cls.add_method('SetMaxSlrc', + 'void', + [param('uint32_t', 'maxSlrc')]) ## wifi-remote-station-manager.h: void ns3::WifiRemoteStationManager::SetRtsCtsThreshold(uint32_t threshold) [member function] - cls.add_method('SetRtsCtsThreshold', 'void', [param('uint32_t', 'threshold')]) + cls.add_method('SetRtsCtsThreshold', + 'void', + [param('uint32_t', 'threshold')]) ## wifi-remote-station-manager.h: void ns3::WifiRemoteStationManager::SetFragmentationThreshold(uint32_t threshold) [member function] - cls.add_method('SetFragmentationThreshold', 'void', [param('uint32_t', 'threshold')]) + cls.add_method('SetFragmentationThreshold', + 'void', + [param('uint32_t', 'threshold')]) ## wifi-remote-station-manager.h: void ns3::WifiRemoteStationManager::Reset() [member function] - cls.add_method('Reset', 'void', []) + cls.add_method('Reset', + 'void', + []) ## wifi-remote-station-manager.h: void ns3::WifiRemoteStationManager::AddBasicMode(ns3::WifiMode mode) [member function] - cls.add_method('AddBasicMode', 'void', [param('ns3::WifiMode', 'mode')]) + cls.add_method('AddBasicMode', + 'void', + [param('ns3::WifiMode', 'mode')]) ## wifi-remote-station-manager.h: ns3::WifiMode ns3::WifiRemoteStationManager::GetDefaultMode() const [member function] - cls.add_method('GetDefaultMode', 'ns3::WifiMode', [], is_const=True) + cls.add_method('GetDefaultMode', + 'ns3::WifiMode', + [], + is_const=True) ## wifi-remote-station-manager.h: uint32_t ns3::WifiRemoteStationManager::GetNBasicModes() const [member function] - cls.add_method('GetNBasicModes', 'uint32_t', [], is_const=True) + cls.add_method('GetNBasicModes', + 'uint32_t', + [], + is_const=True) ## wifi-remote-station-manager.h: ns3::WifiMode ns3::WifiRemoteStationManager::GetBasicMode(uint32_t i) const [member function] - cls.add_method('GetBasicMode', 'ns3::WifiMode', [param('uint32_t', 'i')], is_const=True) + cls.add_method('GetBasicMode', + 'ns3::WifiMode', + [param('uint32_t', 'i')], + is_const=True) ## wifi-remote-station-manager.h: __gnu_cxx::__normal_iterator > > ns3::WifiRemoteStationManager::BeginBasicModes() const [member function] - cls.add_method('BeginBasicModes', '__gnu_cxx::__normal_iterator< const ns3::WifiMode*, std::vector< ns3::WifiMode, std::allocator< ns3::WifiMode > > >', [], is_const=True) + cls.add_method('BeginBasicModes', + '__gnu_cxx::__normal_iterator< const ns3::WifiMode*, std::vector< ns3::WifiMode, std::allocator< ns3::WifiMode > > >', + [], + is_const=True) ## wifi-remote-station-manager.h: __gnu_cxx::__normal_iterator > > ns3::WifiRemoteStationManager::EndBasicModes() const [member function] - cls.add_method('EndBasicModes', '__gnu_cxx::__normal_iterator< const ns3::WifiMode*, std::vector< ns3::WifiMode, std::allocator< ns3::WifiMode > > >', [], is_const=True) + cls.add_method('EndBasicModes', + '__gnu_cxx::__normal_iterator< const ns3::WifiMode*, std::vector< ns3::WifiMode, std::allocator< ns3::WifiMode > > >', + [], + is_const=True) ## wifi-remote-station-manager.h: bool ns3::WifiRemoteStationManager::IsLowLatency() const [member function] - cls.add_method('IsLowLatency', 'bool', [], is_const=True) + cls.add_method('IsLowLatency', + 'bool', + [], + is_const=True) ## wifi-remote-station-manager.h: ns3::WifiRemoteStation * ns3::WifiRemoteStationManager::Lookup(ns3::Mac48Address address) [member function] - cls.add_method('Lookup', 'ns3::WifiRemoteStation *', [param('ns3::Mac48Address', 'address')]) + cls.add_method('Lookup', + 'ns3::WifiRemoteStation *', + [param('ns3::Mac48Address', 'address')]) ## wifi-remote-station-manager.h: ns3::WifiRemoteStation * ns3::WifiRemoteStationManager::LookupNonUnicast() [member function] - cls.add_method('LookupNonUnicast', 'ns3::WifiRemoteStation *', []) + cls.add_method('LookupNonUnicast', + 'ns3::WifiRemoteStation *', + []) ## wifi-remote-station-manager.h: void ns3::WifiRemoteStationManager::DoDispose() [member function] - cls.add_method('DoDispose', 'void', [], visibility='protected', is_virtual=True) + cls.add_method('DoDispose', + 'void', + [], + visibility='protected', is_virtual=True) ## wifi-remote-station-manager.h: ns3::WifiRemoteStation * ns3::WifiRemoteStationManager::CreateStation() [member function] - cls.add_method('CreateStation', 'ns3::WifiRemoteStation *', [], is_pure_virtual=True, visibility='private', is_virtual=True) + cls.add_method('CreateStation', + 'ns3::WifiRemoteStation *', + [], + is_pure_virtual=True, visibility='private', is_virtual=True) return def register_Ns3WifiModeValue_methods(root_module, cls): ## wifi-mode.h: ns3::WifiModeValue::WifiModeValue() [constructor] - cls.add_constructor([], visibility='public') + cls.add_constructor([]) ## wifi-mode.h: ns3::WifiModeValue::WifiModeValue(ns3::WifiMode const & value) [constructor] - cls.add_constructor([param('ns3::WifiMode&', 'value', is_const=True)], visibility='public') + cls.add_constructor([param('ns3::WifiMode&', 'value', is_const=True)]) ## wifi-mode.h: void ns3::WifiModeValue::Set(ns3::WifiMode const & value) [member function] - cls.add_method('Set', 'void', [param('ns3::WifiMode&', 'value', is_const=True)]) + cls.add_method('Set', + 'void', + [param('ns3::WifiMode&', 'value', is_const=True)]) ## wifi-mode.h: ns3::WifiMode ns3::WifiModeValue::Get() const [member function] - cls.add_method('Get', 'ns3::WifiMode', [], is_const=True) + cls.add_method('Get', + 'ns3::WifiMode', + [], + is_const=True) ## wifi-mode.h: ns3::Ptr ns3::WifiModeValue::Copy() const [member function] - cls.add_method('Copy', 'ns3::Ptr< ns3::AttributeValue >', [], is_const=True, is_virtual=True) + cls.add_method('Copy', + 'ns3::Ptr< ns3::AttributeValue >', + [], + is_const=True, is_virtual=True) ## wifi-mode.h: std::string ns3::WifiModeValue::SerializeToString(ns3::Ptr checker) const [member function] - cls.add_method('SerializeToString', 'std::string', [param('ns3::Ptr< ns3::AttributeChecker const >', 'checker')], is_const=True, is_virtual=True) + cls.add_method('SerializeToString', + 'std::string', + [param('ns3::Ptr< ns3::AttributeChecker const >', 'checker')], + is_const=True, is_virtual=True) ## wifi-mode.h: bool ns3::WifiModeValue::DeserializeFromString(std::string value, ns3::Ptr checker) [member function] - cls.add_method('DeserializeFromString', 'bool', [param('std::string', 'value'), param('ns3::Ptr< ns3::AttributeChecker const >', 'checker')], is_virtual=True) + cls.add_method('DeserializeFromString', + 'bool', + [param('std::string', 'value'), param('ns3::Ptr< ns3::AttributeChecker const >', 'checker')], + is_virtual=True) return def register_Ns3OnoeWifiManager_methods(root_module, cls): ## onoe-wifi-manager.h: static ns3::TypeId ns3::OnoeWifiManager::GetTypeId() [member function] - cls.add_method('GetTypeId', 'ns3::TypeId', [], is_static=True) + cls.add_method('GetTypeId', + 'ns3::TypeId', + [], + is_static=True) ## onoe-wifi-manager.h: ns3::OnoeWifiManager::OnoeWifiManager() [constructor] - cls.add_constructor([], visibility='public') + cls.add_constructor([]) ## onoe-wifi-manager.h: ns3::WifiRemoteStation * ns3::OnoeWifiManager::CreateStation() [member function] - cls.add_method('CreateStation', 'ns3::WifiRemoteStation *', [], visibility='private', is_virtual=True) + cls.add_method('CreateStation', + 'ns3::WifiRemoteStation *', + [], + visibility='private', is_virtual=True) return def register_Ns3WifiPhy_methods(root_module, cls): ## wifi-phy.h: static ns3::TypeId ns3::WifiPhy::GetTypeId() [member function] - cls.add_method('GetTypeId', 'ns3::TypeId', [], is_static=True) + cls.add_method('GetTypeId', + 'ns3::TypeId', + [], + is_static=True) ## wifi-phy.h: ns3::WifiPhy::WifiPhy() [constructor] - cls.add_constructor([], visibility='public') + cls.add_constructor([]) ## wifi-phy.h: void ns3::WifiPhy::SetStandard(ns3::WifiPhyStandard standard) [member function] - cls.add_method('SetStandard', 'void', [param('ns3::WifiPhyStandard', 'standard')]) + cls.add_method('SetStandard', + 'void', + [param('ns3::WifiPhyStandard', 'standard')]) ## wifi-phy.h: void ns3::WifiPhy::SetRxNoise(double ratio) [member function] - cls.add_method('SetRxNoise', 'void', [param('double', 'ratio')]) + cls.add_method('SetRxNoise', + 'void', + [param('double', 'ratio')]) ## wifi-phy.h: void ns3::WifiPhy::SetTxPowerStart(double start) [member function] - cls.add_method('SetTxPowerStart', 'void', [param('double', 'start')]) + cls.add_method('SetTxPowerStart', + 'void', + [param('double', 'start')]) ## wifi-phy.h: void ns3::WifiPhy::SetTxPowerEnd(double end) [member function] - cls.add_method('SetTxPowerEnd', 'void', [param('double', 'end')]) + cls.add_method('SetTxPowerEnd', + 'void', + [param('double', 'end')]) ## wifi-phy.h: void ns3::WifiPhy::SetNTxPower(uint32_t n) [member function] - cls.add_method('SetNTxPower', 'void', [param('uint32_t', 'n')]) + cls.add_method('SetNTxPower', + 'void', + [param('uint32_t', 'n')]) ## wifi-phy.h: void ns3::WifiPhy::SetTxGain(double gain) [member function] - cls.add_method('SetTxGain', 'void', [param('double', 'gain')]) + cls.add_method('SetTxGain', + 'void', + [param('double', 'gain')]) ## wifi-phy.h: void ns3::WifiPhy::SetRxGain(double gain) [member function] - cls.add_method('SetRxGain', 'void', [param('double', 'gain')]) + cls.add_method('SetRxGain', + 'void', + [param('double', 'gain')]) ## wifi-phy.h: void ns3::WifiPhy::SetEdThreshold(double threshold) [member function] - cls.add_method('SetEdThreshold', 'void', [param('double', 'threshold')]) + cls.add_method('SetEdThreshold', + 'void', + [param('double', 'threshold')]) ## wifi-phy.h: double ns3::WifiPhy::GetRxNoise() const [member function] - cls.add_method('GetRxNoise', 'double', [], is_const=True) + cls.add_method('GetRxNoise', + 'double', + [], + is_const=True) ## wifi-phy.h: double ns3::WifiPhy::GetTxPowerStart() const [member function] - cls.add_method('GetTxPowerStart', 'double', [], is_const=True) + cls.add_method('GetTxPowerStart', + 'double', + [], + is_const=True) ## wifi-phy.h: double ns3::WifiPhy::GetTxPowerEnd() const [member function] - cls.add_method('GetTxPowerEnd', 'double', [], is_const=True) + cls.add_method('GetTxPowerEnd', + 'double', + [], + is_const=True) ## wifi-phy.h: uint32_t ns3::WifiPhy::GetNTxPower() const [member function] - cls.add_method('GetNTxPower', 'uint32_t', [], is_const=True) + cls.add_method('GetNTxPower', + 'uint32_t', + [], + is_const=True) ## wifi-phy.h: double ns3::WifiPhy::GetTxGain() const [member function] - cls.add_method('GetTxGain', 'double', [], is_const=True) + cls.add_method('GetTxGain', + 'double', + [], + is_const=True) ## wifi-phy.h: double ns3::WifiPhy::GetRxGain() const [member function] - cls.add_method('GetRxGain', 'double', [], is_const=True) + cls.add_method('GetRxGain', + 'double', + [], + is_const=True) ## wifi-phy.h: double ns3::WifiPhy::GetEdThreshold() const [member function] - cls.add_method('GetEdThreshold', 'double', [], is_const=True) + cls.add_method('GetEdThreshold', + 'double', + [], + is_const=True) ## wifi-phy.h: void ns3::WifiPhy::SetChannel(ns3::Ptr channel) [member function] - cls.add_method('SetChannel', 'void', [param('ns3::Ptr< ns3::WifiChannel >', 'channel')]) + cls.add_method('SetChannel', + 'void', + [param('ns3::Ptr< ns3::WifiChannel >', 'channel')]) ## wifi-phy.h: void ns3::WifiPhy::SetReceiveOkCallback(ns3::Callback, double, ns3::WifiMode, ns3::WifiPreamble, ns3::empty, ns3::empty> callback) [member function] - cls.add_method('SetReceiveOkCallback', 'void', [param('ns3::Callback< void, ns3::Ptr< ns3::Packet >, double, ns3::WifiMode, ns3::WifiPreamble, ns3::empty, ns3::empty >', 'callback')]) + cls.add_method('SetReceiveOkCallback', + 'void', + [param('ns3::Callback< void, ns3::Ptr< ns3::Packet >, double, ns3::WifiMode, ns3::WifiPreamble, ns3::empty, ns3::empty >', 'callback')]) ## wifi-phy.h: void ns3::WifiPhy::SetReceiveErrorCallback(ns3::Callback, double, ns3::empty, ns3::empty, ns3::empty, ns3::empty> callback) [member function] - cls.add_method('SetReceiveErrorCallback', 'void', [param('ns3::Callback< void, ns3::Ptr< ns3::Packet >, double, ns3::empty, ns3::empty, ns3::empty, ns3::empty >', 'callback')]) + cls.add_method('SetReceiveErrorCallback', + 'void', + [param('ns3::Callback< void, ns3::Ptr< ns3::Packet >, double, ns3::empty, ns3::empty, ns3::empty, ns3::empty >', 'callback')]) ## wifi-phy.h: void ns3::WifiPhy::SendPacket(ns3::Ptr packet, ns3::WifiMode mode, ns3::WifiPreamble preamble, uint8_t txPowerLevel) [member function] - cls.add_method('SendPacket', 'void', [param('ns3::Ptr< const ns3::Packet >', 'packet'), param('ns3::WifiMode', 'mode'), param('ns3::WifiPreamble', 'preamble'), param('uint8_t', 'txPowerLevel')]) + cls.add_method('SendPacket', + 'void', + [param('ns3::Ptr< const ns3::Packet >', 'packet'), param('ns3::WifiMode', 'mode'), param('ns3::WifiPreamble', 'preamble'), param('uint8_t', 'txPowerLevel')]) ## wifi-phy.h: void ns3::WifiPhy::RegisterListener(ns3::WifiPhyListener * listener) [member function] - cls.add_method('RegisterListener', 'void', [param('ns3::WifiPhyListener *', 'listener')]) + cls.add_method('RegisterListener', + 'void', + [param('ns3::WifiPhyListener *', 'listener')]) ## wifi-phy.h: bool ns3::WifiPhy::IsStateCcaBusy() [member function] - cls.add_method('IsStateCcaBusy', 'bool', []) + cls.add_method('IsStateCcaBusy', + 'bool', + []) ## wifi-phy.h: bool ns3::WifiPhy::IsStateIdle() [member function] - cls.add_method('IsStateIdle', 'bool', []) + cls.add_method('IsStateIdle', + 'bool', + []) ## wifi-phy.h: bool ns3::WifiPhy::IsStateBusy() [member function] - cls.add_method('IsStateBusy', 'bool', []) + cls.add_method('IsStateBusy', + 'bool', + []) ## wifi-phy.h: bool ns3::WifiPhy::IsStateSync() [member function] - cls.add_method('IsStateSync', 'bool', []) + cls.add_method('IsStateSync', + 'bool', + []) ## wifi-phy.h: bool ns3::WifiPhy::IsStateTx() [member function] - cls.add_method('IsStateTx', 'bool', []) + cls.add_method('IsStateTx', + 'bool', + []) ## wifi-phy.h: ns3::Time ns3::WifiPhy::GetStateDuration() [member function] - cls.add_method('GetStateDuration', 'ns3::Time', []) + cls.add_method('GetStateDuration', + 'ns3::Time', + []) ## wifi-phy.h: ns3::Time ns3::WifiPhy::GetDelayUntilIdle() [member function] - cls.add_method('GetDelayUntilIdle', 'ns3::Time', []) + cls.add_method('GetDelayUntilIdle', + 'ns3::Time', + []) ## wifi-phy.h: ns3::Time ns3::WifiPhy::GetLastRxStartTime() const [member function] - cls.add_method('GetLastRxStartTime', 'ns3::Time', [], is_const=True) + cls.add_method('GetLastRxStartTime', + 'ns3::Time', + [], + is_const=True) ## wifi-phy.h: ns3::Time ns3::WifiPhy::CalculateTxDuration(uint32_t size, ns3::WifiMode payloadMode, ns3::WifiPreamble preamble) const [member function] - cls.add_method('CalculateTxDuration', 'ns3::Time', [param('uint32_t', 'size'), param('ns3::WifiMode', 'payloadMode'), param('ns3::WifiPreamble', 'preamble')], is_const=True) + cls.add_method('CalculateTxDuration', + 'ns3::Time', + [param('uint32_t', 'size'), param('ns3::WifiMode', 'payloadMode'), param('ns3::WifiPreamble', 'preamble')], + is_const=True) ## wifi-phy.h: uint32_t ns3::WifiPhy::GetNModes() const [member function] - cls.add_method('GetNModes', 'uint32_t', [], is_const=True) + cls.add_method('GetNModes', + 'uint32_t', + [], + is_const=True) ## wifi-phy.h: ns3::WifiMode ns3::WifiPhy::GetMode(uint32_t mode) const [member function] - cls.add_method('GetMode', 'ns3::WifiMode', [param('uint32_t', 'mode')], is_const=True) + cls.add_method('GetMode', + 'ns3::WifiMode', + [param('uint32_t', 'mode')], + is_const=True) ## wifi-phy.h: double ns3::WifiPhy::CalculateSnr(ns3::WifiMode txMode, double ber) const [member function] - cls.add_method('CalculateSnr', 'double', [param('ns3::WifiMode', 'txMode'), param('double', 'ber')], is_const=True) + cls.add_method('CalculateSnr', + 'double', + [param('ns3::WifiMode', 'txMode'), param('double', 'ber')], + is_const=True) ## wifi-phy.h: void ns3::WifiPhy::StartReceivePacket(ns3::Ptr packet, double rxPowerDbm, ns3::WifiMode mode, ns3::WifiPreamble preamble) [member function] - cls.add_method('StartReceivePacket', 'void', [param('ns3::Ptr< ns3::Packet >', 'packet'), param('double', 'rxPowerDbm'), param('ns3::WifiMode', 'mode'), param('ns3::WifiPreamble', 'preamble')]) + cls.add_method('StartReceivePacket', + 'void', + [param('ns3::Ptr< ns3::Packet >', 'packet'), param('double', 'rxPowerDbm'), param('ns3::WifiMode', 'mode'), param('ns3::WifiPreamble', 'preamble')]) ## wifi-phy.h: ns3::Ptr ns3::WifiPhy::GetChannel() const [member function] - cls.add_method('GetChannel', 'ns3::Ptr< ns3::WifiChannel >', [], is_const=True) + cls.add_method('GetChannel', + 'ns3::Ptr< ns3::WifiChannel >', + [], + is_const=True) ## wifi-phy.h: void ns3::WifiPhy::DoDispose() [member function] - cls.add_method('DoDispose', 'void', [], visibility='private', is_virtual=True) + cls.add_method('DoDispose', + 'void', + [], + visibility='private', is_virtual=True) return def register_Ns3WifiChannel_methods(root_module, cls): ## wifi-channel.h: static ns3::TypeId ns3::WifiChannel::GetTypeId() [member function] - cls.add_method('GetTypeId', 'ns3::TypeId', [], is_static=True) + cls.add_method('GetTypeId', + 'ns3::TypeId', + [], + is_static=True) ## wifi-channel.h: ns3::WifiChannel::WifiChannel() [constructor] - cls.add_constructor([], visibility='public') + cls.add_constructor([]) ## wifi-channel.h: uint32_t ns3::WifiChannel::GetNDevices() const [member function] - cls.add_method('GetNDevices', 'uint32_t', [], is_const=True, is_virtual=True) + cls.add_method('GetNDevices', + 'uint32_t', + [], + is_const=True, is_virtual=True) ## wifi-channel.h: ns3::Ptr ns3::WifiChannel::GetDevice(uint32_t i) const [member function] - cls.add_method('GetDevice', 'ns3::Ptr< ns3::NetDevice >', [param('uint32_t', 'i')], is_const=True, is_virtual=True) + cls.add_method('GetDevice', + 'ns3::Ptr< ns3::NetDevice >', + [param('uint32_t', 'i')], + is_const=True, is_virtual=True) ## wifi-channel.h: void ns3::WifiChannel::SetPropagationLossModel(ns3::Ptr loss) [member function] - cls.add_method('SetPropagationLossModel', 'void', [param('ns3::Ptr< ns3::PropagationLossModel >', 'loss')]) + cls.add_method('SetPropagationLossModel', + 'void', + [param('ns3::Ptr< ns3::PropagationLossModel >', 'loss')]) ## wifi-channel.h: void ns3::WifiChannel::SetPropagationDelayModel(ns3::Ptr delay) [member function] - cls.add_method('SetPropagationDelayModel', 'void', [param('ns3::Ptr< ns3::PropagationDelayModel >', 'delay')]) + cls.add_method('SetPropagationDelayModel', + 'void', + [param('ns3::Ptr< ns3::PropagationDelayModel >', 'delay')]) ## wifi-channel.h: void ns3::WifiChannel::Add(ns3::Ptr device, ns3::Ptr phy) [member function] - cls.add_method('Add', 'void', [param('ns3::Ptr< ns3::NetDevice >', 'device'), param('ns3::Ptr< ns3::WifiPhy >', 'phy')]) + cls.add_method('Add', + 'void', + [param('ns3::Ptr< ns3::NetDevice >', 'device'), param('ns3::Ptr< ns3::WifiPhy >', 'phy')]) ## wifi-channel.h: void ns3::WifiChannel::Send(ns3::Ptr sender, ns3::Ptr packet, double txPowerDbm, ns3::WifiMode wifiMode, ns3::WifiPreamble preamble) const [member function] - cls.add_method('Send', 'void', [param('ns3::Ptr< ns3::WifiPhy >', 'sender'), param('ns3::Ptr< const ns3::Packet >', 'packet'), param('double', 'txPowerDbm'), param('ns3::WifiMode', 'wifiMode'), param('ns3::WifiPreamble', 'preamble')], is_const=True) + cls.add_method('Send', + 'void', + [param('ns3::Ptr< ns3::WifiPhy >', 'sender'), param('ns3::Ptr< const ns3::Packet >', 'packet'), param('double', 'txPowerDbm'), param('ns3::WifiMode', 'wifiMode'), param('ns3::WifiPreamble', 'preamble')], + is_const=True) return def register_Ns3LogDistancePropagationLossModel_methods(root_module, cls): ## propagation-loss-model.h: static ns3::TypeId ns3::LogDistancePropagationLossModel::GetTypeId() [member function] - cls.add_method('GetTypeId', 'ns3::TypeId', [], is_static=True) + cls.add_method('GetTypeId', + 'ns3::TypeId', + [], + is_static=True) ## propagation-loss-model.h: ns3::LogDistancePropagationLossModel::LogDistancePropagationLossModel() [constructor] - cls.add_constructor([], visibility='public') + cls.add_constructor([]) ## propagation-loss-model.h: void ns3::LogDistancePropagationLossModel::SetPathLossExponent(double n) [member function] - cls.add_method('SetPathLossExponent', 'void', [param('double', 'n')]) + cls.add_method('SetPathLossExponent', + 'void', + [param('double', 'n')]) ## propagation-loss-model.h: double ns3::LogDistancePropagationLossModel::GetPathLossExponent() const [member function] - cls.add_method('GetPathLossExponent', 'double', [], is_const=True) + cls.add_method('GetPathLossExponent', + 'double', + [], + is_const=True) ## propagation-loss-model.h: void ns3::LogDistancePropagationLossModel::SetReferenceModel(ns3::Ptr model) [member function] - cls.add_method('SetReferenceModel', 'void', [param('ns3::Ptr< ns3::PropagationLossModel >', 'model')]) + cls.add_method('SetReferenceModel', + 'void', + [param('ns3::Ptr< ns3::PropagationLossModel >', 'model')]) ## propagation-loss-model.h: void ns3::LogDistancePropagationLossModel::SetReferenceDistance(double referenceDistance) [member function] - cls.add_method('SetReferenceDistance', 'void', [param('double', 'referenceDistance')]) + cls.add_method('SetReferenceDistance', + 'void', + [param('double', 'referenceDistance')]) ## propagation-loss-model.h: double ns3::LogDistancePropagationLossModel::GetLoss(ns3::Ptr a, ns3::Ptr b) const [member function] - cls.add_method('GetLoss', 'double', [param('ns3::Ptr< ns3::MobilityModel >', 'a'), param('ns3::Ptr< ns3::MobilityModel >', 'b')], is_const=True, is_virtual=True) + cls.add_method('GetLoss', + 'double', + [param('ns3::Ptr< ns3::MobilityModel >', 'a'), param('ns3::Ptr< ns3::MobilityModel >', 'b')], + is_const=True, is_virtual=True) return def register_Ns3ConstantRateWifiManager_methods(root_module, cls): ## constant-rate-wifi-manager.h: static ns3::TypeId ns3::ConstantRateWifiManager::GetTypeId() [member function] - cls.add_method('GetTypeId', 'ns3::TypeId', [], is_static=True) + cls.add_method('GetTypeId', + 'ns3::TypeId', + [], + is_static=True) ## constant-rate-wifi-manager.h: ns3::ConstantRateWifiManager::ConstantRateWifiManager() [constructor] - cls.add_constructor([], visibility='public') + cls.add_constructor([]) ## constant-rate-wifi-manager.h: ns3::WifiMode ns3::ConstantRateWifiManager::GetDataMode() const [member function] - cls.add_method('GetDataMode', 'ns3::WifiMode', [], is_const=True) + cls.add_method('GetDataMode', + 'ns3::WifiMode', + [], + is_const=True) ## constant-rate-wifi-manager.h: ns3::WifiMode ns3::ConstantRateWifiManager::GetCtlMode() const [member function] - cls.add_method('GetCtlMode', 'ns3::WifiMode', [], is_const=True) + cls.add_method('GetCtlMode', + 'ns3::WifiMode', + [], + is_const=True) ## constant-rate-wifi-manager.h: ns3::WifiRemoteStation * ns3::ConstantRateWifiManager::CreateStation() [member function] - cls.add_method('CreateStation', 'ns3::WifiRemoteStation *', [], visibility='private', is_virtual=True) + cls.add_method('CreateStation', + 'ns3::WifiRemoteStation *', + [], + visibility='private', is_virtual=True) return def register_Ns3AarfWifiRemoteStation_methods(root_module, cls): ## aarf-wifi-manager.h: ns3::AarfWifiRemoteStation::AarfWifiRemoteStation(ns3::Ptr stations, uint32_t minTimerThreshold, uint32_t minSuccessThreshold, double successK, uint32_t maxSuccessThreshold, double timerK) [constructor] - cls.add_constructor([param('ns3::Ptr< ns3::AarfWifiManager >', 'stations'), param('uint32_t', 'minTimerThreshold'), param('uint32_t', 'minSuccessThreshold'), param('double', 'successK'), param('uint32_t', 'maxSuccessThreshold'), param('double', 'timerK')], visibility='public') + cls.add_constructor([param('ns3::Ptr< ns3::AarfWifiManager >', 'stations'), param('uint32_t', 'minTimerThreshold'), param('uint32_t', 'minSuccessThreshold'), param('double', 'successK'), param('uint32_t', 'maxSuccessThreshold'), param('double', 'timerK')]) ## aarf-wifi-manager.h: void ns3::AarfWifiRemoteStation::ReportRecoveryFailure() [member function] - cls.add_method('ReportRecoveryFailure', 'void', [], visibility='private', is_virtual=True) + cls.add_method('ReportRecoveryFailure', + 'void', + [], + visibility='private', is_virtual=True) ## aarf-wifi-manager.h: void ns3::AarfWifiRemoteStation::ReportFailure() [member function] - cls.add_method('ReportFailure', 'void', [], visibility='private', is_virtual=True) + cls.add_method('ReportFailure', + 'void', + [], + visibility='private', is_virtual=True) return def register_Ns3PropagationDelayModel_methods(root_module, cls): ## propagation-delay-model.h: static ns3::TypeId ns3::PropagationDelayModel::GetTypeId() [member function] - cls.add_method('GetTypeId', 'ns3::TypeId', [], is_static=True) + cls.add_method('GetTypeId', + 'ns3::TypeId', + [], + is_static=True) ## propagation-delay-model.h: ns3::Time ns3::PropagationDelayModel::GetDelay(ns3::Ptr a, ns3::Ptr b) const [member function] - cls.add_method('GetDelay', 'ns3::Time', [param('ns3::Ptr< ns3::MobilityModel >', 'a'), param('ns3::Ptr< ns3::MobilityModel >', 'b')], is_pure_virtual=True, is_const=True, is_virtual=True) + cls.add_method('GetDelay', + 'ns3::Time', + [param('ns3::Ptr< ns3::MobilityModel >', 'a'), param('ns3::Ptr< ns3::MobilityModel >', 'b')], + is_pure_virtual=True, is_const=True, is_virtual=True) cls.add_constructor([]) return def register_Ns3AdhocWifiMac_methods(root_module, cls): ## adhoc-wifi-mac.h: static ns3::TypeId ns3::AdhocWifiMac::GetTypeId() [member function] - cls.add_method('GetTypeId', 'ns3::TypeId', [], is_static=True) + cls.add_method('GetTypeId', + 'ns3::TypeId', + [], + is_static=True) ## adhoc-wifi-mac.h: ns3::AdhocWifiMac::AdhocWifiMac() [constructor] - cls.add_constructor([], visibility='public') + cls.add_constructor([]) ## adhoc-wifi-mac.h: void ns3::AdhocWifiMac::SetSlot(ns3::Time slotTime) [member function] - cls.add_method('SetSlot', 'void', [param('ns3::Time', 'slotTime')], is_virtual=True) + cls.add_method('SetSlot', + 'void', + [param('ns3::Time', 'slotTime')], + is_virtual=True) ## adhoc-wifi-mac.h: void ns3::AdhocWifiMac::SetSifs(ns3::Time sifs) [member function] - cls.add_method('SetSifs', 'void', [param('ns3::Time', 'sifs')], is_virtual=True) + cls.add_method('SetSifs', + 'void', + [param('ns3::Time', 'sifs')], + is_virtual=True) ## adhoc-wifi-mac.h: void ns3::AdhocWifiMac::SetEifsNoDifs(ns3::Time eifsNoDifs) [member function] - cls.add_method('SetEifsNoDifs', 'void', [param('ns3::Time', 'eifsNoDifs')], is_virtual=True) + cls.add_method('SetEifsNoDifs', + 'void', + [param('ns3::Time', 'eifsNoDifs')], + is_virtual=True) ## adhoc-wifi-mac.h: ns3::Time ns3::AdhocWifiMac::GetSlot() const [member function] - cls.add_method('GetSlot', 'ns3::Time', [], is_const=True, is_virtual=True) + cls.add_method('GetSlot', + 'ns3::Time', + [], + is_const=True, is_virtual=True) ## adhoc-wifi-mac.h: ns3::Time ns3::AdhocWifiMac::GetSifs() const [member function] - cls.add_method('GetSifs', 'ns3::Time', [], is_const=True, is_virtual=True) + cls.add_method('GetSifs', + 'ns3::Time', + [], + is_const=True, is_virtual=True) ## adhoc-wifi-mac.h: ns3::Time ns3::AdhocWifiMac::GetEifsNoDifs() const [member function] - cls.add_method('GetEifsNoDifs', 'ns3::Time', [], is_const=True, is_virtual=True) + cls.add_method('GetEifsNoDifs', + 'ns3::Time', + [], + is_const=True, is_virtual=True) ## adhoc-wifi-mac.h: void ns3::AdhocWifiMac::SetWifiPhy(ns3::Ptr phy) [member function] - cls.add_method('SetWifiPhy', 'void', [param('ns3::Ptr< ns3::WifiPhy >', 'phy')], is_virtual=True) + cls.add_method('SetWifiPhy', + 'void', + [param('ns3::Ptr< ns3::WifiPhy >', 'phy')], + is_virtual=True) ## adhoc-wifi-mac.h: void ns3::AdhocWifiMac::SetWifiRemoteStationManager(ns3::Ptr stationManager) [member function] - cls.add_method('SetWifiRemoteStationManager', 'void', [param('ns3::Ptr< ns3::WifiRemoteStationManager >', 'stationManager')], is_virtual=True) + cls.add_method('SetWifiRemoteStationManager', + 'void', + [param('ns3::Ptr< ns3::WifiRemoteStationManager >', 'stationManager')], + is_virtual=True) ## adhoc-wifi-mac.h: void ns3::AdhocWifiMac::Enqueue(ns3::Ptr packet, ns3::Mac48Address to) [member function] - cls.add_method('Enqueue', 'void', [param('ns3::Ptr< const ns3::Packet >', 'packet'), param('ns3::Mac48Address', 'to')], is_virtual=True) + cls.add_method('Enqueue', + 'void', + [param('ns3::Ptr< const ns3::Packet >', 'packet'), param('ns3::Mac48Address', 'to')], + is_virtual=True) ## adhoc-wifi-mac.h: void ns3::AdhocWifiMac::SetForwardUpCallback(ns3::Callback, ns3::Mac48Address const&, ns3::empty, ns3::empty, ns3::empty, ns3::empty> upCallback) [member function] - cls.add_method('SetForwardUpCallback', 'void', [param('ns3::Callback< void, ns3::Ptr< ns3::Packet >, ns3::Mac48Address const&, ns3::empty, ns3::empty, ns3::empty, ns3::empty >', 'upCallback')], is_virtual=True) + cls.add_method('SetForwardUpCallback', + 'void', + [param('ns3::Callback< void, ns3::Ptr< ns3::Packet >, ns3::Mac48Address const&, ns3::empty, ns3::empty, ns3::empty, ns3::empty >', 'upCallback')], + is_virtual=True) ## adhoc-wifi-mac.h: void ns3::AdhocWifiMac::SetLinkUpCallback(ns3::Callback linkUp) [member function] - cls.add_method('SetLinkUpCallback', 'void', [param('ns3::Callback< void, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty >', 'linkUp')], is_virtual=True) + cls.add_method('SetLinkUpCallback', + 'void', + [param('ns3::Callback< void, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty >', 'linkUp')], + is_virtual=True) ## adhoc-wifi-mac.h: void ns3::AdhocWifiMac::SetLinkDownCallback(ns3::Callback linkDown) [member function] - cls.add_method('SetLinkDownCallback', 'void', [param('ns3::Callback< void, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty >', 'linkDown')], is_virtual=True) + cls.add_method('SetLinkDownCallback', + 'void', + [param('ns3::Callback< void, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty >', 'linkDown')], + is_virtual=True) ## adhoc-wifi-mac.h: ns3::Mac48Address ns3::AdhocWifiMac::GetAddress() const [member function] - cls.add_method('GetAddress', 'ns3::Mac48Address', [], is_const=True, is_virtual=True) + cls.add_method('GetAddress', + 'ns3::Mac48Address', + [], + is_const=True, is_virtual=True) ## adhoc-wifi-mac.h: ns3::Ssid ns3::AdhocWifiMac::GetSsid() const [member function] - cls.add_method('GetSsid', 'ns3::Ssid', [], is_const=True, is_virtual=True) + cls.add_method('GetSsid', + 'ns3::Ssid', + [], + is_const=True, is_virtual=True) ## adhoc-wifi-mac.h: ns3::Mac48Address ns3::AdhocWifiMac::GetBssid() const [member function] - cls.add_method('GetBssid', 'ns3::Mac48Address', [], is_const=True, is_virtual=True) + cls.add_method('GetBssid', + 'ns3::Mac48Address', + [], + is_const=True, is_virtual=True) ## adhoc-wifi-mac.h: void ns3::AdhocWifiMac::SetAddress(ns3::Mac48Address address) [member function] - cls.add_method('SetAddress', 'void', [param('ns3::Mac48Address', 'address')], is_virtual=True) + cls.add_method('SetAddress', + 'void', + [param('ns3::Mac48Address', 'address')], + is_virtual=True) ## adhoc-wifi-mac.h: void ns3::AdhocWifiMac::SetSsid(ns3::Ssid ssid) [member function] - cls.add_method('SetSsid', 'void', [param('ns3::Ssid', 'ssid')], is_virtual=True) + cls.add_method('SetSsid', + 'void', + [param('ns3::Ssid', 'ssid')], + is_virtual=True) ## adhoc-wifi-mac.h: void ns3::AdhocWifiMac::DoDispose() [member function] - cls.add_method('DoDispose', 'void', [], visibility='private', is_virtual=True) + cls.add_method('DoDispose', + 'void', + [], + visibility='private', is_virtual=True) return def register_Ns3JakesPropagationLossModel_methods(root_module, cls): ## jakes-propagation-loss-model.h: static ns3::TypeId ns3::JakesPropagationLossModel::GetTypeId() [member function] - cls.add_method('GetTypeId', 'ns3::TypeId', [], is_static=True) + cls.add_method('GetTypeId', + 'ns3::TypeId', + [], + is_static=True) ## jakes-propagation-loss-model.h: ns3::JakesPropagationLossModel::JakesPropagationLossModel() [constructor] - cls.add_constructor([], visibility='public') + cls.add_constructor([]) ## jakes-propagation-loss-model.h: double ns3::JakesPropagationLossModel::GetLoss(ns3::Ptr a, ns3::Ptr b) const [member function] - cls.add_method('GetLoss', 'double', [param('ns3::Ptr< ns3::MobilityModel >', 'a'), param('ns3::Ptr< ns3::MobilityModel >', 'b')], is_const=True, is_virtual=True) + cls.add_method('GetLoss', + 'double', + [param('ns3::Ptr< ns3::MobilityModel >', 'a'), param('ns3::Ptr< ns3::MobilityModel >', 'b')], + is_const=True, is_virtual=True) ## jakes-propagation-loss-model.h: void ns3::JakesPropagationLossModel::SetNRays(uint8_t nRays) [member function] - cls.add_method('SetNRays', 'void', [param('uint8_t', 'nRays')]) + cls.add_method('SetNRays', + 'void', + [param('uint8_t', 'nRays')]) ## jakes-propagation-loss-model.h: void ns3::JakesPropagationLossModel::SetNOscillators(uint8_t nOscillators) [member function] - cls.add_method('SetNOscillators', 'void', [param('uint8_t', 'nOscillators')]) + cls.add_method('SetNOscillators', + 'void', + [param('uint8_t', 'nOscillators')]) return def register_Ns3ConstantSpeedPropagationDelayModel_methods(root_module, cls): ## propagation-delay-model.h: static ns3::TypeId ns3::ConstantSpeedPropagationDelayModel::GetTypeId() [member function] - cls.add_method('GetTypeId', 'ns3::TypeId', [], is_static=True) + cls.add_method('GetTypeId', + 'ns3::TypeId', + [], + is_static=True) ## propagation-delay-model.h: ns3::ConstantSpeedPropagationDelayModel::ConstantSpeedPropagationDelayModel() [constructor] - cls.add_constructor([], visibility='public') + cls.add_constructor([]) ## propagation-delay-model.h: ns3::Time ns3::ConstantSpeedPropagationDelayModel::GetDelay(ns3::Ptr a, ns3::Ptr b) const [member function] - cls.add_method('GetDelay', 'ns3::Time', [param('ns3::Ptr< ns3::MobilityModel >', 'a'), param('ns3::Ptr< ns3::MobilityModel >', 'b')], is_const=True, is_virtual=True) + cls.add_method('GetDelay', + 'ns3::Time', + [param('ns3::Ptr< ns3::MobilityModel >', 'a'), param('ns3::Ptr< ns3::MobilityModel >', 'b')], + is_const=True, is_virtual=True) ## propagation-delay-model.h: void ns3::ConstantSpeedPropagationDelayModel::SetSpeed(double speed) [member function] - cls.add_method('SetSpeed', 'void', [param('double', 'speed')]) + cls.add_method('SetSpeed', + 'void', + [param('double', 'speed')]) ## propagation-delay-model.h: double ns3::ConstantSpeedPropagationDelayModel::GetSpeed() const [member function] - cls.add_method('GetSpeed', 'double', [], is_const=True) + cls.add_method('GetSpeed', + 'double', + [], + is_const=True) return def register_Ns3WifiNetDevice_methods(root_module, cls): ## wifi-net-device.h: static ns3::TypeId ns3::WifiNetDevice::GetTypeId() [member function] - cls.add_method('GetTypeId', 'ns3::TypeId', [], is_static=True) + cls.add_method('GetTypeId', + 'ns3::TypeId', + [], + is_static=True) ## wifi-net-device.h: ns3::WifiNetDevice::WifiNetDevice() [constructor] - cls.add_constructor([], visibility='public') + cls.add_constructor([]) ## wifi-net-device.h: void ns3::WifiNetDevice::SetMac(ns3::Ptr mac) [member function] - cls.add_method('SetMac', 'void', [param('ns3::Ptr< ns3::WifiMac >', 'mac')]) + cls.add_method('SetMac', + 'void', + [param('ns3::Ptr< ns3::WifiMac >', 'mac')]) ## wifi-net-device.h: void ns3::WifiNetDevice::SetPhy(ns3::Ptr phy) [member function] - cls.add_method('SetPhy', 'void', [param('ns3::Ptr< ns3::WifiPhy >', 'phy')]) + cls.add_method('SetPhy', + 'void', + [param('ns3::Ptr< ns3::WifiPhy >', 'phy')]) ## wifi-net-device.h: void ns3::WifiNetDevice::SetRemoteStationManager(ns3::Ptr manager) [member function] - cls.add_method('SetRemoteStationManager', 'void', [param('ns3::Ptr< ns3::WifiRemoteStationManager >', 'manager')]) + cls.add_method('SetRemoteStationManager', + 'void', + [param('ns3::Ptr< ns3::WifiRemoteStationManager >', 'manager')]) ## wifi-net-device.h: void ns3::WifiNetDevice::SetChannel(ns3::Ptr channel) [member function] - cls.add_method('SetChannel', 'void', [param('ns3::Ptr< ns3::WifiChannel >', 'channel')]) + cls.add_method('SetChannel', + 'void', + [param('ns3::Ptr< ns3::WifiChannel >', 'channel')]) ## wifi-net-device.h: ns3::Ptr ns3::WifiNetDevice::GetMac() const [member function] - cls.add_method('GetMac', 'ns3::Ptr< ns3::WifiMac >', [], is_const=True) + cls.add_method('GetMac', + 'ns3::Ptr< ns3::WifiMac >', + [], + is_const=True) ## wifi-net-device.h: ns3::Ptr ns3::WifiNetDevice::GetPhy() const [member function] - cls.add_method('GetPhy', 'ns3::Ptr< ns3::WifiPhy >', [], is_const=True) + cls.add_method('GetPhy', + 'ns3::Ptr< ns3::WifiPhy >', + [], + is_const=True) ## wifi-net-device.h: ns3::Ptr ns3::WifiNetDevice::GetRemoteStationManager() const [member function] - cls.add_method('GetRemoteStationManager', 'ns3::Ptr< ns3::WifiRemoteStationManager >', [], is_const=True) + cls.add_method('GetRemoteStationManager', + 'ns3::Ptr< ns3::WifiRemoteStationManager >', + [], + is_const=True) ## wifi-net-device.h: void ns3::WifiNetDevice::SetName(std::string const name) [member function] - cls.add_method('SetName', 'void', [param('std::string', 'name', is_const=True)], is_virtual=True) + cls.add_method('SetName', + 'void', + [param('std::string', 'name', is_const=True)], + is_virtual=True) ## wifi-net-device.h: std::string ns3::WifiNetDevice::GetName() const [member function] - cls.add_method('GetName', 'std::string', [], is_const=True, is_virtual=True) + cls.add_method('GetName', + 'std::string', + [], + is_const=True, is_virtual=True) ## wifi-net-device.h: void ns3::WifiNetDevice::SetIfIndex(uint32_t const index) [member function] - cls.add_method('SetIfIndex', 'void', [param('uint32_t', 'index', is_const=True)], is_virtual=True) + cls.add_method('SetIfIndex', + 'void', + [param('uint32_t', 'index', is_const=True)], + is_virtual=True) ## wifi-net-device.h: uint32_t ns3::WifiNetDevice::GetIfIndex() const [member function] - cls.add_method('GetIfIndex', 'uint32_t', [], is_const=True, is_virtual=True) + cls.add_method('GetIfIndex', + 'uint32_t', + [], + is_const=True, is_virtual=True) ## wifi-net-device.h: ns3::Ptr ns3::WifiNetDevice::GetChannel() const [member function] - cls.add_method('GetChannel', 'ns3::Ptr< ns3::Channel >', [], is_const=True, is_virtual=True) + cls.add_method('GetChannel', + 'ns3::Ptr< ns3::Channel >', + [], + is_const=True, is_virtual=True) ## wifi-net-device.h: ns3::Address ns3::WifiNetDevice::GetAddress() const [member function] - cls.add_method('GetAddress', 'ns3::Address', [], is_const=True, is_virtual=True) + cls.add_method('GetAddress', + 'ns3::Address', + [], + is_const=True, is_virtual=True) ## wifi-net-device.h: bool ns3::WifiNetDevice::SetMtu(uint16_t const mtu) [member function] - cls.add_method('SetMtu', 'bool', [param('uint16_t', 'mtu', is_const=True)], is_virtual=True) + cls.add_method('SetMtu', + 'bool', + [param('uint16_t', 'mtu', is_const=True)], + is_virtual=True) ## wifi-net-device.h: uint16_t ns3::WifiNetDevice::GetMtu() const [member function] - cls.add_method('GetMtu', 'uint16_t', [], is_const=True, is_virtual=True) + cls.add_method('GetMtu', + 'uint16_t', + [], + is_const=True, is_virtual=True) ## wifi-net-device.h: bool ns3::WifiNetDevice::IsLinkUp() const [member function] - cls.add_method('IsLinkUp', 'bool', [], is_const=True, is_virtual=True) + cls.add_method('IsLinkUp', + 'bool', + [], + is_const=True, is_virtual=True) ## wifi-net-device.h: void ns3::WifiNetDevice::SetLinkChangeCallback(ns3::Callback callback) [member function] - cls.add_method('SetLinkChangeCallback', 'void', [param('ns3::Callback< void, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty >', 'callback')], is_virtual=True) + cls.add_method('SetLinkChangeCallback', + 'void', + [param('ns3::Callback< void, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty >', 'callback')], + is_virtual=True) ## wifi-net-device.h: bool ns3::WifiNetDevice::IsBroadcast() const [member function] - cls.add_method('IsBroadcast', 'bool', [], is_const=True, is_virtual=True) + cls.add_method('IsBroadcast', + 'bool', + [], + is_const=True, is_virtual=True) ## wifi-net-device.h: ns3::Address ns3::WifiNetDevice::GetBroadcast() const [member function] - cls.add_method('GetBroadcast', 'ns3::Address', [], is_const=True, is_virtual=True) + cls.add_method('GetBroadcast', + 'ns3::Address', + [], + is_const=True, is_virtual=True) ## wifi-net-device.h: bool ns3::WifiNetDevice::IsMulticast() const [member function] - cls.add_method('IsMulticast', 'bool', [], is_const=True, is_virtual=True) + cls.add_method('IsMulticast', + 'bool', + [], + is_const=True, is_virtual=True) ## wifi-net-device.h: ns3::Address ns3::WifiNetDevice::GetMulticast() const [member function] - cls.add_method('GetMulticast', 'ns3::Address', [], is_const=True, is_virtual=True) + cls.add_method('GetMulticast', + 'ns3::Address', + [], + is_const=True, is_virtual=True) ## wifi-net-device.h: ns3::Address ns3::WifiNetDevice::MakeMulticastAddress(ns3::Ipv4Address multicastGroup) const [member function] - cls.add_method('MakeMulticastAddress', 'ns3::Address', [param('ns3::Ipv4Address', 'multicastGroup')], is_const=True, is_virtual=True) + cls.add_method('MakeMulticastAddress', + 'ns3::Address', + [param('ns3::Ipv4Address', 'multicastGroup')], + is_const=True, is_virtual=True) ## wifi-net-device.h: bool ns3::WifiNetDevice::IsPointToPoint() const [member function] - cls.add_method('IsPointToPoint', 'bool', [], is_const=True, is_virtual=True) + cls.add_method('IsPointToPoint', + 'bool', + [], + is_const=True, is_virtual=True) ## wifi-net-device.h: bool ns3::WifiNetDevice::Send(ns3::Ptr packet, ns3::Address const & dest, uint16_t protocolNumber) [member function] - cls.add_method('Send', 'bool', [param('ns3::Ptr< ns3::Packet >', 'packet'), param('ns3::Address&', 'dest', is_const=True), param('uint16_t', 'protocolNumber')], is_virtual=True) - ## wifi-net-device.h: bool ns3::WifiNetDevice::SendFrom(ns3::Ptr packet, ns3::Address const & src, ns3::Address const & dest, uint16_t protocolNumber) [member function] - cls.add_method('SendFrom', 'bool', [param('ns3::Ptr< ns3::Packet >', 'packet'), param('ns3::Address&', 'src', is_const=True), param('ns3::Address&', 'dest', is_const=True), param('uint16_t', 'protocolNumber')], is_virtual=True) + cls.add_method('Send', + 'bool', + [param('ns3::Ptr< ns3::Packet >', 'packet'), param('ns3::Address&', 'dest', is_const=True), param('uint16_t', 'protocolNumber')], + is_virtual=True) ## wifi-net-device.h: ns3::Ptr ns3::WifiNetDevice::GetNode() const [member function] - cls.add_method('GetNode', 'ns3::Ptr< ns3::Node >', [], is_const=True, is_virtual=True) + cls.add_method('GetNode', + 'ns3::Ptr< ns3::Node >', + [], + is_const=True, is_virtual=True) ## wifi-net-device.h: void ns3::WifiNetDevice::SetNode(ns3::Ptr node) [member function] - cls.add_method('SetNode', 'void', [param('ns3::Ptr< ns3::Node >', 'node')], is_virtual=True) + cls.add_method('SetNode', + 'void', + [param('ns3::Ptr< ns3::Node >', 'node')], + is_virtual=True) ## wifi-net-device.h: bool ns3::WifiNetDevice::NeedsArp() const [member function] - cls.add_method('NeedsArp', 'bool', [], is_const=True, is_virtual=True) + cls.add_method('NeedsArp', + 'bool', + [], + is_const=True, is_virtual=True) ## wifi-net-device.h: void ns3::WifiNetDevice::SetReceiveCallback(ns3::Callback, ns3::Ptr, unsigned short, ns3::Address const&, ns3::empty, ns3::empty> cb) [member function] - cls.add_method('SetReceiveCallback', 'void', [param('ns3::Callback< bool, ns3::Ptr< ns3::NetDevice >, ns3::Ptr< ns3::Packet >, unsigned short, ns3::Address const&, ns3::empty, ns3::empty >', 'cb')], is_virtual=True) + cls.add_method('SetReceiveCallback', + 'void', + [param('ns3::Callback< bool, ns3::Ptr< ns3::NetDevice >, ns3::Ptr< ns3::Packet >, unsigned short, ns3::Address const&, ns3::empty, ns3::empty >', 'cb')], + is_virtual=True) ## wifi-net-device.h: void ns3::WifiNetDevice::DoDispose() [member function] - cls.add_method('DoDispose', 'void', [], visibility='private', is_virtual=True) + cls.add_method('DoDispose', + 'void', + [], + visibility='private', is_virtual=True) return def register_Ns3NqstaWifiMac_methods(root_module, cls): ## nqsta-wifi-mac.h: static ns3::TypeId ns3::NqstaWifiMac::GetTypeId() [member function] - cls.add_method('GetTypeId', 'ns3::TypeId', [], is_static=True) + cls.add_method('GetTypeId', + 'ns3::TypeId', + [], + is_static=True) ## nqsta-wifi-mac.h: ns3::NqstaWifiMac::NqstaWifiMac() [constructor] - cls.add_constructor([], visibility='public') + cls.add_constructor([]) ## nqsta-wifi-mac.h: void ns3::NqstaWifiMac::SetSlot(ns3::Time slotTime) [member function] - cls.add_method('SetSlot', 'void', [param('ns3::Time', 'slotTime')], is_virtual=True) + cls.add_method('SetSlot', + 'void', + [param('ns3::Time', 'slotTime')], + is_virtual=True) ## nqsta-wifi-mac.h: void ns3::NqstaWifiMac::SetSifs(ns3::Time sifs) [member function] - cls.add_method('SetSifs', 'void', [param('ns3::Time', 'sifs')], is_virtual=True) + cls.add_method('SetSifs', + 'void', + [param('ns3::Time', 'sifs')], + is_virtual=True) ## nqsta-wifi-mac.h: void ns3::NqstaWifiMac::SetEifsNoDifs(ns3::Time eifsNoDifs) [member function] - cls.add_method('SetEifsNoDifs', 'void', [param('ns3::Time', 'eifsNoDifs')], is_virtual=True) + cls.add_method('SetEifsNoDifs', + 'void', + [param('ns3::Time', 'eifsNoDifs')], + is_virtual=True) ## nqsta-wifi-mac.h: ns3::Time ns3::NqstaWifiMac::GetSlot() const [member function] - cls.add_method('GetSlot', 'ns3::Time', [], is_const=True, is_virtual=True) + cls.add_method('GetSlot', + 'ns3::Time', + [], + is_const=True, is_virtual=True) ## nqsta-wifi-mac.h: ns3::Time ns3::NqstaWifiMac::GetSifs() const [member function] - cls.add_method('GetSifs', 'ns3::Time', [], is_const=True, is_virtual=True) + cls.add_method('GetSifs', + 'ns3::Time', + [], + is_const=True, is_virtual=True) ## nqsta-wifi-mac.h: ns3::Time ns3::NqstaWifiMac::GetEifsNoDifs() const [member function] - cls.add_method('GetEifsNoDifs', 'ns3::Time', [], is_const=True, is_virtual=True) + cls.add_method('GetEifsNoDifs', + 'ns3::Time', + [], + is_const=True, is_virtual=True) ## nqsta-wifi-mac.h: void ns3::NqstaWifiMac::SetWifiPhy(ns3::Ptr phy) [member function] - cls.add_method('SetWifiPhy', 'void', [param('ns3::Ptr< ns3::WifiPhy >', 'phy')], is_virtual=True) + cls.add_method('SetWifiPhy', + 'void', + [param('ns3::Ptr< ns3::WifiPhy >', 'phy')], + is_virtual=True) ## nqsta-wifi-mac.h: void ns3::NqstaWifiMac::SetWifiRemoteStationManager(ns3::Ptr stationManager) [member function] - cls.add_method('SetWifiRemoteStationManager', 'void', [param('ns3::Ptr< ns3::WifiRemoteStationManager >', 'stationManager')], is_virtual=True) + cls.add_method('SetWifiRemoteStationManager', + 'void', + [param('ns3::Ptr< ns3::WifiRemoteStationManager >', 'stationManager')], + is_virtual=True) ## nqsta-wifi-mac.h: void ns3::NqstaWifiMac::Enqueue(ns3::Ptr packet, ns3::Mac48Address to) [member function] - cls.add_method('Enqueue', 'void', [param('ns3::Ptr< const ns3::Packet >', 'packet'), param('ns3::Mac48Address', 'to')], is_virtual=True) + cls.add_method('Enqueue', + 'void', + [param('ns3::Ptr< const ns3::Packet >', 'packet'), param('ns3::Mac48Address', 'to')], + is_virtual=True) ## nqsta-wifi-mac.h: void ns3::NqstaWifiMac::SetForwardUpCallback(ns3::Callback, ns3::Mac48Address const&, ns3::empty, ns3::empty, ns3::empty, ns3::empty> upCallback) [member function] - cls.add_method('SetForwardUpCallback', 'void', [param('ns3::Callback< void, ns3::Ptr< ns3::Packet >, ns3::Mac48Address const&, ns3::empty, ns3::empty, ns3::empty, ns3::empty >', 'upCallback')], is_virtual=True) + cls.add_method('SetForwardUpCallback', + 'void', + [param('ns3::Callback< void, ns3::Ptr< ns3::Packet >, ns3::Mac48Address const&, ns3::empty, ns3::empty, ns3::empty, ns3::empty >', 'upCallback')], + is_virtual=True) ## nqsta-wifi-mac.h: void ns3::NqstaWifiMac::SetLinkUpCallback(ns3::Callback linkUp) [member function] - cls.add_method('SetLinkUpCallback', 'void', [param('ns3::Callback< void, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty >', 'linkUp')], is_virtual=True) + cls.add_method('SetLinkUpCallback', + 'void', + [param('ns3::Callback< void, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty >', 'linkUp')], + is_virtual=True) ## nqsta-wifi-mac.h: void ns3::NqstaWifiMac::SetLinkDownCallback(ns3::Callback linkDown) [member function] - cls.add_method('SetLinkDownCallback', 'void', [param('ns3::Callback< void, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty >', 'linkDown')], is_virtual=True) + cls.add_method('SetLinkDownCallback', + 'void', + [param('ns3::Callback< void, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty >', 'linkDown')], + is_virtual=True) ## nqsta-wifi-mac.h: ns3::Mac48Address ns3::NqstaWifiMac::GetAddress() const [member function] - cls.add_method('GetAddress', 'ns3::Mac48Address', [], is_const=True, is_virtual=True) + cls.add_method('GetAddress', + 'ns3::Mac48Address', + [], + is_const=True, is_virtual=True) ## nqsta-wifi-mac.h: ns3::Ssid ns3::NqstaWifiMac::GetSsid() const [member function] - cls.add_method('GetSsid', 'ns3::Ssid', [], is_const=True, is_virtual=True) + cls.add_method('GetSsid', + 'ns3::Ssid', + [], + is_const=True, is_virtual=True) ## nqsta-wifi-mac.h: ns3::Mac48Address ns3::NqstaWifiMac::GetBssid() const [member function] - cls.add_method('GetBssid', 'ns3::Mac48Address', [], is_const=True, is_virtual=True) + cls.add_method('GetBssid', + 'ns3::Mac48Address', + [], + is_const=True, is_virtual=True) ## nqsta-wifi-mac.h: void ns3::NqstaWifiMac::SetAddress(ns3::Mac48Address address) [member function] - cls.add_method('SetAddress', 'void', [param('ns3::Mac48Address', 'address')], is_virtual=True) + cls.add_method('SetAddress', + 'void', + [param('ns3::Mac48Address', 'address')], + is_virtual=True) ## nqsta-wifi-mac.h: void ns3::NqstaWifiMac::SetSsid(ns3::Ssid ssid) [member function] - cls.add_method('SetSsid', 'void', [param('ns3::Ssid', 'ssid')], is_virtual=True) + cls.add_method('SetSsid', + 'void', + [param('ns3::Ssid', 'ssid')], + is_virtual=True) ## nqsta-wifi-mac.h: void ns3::NqstaWifiMac::SetMaxMissedBeacons(uint32_t missed) [member function] - cls.add_method('SetMaxMissedBeacons', 'void', [param('uint32_t', 'missed')]) + cls.add_method('SetMaxMissedBeacons', + 'void', + [param('uint32_t', 'missed')]) ## nqsta-wifi-mac.h: void ns3::NqstaWifiMac::SetProbeRequestTimeout(ns3::Time timeout) [member function] - cls.add_method('SetProbeRequestTimeout', 'void', [param('ns3::Time', 'timeout')]) + cls.add_method('SetProbeRequestTimeout', + 'void', + [param('ns3::Time', 'timeout')]) ## nqsta-wifi-mac.h: void ns3::NqstaWifiMac::SetAssocRequestTimeout(ns3::Time timeout) [member function] - cls.add_method('SetAssocRequestTimeout', 'void', [param('ns3::Time', 'timeout')]) + cls.add_method('SetAssocRequestTimeout', + 'void', + [param('ns3::Time', 'timeout')]) ## nqsta-wifi-mac.h: void ns3::NqstaWifiMac::StartActiveAssociation() [member function] - cls.add_method('StartActiveAssociation', 'void', []) + cls.add_method('StartActiveAssociation', + 'void', + []) ## nqsta-wifi-mac.h: void ns3::NqstaWifiMac::DoDispose() [member function] - cls.add_method('DoDispose', 'void', [], visibility='private', is_virtual=True) + cls.add_method('DoDispose', + 'void', + [], + visibility='private', is_virtual=True) return def register_Ns3RandomPropagationLossModel_methods(root_module, cls): ## propagation-loss-model.h: static ns3::TypeId ns3::RandomPropagationLossModel::GetTypeId() [member function] - cls.add_method('GetTypeId', 'ns3::TypeId', [], is_static=True) + cls.add_method('GetTypeId', + 'ns3::TypeId', + [], + is_static=True) ## propagation-loss-model.h: ns3::RandomPropagationLossModel::RandomPropagationLossModel() [constructor] - cls.add_constructor([], visibility='public') + cls.add_constructor([]) ## propagation-loss-model.h: double ns3::RandomPropagationLossModel::GetLoss(ns3::Ptr a, ns3::Ptr b) const [member function] - cls.add_method('GetLoss', 'double', [param('ns3::Ptr< ns3::MobilityModel >', 'a'), param('ns3::Ptr< ns3::MobilityModel >', 'b')], is_const=True, is_virtual=True) + cls.add_method('GetLoss', + 'double', + [param('ns3::Ptr< ns3::MobilityModel >', 'a'), param('ns3::Ptr< ns3::MobilityModel >', 'b')], + is_const=True, is_virtual=True) return def register_Ns3RandomPropagationDelayModel_methods(root_module, cls): ## propagation-delay-model.h: static ns3::TypeId ns3::RandomPropagationDelayModel::GetTypeId() [member function] - cls.add_method('GetTypeId', 'ns3::TypeId', [], is_static=True) + cls.add_method('GetTypeId', + 'ns3::TypeId', + [], + is_static=True) ## propagation-delay-model.h: ns3::RandomPropagationDelayModel::RandomPropagationDelayModel() [constructor] - cls.add_constructor([], visibility='public') + cls.add_constructor([]) ## propagation-delay-model.h: ns3::Time ns3::RandomPropagationDelayModel::GetDelay(ns3::Ptr a, ns3::Ptr b) const [member function] - cls.add_method('GetDelay', 'ns3::Time', [param('ns3::Ptr< ns3::MobilityModel >', 'a'), param('ns3::Ptr< ns3::MobilityModel >', 'b')], is_const=True, is_virtual=True) + cls.add_method('GetDelay', + 'ns3::Time', + [param('ns3::Ptr< ns3::MobilityModel >', 'a'), param('ns3::Ptr< ns3::MobilityModel >', 'b')], + is_const=True, is_virtual=True) return def register_Ns3AmrrWifiManager_methods(root_module, cls): ## amrr-wifi-manager.h: static ns3::TypeId ns3::AmrrWifiManager::GetTypeId() [member function] - cls.add_method('GetTypeId', 'ns3::TypeId', [], is_static=True) + cls.add_method('GetTypeId', + 'ns3::TypeId', + [], + is_static=True) ## amrr-wifi-manager.h: ns3::AmrrWifiManager::AmrrWifiManager() [constructor] - cls.add_constructor([], visibility='public') + cls.add_constructor([]) ## amrr-wifi-manager.h: ns3::WifiRemoteStation * ns3::AmrrWifiManager::CreateStation() [member function] - cls.add_method('CreateStation', 'ns3::WifiRemoteStation *', [], visibility='private', is_virtual=True) + cls.add_method('CreateStation', + 'ns3::WifiRemoteStation *', + [], + visibility='private', is_virtual=True) return def register_Ns3RraaWifiManager_methods(root_module, cls): ## rraa-wifi-manager.h: static ns3::TypeId ns3::RraaWifiManager::GetTypeId() [member function] - cls.add_method('GetTypeId', 'ns3::TypeId', [], is_static=True) + cls.add_method('GetTypeId', + 'ns3::TypeId', + [], + is_static=True) ## rraa-wifi-manager.h: ns3::RraaWifiManager::RraaWifiManager() [constructor] - cls.add_constructor([], visibility='public') + cls.add_constructor([]) ## rraa-wifi-manager.h: bool ns3::RraaWifiManager::OnlyBasic() [member function] - cls.add_method('OnlyBasic', 'bool', []) + cls.add_method('OnlyBasic', + 'bool', + []) ## rraa-wifi-manager.h: ns3::Time ns3::RraaWifiManager::GetTimeout() const [member function] - cls.add_method('GetTimeout', 'ns3::Time', [], is_const=True) + cls.add_method('GetTimeout', + 'ns3::Time', + [], + is_const=True) ## rraa-wifi-manager.h: ns3::ThresholdsItem ns3::RraaWifiManager::GetThresholds(ns3::WifiMode mode) const [member function] - cls.add_method('GetThresholds', 'ns3::ThresholdsItem', [param('ns3::WifiMode', 'mode')], is_const=True) + cls.add_method('GetThresholds', + 'ns3::ThresholdsItem', + [param('ns3::WifiMode', 'mode')], + is_const=True) ## rraa-wifi-manager.h: ns3::WifiRemoteStation * ns3::RraaWifiManager::CreateStation() [member function] - cls.add_method('CreateStation', 'ns3::WifiRemoteStation *', [], visibility='private', is_virtual=True) + cls.add_method('CreateStation', + 'ns3::WifiRemoteStation *', + [], + visibility='private', is_virtual=True) return def register_Ns3IdealWifiManager_methods(root_module, cls): ## ideal-wifi-manager.h: static ns3::TypeId ns3::IdealWifiManager::GetTypeId() [member function] - cls.add_method('GetTypeId', 'ns3::TypeId', [], is_static=True) + cls.add_method('GetTypeId', + 'ns3::TypeId', + [], + is_static=True) ## ideal-wifi-manager.h: ns3::IdealWifiManager::IdealWifiManager() [constructor] - cls.add_constructor([], visibility='public') + cls.add_constructor([]) ## ideal-wifi-manager.h: void ns3::IdealWifiManager::SetupPhy(ns3::Ptr phy) [member function] - cls.add_method('SetupPhy', 'void', [param('ns3::Ptr< ns3::WifiPhy >', 'phy')], is_virtual=True) + cls.add_method('SetupPhy', + 'void', + [param('ns3::Ptr< ns3::WifiPhy >', 'phy')], + is_virtual=True) ## ideal-wifi-manager.h: double ns3::IdealWifiManager::GetSnrThreshold(ns3::WifiMode mode) const [member function] - cls.add_method('GetSnrThreshold', 'double', [param('ns3::WifiMode', 'mode')], is_const=True) + cls.add_method('GetSnrThreshold', + 'double', + [param('ns3::WifiMode', 'mode')], + is_const=True) ## ideal-wifi-manager.h: void ns3::IdealWifiManager::AddModeSnrThreshold(ns3::WifiMode mode, double ber) [member function] - cls.add_method('AddModeSnrThreshold', 'void', [param('ns3::WifiMode', 'mode'), param('double', 'ber')]) + cls.add_method('AddModeSnrThreshold', + 'void', + [param('ns3::WifiMode', 'mode'), param('double', 'ber')]) ## ideal-wifi-manager.h: ns3::WifiRemoteStation * ns3::IdealWifiManager::CreateStation() [member function] - cls.add_method('CreateStation', 'ns3::WifiRemoteStation *', [], visibility='private', is_virtual=True) + cls.add_method('CreateStation', + 'ns3::WifiRemoteStation *', + [], + visibility='private', is_virtual=True) return def register_Ns3ArfWifiManager_methods(root_module, cls): ## arf-wifi-manager.h: static ns3::TypeId ns3::ArfWifiManager::GetTypeId() [member function] - cls.add_method('GetTypeId', 'ns3::TypeId', [], is_static=True) + cls.add_method('GetTypeId', + 'ns3::TypeId', + [], + is_static=True) ## arf-wifi-manager.h: ns3::ArfWifiManager::ArfWifiManager() [constructor] - cls.add_constructor([], visibility='public') + cls.add_constructor([]) ## arf-wifi-manager.h: ns3::WifiRemoteStation * ns3::ArfWifiManager::CreateStation() [member function] - cls.add_method('CreateStation', 'ns3::WifiRemoteStation *', [], visibility='private', is_virtual=True) + cls.add_method('CreateStation', + 'ns3::WifiRemoteStation *', + [], + visibility='private', is_virtual=True) return def register_Ns3AarfWifiManager_methods(root_module, cls): ## aarf-wifi-manager.h: static ns3::TypeId ns3::AarfWifiManager::GetTypeId() [member function] - cls.add_method('GetTypeId', 'ns3::TypeId', [], is_static=True) + cls.add_method('GetTypeId', + 'ns3::TypeId', + [], + is_static=True) ## aarf-wifi-manager.h: ns3::AarfWifiManager::AarfWifiManager() [constructor] - cls.add_constructor([], visibility='public') + cls.add_constructor([]) ## aarf-wifi-manager.h: ns3::WifiRemoteStation * ns3::AarfWifiManager::CreateStation() [member function] - cls.add_method('CreateStation', 'ns3::WifiRemoteStation *', [], visibility='private', is_virtual=True) + cls.add_method('CreateStation', + 'ns3::WifiRemoteStation *', + [], + visibility='private', is_virtual=True) return def register_functions(root_module): module = root_module ## wifi-mode.h: extern ns3::Ptr ns3::MakeWifiModeChecker() [free function] - module.add_function('MakeWifiModeChecker', 'ns3::Ptr< ns3::AttributeChecker const >', []) + module.add_function('MakeWifiModeChecker', + 'ns3::Ptr< ns3::AttributeChecker const >', + []) ## ssid.h: extern ns3::Ptr ns3::MakeSsidChecker() [free function] - module.add_function('MakeSsidChecker', 'ns3::Ptr< ns3::AttributeChecker const >', []) + module.add_function('MakeSsidChecker', + 'ns3::Ptr< ns3::AttributeChecker const >', + []) register_functions_ns3_internal(module.get_submodule('internal'), root_module) register_functions_ns3_TimeStepPrecision(module.get_submodule('TimeStepPrecision'), root_module) register_functions_ns3_Config(module.get_submodule('Config'), root_module) diff --git a/bindings/python/ns3modulegen_generated.py b/bindings/python/ns3modulegen_generated.py index 2e700fe0d..e2ae02275 100644 --- a/bindings/python/ns3modulegen_generated.py +++ b/bindings/python/ns3modulegen_generated.py @@ -1,4 +1,4 @@ -from pybindgen import Module, FileCodeSink, write_preamble, param, retval +from pybindgen import Module, FileCodeSink, param, retval, cppclass import pybindgen.settings @@ -668,7 +668,6 @@ def main(): register_types(root_module) register_methods(root_module) register_functions(root_module) - write_preamble(out) root_module.generate(out) if __name__ == '__main__': diff --git a/bindings/python/wscript b/bindings/python/wscript index a755cf28c..03766fa24 100644 --- a/bindings/python/wscript +++ b/bindings/python/wscript @@ -21,7 +21,7 @@ else: os.environ['PYTHONPATH'] = LOCAL_PYBINDGEN_PATH ## https://launchpad.net/pybindgen/ -REQUIRED_PYBINDGEN_VERSION = (0, 8, 0, 492) +REQUIRED_PYBINDGEN_VERSION = (0, 8, 0, 511) REQUIRED_PYGCCXML_VERSION = (0, 9, 5) From b9722796d773af4e3bc529be701d6002cd56c93d Mon Sep 17 00:00:00 2001 From: "Gustavo J. A. M. Carneiro" Date: Tue, 22 Jul 2008 16:54:24 +0100 Subject: [PATCH 190/495] Require new PyBindGen; make it work for Python 2.3. --- bindings/python/ns3modulegen.py | 2 +- bindings/python/ns3modulegen_core_customizations.py | 2 +- bindings/python/wscript | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/bindings/python/ns3modulegen.py b/bindings/python/ns3modulegen.py index d986e9565..7d3ab611a 100644 --- a/bindings/python/ns3modulegen.py +++ b/bindings/python/ns3modulegen.py @@ -12,7 +12,7 @@ from pybindgen import FileCodeSink, write_preamble from pybindgen.module import MultiSectionFactory import pybindgen.settings -from ns3modulegen_generated import (module_init, register_types, register_methods, register_functions) +from ns3modulegen_generated import module_init, register_types, register_methods, register_functions import ns3modulegen_core_customizations import callbacks_list diff --git a/bindings/python/ns3modulegen_core_customizations.py b/bindings/python/ns3modulegen_core_customizations.py index 50e6dc849..29a73206f 100644 --- a/bindings/python/ns3modulegen_core_customizations.py +++ b/bindings/python/ns3modulegen_core_customizations.py @@ -1,7 +1,7 @@ import re from pybindgen.typehandlers import base as typehandlers -from pybindgen import (ReturnValue, Parameter) +from pybindgen import ReturnValue, Parameter from pybindgen.cppmethod import CustomCppMethodWrapper, CustomCppConstructorWrapper from pybindgen.typehandlers.codesink import MemoryCodeSink from pybindgen.typehandlers import ctypeparser diff --git a/bindings/python/wscript b/bindings/python/wscript index 03766fa24..701123fae 100644 --- a/bindings/python/wscript +++ b/bindings/python/wscript @@ -21,7 +21,7 @@ else: os.environ['PYTHONPATH'] = LOCAL_PYBINDGEN_PATH ## https://launchpad.net/pybindgen/ -REQUIRED_PYBINDGEN_VERSION = (0, 8, 0, 511) +REQUIRED_PYBINDGEN_VERSION = (0, 8, 0, 515) REQUIRED_PYGCCXML_VERSION = (0, 9, 5) @@ -93,7 +93,7 @@ def configure(conf): ## Check for Python try: conf.check_tool('python') - conf.check_python_version((2,4,2)) + conf.check_python_version((2,3)) conf.check_python_headers() except Configure.ConfigurationError: return From 5a71f60c7ab132307b6963cfca578a04f1d600fd Mon Sep 17 00:00:00 2001 From: "Gustavo J. A. M. Carneiro" Date: Wed, 23 Jul 2008 11:48:17 +0100 Subject: [PATCH 191/495] Define NS3_ASSERT_ENABLE and NS3_LOG_ENABLE, to make sure we pick up all definitions (such as the logging APIs) --- bindings/python/ns3_module_common.py | 4 +- bindings/python/ns3_module_core.py | 69 ++++- bindings/python/ns3_module_node.py | 118 ++++----- bindings/python/ns3_module_simulator.py | 205 +++++++++++++++ bindings/python/ns3_module_wifi.py | 326 ++++++++++++------------ bindings/python/ns3modulescan.py | 14 +- bindings/python/wscript | 2 +- 7 files changed, 509 insertions(+), 229 deletions(-) diff --git a/bindings/python/ns3_module_common.py b/bindings/python/ns3_module_common.py index 2b9ad84e3..b6a44c031 100644 --- a/bindings/python/ns3_module_common.py +++ b/bindings/python/ns3_module_common.py @@ -609,10 +609,10 @@ def register_Ns3BufferIterator_methods(root_module, cls): return def register_Ns3Chunk_methods(root_module, cls): - ## chunk.h: ns3::Chunk::Chunk() [constructor] - cls.add_constructor([]) ## chunk.h: ns3::Chunk::Chunk(ns3::Chunk const & arg0) [copy constructor] cls.add_constructor([param('ns3::Chunk&', 'arg0', is_const=True)]) + ## chunk.h: ns3::Chunk::Chunk() [constructor] + cls.add_constructor([]) ## chunk.h: static ns3::TypeId ns3::Chunk::GetTypeId() [member function] cls.add_method('GetTypeId', 'ns3::TypeId', diff --git a/bindings/python/ns3_module_core.py b/bindings/python/ns3_module_core.py index 2e27dd214..c2ebbafaa 100644 --- a/bindings/python/ns3_module_core.py +++ b/bindings/python/ns3_module_core.py @@ -3,6 +3,8 @@ from pybindgen import Module, FileCodeSink, param, retval, cppclass def register_types(module): root_module = module.get_root() + ## log.h: ns3::LogLevel [enumeration] + module.add_enum('LogLevel', ['LOG_NONE', 'LOG_ERROR', 'LOG_LEVEL_ERROR', 'LOG_WARN', 'LOG_LEVEL_WARN', 'LOG_DEBUG', 'LOG_LEVEL_DEBUG', 'LOG_INFO', 'LOG_LEVEL_INFO', 'LOG_FUNCTION', 'LOG_LEVEL_FUNCTION', 'LOG_LOGIC', 'LOG_LEVEL_LOGIC', 'LOG_ALL', 'LOG_LEVEL_ALL', 'LOG_PREFIX_FUNC', 'LOG_PREFIX_TIME']) ## random-variable.h: ns3::RandomVariable [class] module.add_class('RandomVariable') ## random-variable.h: ns3::TriangularVariable [class] @@ -117,6 +119,8 @@ def register_types(module): module.add_class('TracedCallback', template_parameters=['unsigned int', 'unsigned int', 'ns3::empty', 'ns3::empty']) ## random-variable.h: ns3::DeterministicVariable [class] module.add_class('DeterministicVariable', parent=root_module['ns3::RandomVariable']) + ## log.h: ns3::LogComponent [class] + module.add_class('LogComponent') ## attribute-list.h: ns3::AttributeList [class] module.add_class('AttributeList') ## attribute.h: ns3::AttributeValue [class] @@ -268,6 +272,7 @@ def register_methods(root_module): register_Ns3TracedCallback__Ns3Ptr__lt__ns3Packet_const__gt___Double_Ns3WifiMode_Ns3WifiPreamble_methods(root_module, root_module['ns3::TracedCallback< ns3::Ptr, double, ns3::WifiMode, ns3::WifiPreamble >']) register_Ns3TracedCallback__Unsigned_int_Unsigned_int_Ns3Empty_Ns3Empty_methods(root_module, root_module['ns3::TracedCallback< unsigned int, unsigned int, ns3::empty, ns3::empty >']) register_Ns3DeterministicVariable_methods(root_module, root_module['ns3::DeterministicVariable']) + register_Ns3LogComponent_methods(root_module, root_module['ns3::LogComponent']) register_Ns3AttributeList_methods(root_module, root_module['ns3::AttributeList']) register_Ns3AttributeValue_methods(root_module, root_module['ns3::AttributeValue']) register_Ns3UniformVariable_methods(root_module, root_module['ns3::UniformVariable']) @@ -887,10 +892,10 @@ def register_Ns3Empty_methods(root_module, cls): return def register_Ns3ObjectBase_methods(root_module, cls): - ## object-base.h: ns3::ObjectBase::ObjectBase() [constructor] - cls.add_constructor([]) ## object-base.h: ns3::ObjectBase::ObjectBase(ns3::ObjectBase const & arg0) [copy constructor] cls.add_constructor([param('ns3::ObjectBase&', 'arg0', is_const=True)]) + ## object-base.h: ns3::ObjectBase::ObjectBase() [constructor] + cls.add_constructor([]) ## object-base.h: static ns3::TypeId ns3::ObjectBase::GetTypeId() [member function] cls.add_method('GetTypeId', 'ns3::TypeId', @@ -1327,6 +1332,38 @@ def register_Ns3DeterministicVariable_methods(root_module, cls): cls.add_constructor([param('double *', 'd'), param('uint32_t', 'c')]) return +def register_Ns3LogComponent_methods(root_module, cls): + ## log.h: ns3::LogComponent::LogComponent(char const * name) [constructor] + cls.add_constructor([param('char *', 'name', transfer_ownership=False, is_const=True)]) + ## log.h: void ns3::LogComponent::EnvVarCheck(char const * name) [member function] + cls.add_method('EnvVarCheck', + 'void', + [param('char *', 'name', transfer_ownership=False, is_const=True)]) + ## log.h: bool ns3::LogComponent::IsEnabled(ns3::LogLevel level) const [member function] + cls.add_method('IsEnabled', + 'bool', + [param('ns3::LogLevel', 'level')], + is_const=True) + ## log.h: bool ns3::LogComponent::IsNoneEnabled() const [member function] + cls.add_method('IsNoneEnabled', + 'bool', + [], + is_const=True) + ## log.h: void ns3::LogComponent::Enable(ns3::LogLevel level) [member function] + cls.add_method('Enable', + 'void', + [param('ns3::LogLevel', 'level')]) + ## log.h: void ns3::LogComponent::Disable(ns3::LogLevel level) [member function] + cls.add_method('Disable', + 'void', + [param('ns3::LogLevel', 'level')]) + ## log.h: char const * ns3::LogComponent::Name() const [member function] + cls.add_method('Name', + retval('char *', is_const=True, caller_owns_return=False), + [], + is_const=True) + return + def register_Ns3AttributeList_methods(root_module, cls): ## attribute-list.h: ns3::AttributeList::AttributeList() [constructor] cls.add_constructor([]) @@ -2031,6 +2068,10 @@ def register_functions(root_module): module.add_function('MakeEnumChecker', 'ns3::Ptr< ns3::AttributeChecker const >', [param('int', 'v1'), param('std::string', 'n1'), param('int', 'v2', default_value='0'), param('std::string', 'n2', default_value='""'), param('int', 'v3', default_value='0'), param('std::string', 'n3', default_value='""'), param('int', 'v4', default_value='0'), param('std::string', 'n4', default_value='""'), param('int', 'v5', default_value='0'), param('std::string', 'n5', default_value='""'), param('int', 'v6', default_value='0'), param('std::string', 'n6', default_value='""'), param('int', 'v7', default_value='0'), param('std::string', 'n7', default_value='""'), param('int', 'v8', default_value='0'), param('std::string', 'n8', default_value='""'), param('int', 'v9', default_value='0'), param('std::string', 'n9', default_value='""'), param('int', 'v10', default_value='0'), param('std::string', 'n10', default_value='""'), param('int', 'v11', default_value='0'), param('std::string', 'n11', default_value='""'), param('int', 'v12', default_value='0'), param('std::string', 'n12', default_value='""')]) + ## log.h: extern void ns3::LogComponentEnableAll(ns3::LogLevel level) [free function] + module.add_function('LogComponentEnableAll', + 'void', + [param('ns3::LogLevel', 'level')]) ## type-id.h: extern ns3::Ptr ns3::MakeTypeIdChecker() [free function] module.add_function('MakeTypeIdChecker', 'ns3::Ptr< ns3::AttributeChecker const >', @@ -2049,6 +2090,14 @@ def register_functions(root_module): module.add_function('MakeObjectFactoryChecker', 'ns3::Ptr< ns3::AttributeChecker const >', []) + ## log.h: extern ns3::LogTimePrinter ns3::LogGetTimePrinter() [free function] + module.add_function('LogGetTimePrinter', + 'ns3::LogTimePrinter *', + []) + ## log.h: extern void ns3::LogComponentDisableAll(ns3::LogLevel level) [free function] + module.add_function('LogComponentDisableAll', + 'void', + [param('ns3::LogLevel', 'level')]) ## breakpoint.h: extern void ns3::BreakpointFallback() [free function] module.add_function('BreakpointFallback', 'void', @@ -2057,6 +2106,22 @@ def register_functions(root_module): module.add_function('MakeRandomVariableChecker', 'ns3::Ptr< ns3::AttributeChecker const >', []) + ## log.h: extern void ns3::LogSetTimePrinter(ns3::LogTimePrinter arg0) [free function] + module.add_function('LogSetTimePrinter', + 'void', + [param('ns3::LogTimePrinter *', 'arg0')]) + ## log.h: extern void ns3::LogComponentDisable(char const * name, ns3::LogLevel level) [free function] + module.add_function('LogComponentDisable', + 'void', + [param('char *', 'name', transfer_ownership=False, is_const=True), param('ns3::LogLevel', 'level')]) + ## log.h: extern void ns3::LogComponentEnable(char const * name, ns3::LogLevel level) [free function] + module.add_function('LogComponentEnable', + 'void', + [param('char *', 'name', transfer_ownership=False, is_const=True), param('ns3::LogLevel', 'level')]) + ## log.h: extern void ns3::LogComponentPrintList() [free function] + module.add_function('LogComponentPrintList', + 'void', + []) register_functions_ns3_internal(module.get_submodule('internal'), root_module) register_functions_ns3_TimeStepPrecision(module.get_submodule('TimeStepPrecision'), root_module) register_functions_ns3_Config(module.get_submodule('Config'), root_module) diff --git a/bindings/python/ns3_module_node.py b/bindings/python/ns3_module_node.py index 2bfdbe97a..5d3741594 100644 --- a/bindings/python/ns3_module_node.py +++ b/bindings/python/ns3_module_node.py @@ -73,6 +73,8 @@ def register_types(module): module.add_class('NetDevice', parent=root_module['ns3::Object']) ## net-device.h: ns3::NetDevice::PacketType [enumeration] module.add_enum('PacketType', ['PACKET_HOST', 'PACKET_BROADCAST', 'PACKET_MULTICAST', 'PACKET_OTHERHOST'], outer_class=root_module['ns3::NetDevice']) + ## drop-tail-queue.h: ns3::DropTailQueue [class] + module.add_class('DropTailQueue', parent=root_module['ns3::Queue']) ## address.h: ns3::AddressValue [class] module.add_class('AddressValue', parent=root_module['ns3::AttributeValue']) ## node.h: ns3::Node [class] @@ -89,18 +91,16 @@ def register_types(module): module.add_class('Ipv4', parent=root_module['ns3::Object']) ## socket-factory.h: ns3::SocketFactory [class] module.add_class('SocketFactory', parent=root_module['ns3::Object']) - ## drop-tail-queue.h: ns3::DropTailQueue [class] - module.add_class('DropTailQueue', parent=root_module['ns3::Queue']) ## ethernet-trailer.h: ns3::EthernetTrailer [class] module.add_class('EthernetTrailer', parent=root_module['ns3::Trailer']) + ## simple-channel.h: ns3::SimpleChannel [class] + module.add_class('SimpleChannel', parent=root_module['ns3::Channel']) ## llc-snap-header.h: ns3::LlcSnapHeader [class] module.add_class('LlcSnapHeader', parent=root_module['ns3::Header']) ## udp-socket-factory.h: ns3::UdpSocketFactory [class] module.add_class('UdpSocketFactory', parent=root_module['ns3::SocketFactory']) ## simple-net-device.h: ns3::SimpleNetDevice [class] module.add_class('SimpleNetDevice', parent=root_module['ns3::NetDevice']) - ## simple-channel.h: ns3::SimpleChannel [class] - module.add_class('SimpleChannel', parent=root_module['ns3::Channel']) ## tcp-socket-factory.h: ns3::TcpSocketFactory [class] module.add_class('TcpSocketFactory', parent=root_module['ns3::SocketFactory']) ## packet-socket-factory.h: ns3::PacketSocketFactory [class] @@ -173,6 +173,7 @@ def register_methods(root_module): register_Ns3Ipv4Header_methods(root_module, root_module['ns3::Ipv4Header']) register_Ns3UdpSocket_methods(root_module, root_module['ns3::UdpSocket']) register_Ns3NetDevice_methods(root_module, root_module['ns3::NetDevice']) + register_Ns3DropTailQueue_methods(root_module, root_module['ns3::DropTailQueue']) register_Ns3AddressValue_methods(root_module, root_module['ns3::AddressValue']) register_Ns3Node_methods(root_module, root_module['ns3::Node']) register_Ns3Channel_methods(root_module, root_module['ns3::Channel']) @@ -181,12 +182,11 @@ def register_methods(root_module): register_Ns3SocketIpTtlTag_methods(root_module, root_module['ns3::SocketIpTtlTag']) register_Ns3Ipv4_methods(root_module, root_module['ns3::Ipv4']) register_Ns3SocketFactory_methods(root_module, root_module['ns3::SocketFactory']) - register_Ns3DropTailQueue_methods(root_module, root_module['ns3::DropTailQueue']) register_Ns3EthernetTrailer_methods(root_module, root_module['ns3::EthernetTrailer']) + register_Ns3SimpleChannel_methods(root_module, root_module['ns3::SimpleChannel']) register_Ns3LlcSnapHeader_methods(root_module, root_module['ns3::LlcSnapHeader']) register_Ns3UdpSocketFactory_methods(root_module, root_module['ns3::UdpSocketFactory']) register_Ns3SimpleNetDevice_methods(root_module, root_module['ns3::SimpleNetDevice']) - register_Ns3SimpleChannel_methods(root_module, root_module['ns3::SimpleChannel']) register_Ns3TcpSocketFactory_methods(root_module, root_module['ns3::TcpSocketFactory']) register_Ns3PacketSocketFactory_methods(root_module, root_module['ns3::PacketSocketFactory']) return @@ -1572,6 +1572,31 @@ def register_Ns3NetDevice_methods(root_module, cls): cls.add_constructor([]) return +def register_Ns3DropTailQueue_methods(root_module, cls): + ## drop-tail-queue.h: static ns3::TypeId ns3::DropTailQueue::GetTypeId() [member function] + cls.add_method('GetTypeId', + 'ns3::TypeId', + [], + is_static=True) + ## drop-tail-queue.h: ns3::DropTailQueue::DropTailQueue() [constructor] + cls.add_constructor([]) + ## drop-tail-queue.h: bool ns3::DropTailQueue::DoEnqueue(ns3::Ptr p) [member function] + cls.add_method('DoEnqueue', + 'bool', + [param('ns3::Ptr< ns3::Packet >', 'p')], + visibility='private', is_virtual=True) + ## drop-tail-queue.h: ns3::Ptr ns3::DropTailQueue::DoDequeue() [member function] + cls.add_method('DoDequeue', + 'ns3::Ptr< ns3::Packet >', + [], + visibility='private', is_virtual=True) + ## drop-tail-queue.h: ns3::Ptr ns3::DropTailQueue::DoPeek() const [member function] + cls.add_method('DoPeek', + 'ns3::Ptr< ns3::Packet >', + [], + is_const=True, visibility='private', is_virtual=True) + return + def register_Ns3AddressValue_methods(root_module, cls): ## address.h: ns3::AddressValue::AddressValue() [constructor] cls.add_constructor([]) @@ -2147,31 +2172,6 @@ def register_Ns3SocketFactory_methods(root_module, cls): is_pure_virtual=True, is_virtual=True) return -def register_Ns3DropTailQueue_methods(root_module, cls): - ## drop-tail-queue.h: static ns3::TypeId ns3::DropTailQueue::GetTypeId() [member function] - cls.add_method('GetTypeId', - 'ns3::TypeId', - [], - is_static=True) - ## drop-tail-queue.h: ns3::DropTailQueue::DropTailQueue() [constructor] - cls.add_constructor([]) - ## drop-tail-queue.h: bool ns3::DropTailQueue::DoEnqueue(ns3::Ptr p) [member function] - cls.add_method('DoEnqueue', - 'bool', - [param('ns3::Ptr< ns3::Packet >', 'p')], - visibility='private', is_virtual=True) - ## drop-tail-queue.h: ns3::Ptr ns3::DropTailQueue::DoDequeue() [member function] - cls.add_method('DoDequeue', - 'ns3::Ptr< ns3::Packet >', - [], - visibility='private', is_virtual=True) - ## drop-tail-queue.h: ns3::Ptr ns3::DropTailQueue::DoPeek() const [member function] - cls.add_method('DoPeek', - 'ns3::Ptr< ns3::Packet >', - [], - is_const=True, visibility='private', is_virtual=True) - return - def register_Ns3EthernetTrailer_methods(root_module, cls): ## ethernet-trailer.h: ns3::EthernetTrailer::EthernetTrailer() [constructor] cls.add_constructor([]) @@ -2234,6 +2234,34 @@ def register_Ns3EthernetTrailer_methods(root_module, cls): is_virtual=True) return +def register_Ns3SimpleChannel_methods(root_module, cls): + ## simple-channel.h: static ns3::TypeId ns3::SimpleChannel::GetTypeId() [member function] + cls.add_method('GetTypeId', + 'ns3::TypeId', + [], + is_static=True) + ## simple-channel.h: ns3::SimpleChannel::SimpleChannel() [constructor] + cls.add_constructor([]) + ## simple-channel.h: void ns3::SimpleChannel::Send(ns3::Ptr p, uint16_t protocol, ns3::Mac48Address to, ns3::Mac48Address from, ns3::Ptr sender) [member function] + cls.add_method('Send', + 'void', + [param('ns3::Ptr< ns3::Packet >', 'p'), param('uint16_t', 'protocol'), param('ns3::Mac48Address', 'to'), param('ns3::Mac48Address', 'from'), param('ns3::Ptr< ns3::SimpleNetDevice >', 'sender')]) + ## simple-channel.h: void ns3::SimpleChannel::Add(ns3::Ptr device) [member function] + cls.add_method('Add', + 'void', + [param('ns3::Ptr< ns3::SimpleNetDevice >', 'device')]) + ## simple-channel.h: uint32_t ns3::SimpleChannel::GetNDevices() const [member function] + cls.add_method('GetNDevices', + 'uint32_t', + [], + is_const=True, is_virtual=True) + ## simple-channel.h: ns3::Ptr ns3::SimpleChannel::GetDevice(uint32_t i) const [member function] + cls.add_method('GetDevice', + 'ns3::Ptr< ns3::NetDevice >', + [param('uint32_t', 'i')], + is_const=True, is_virtual=True) + return + def register_Ns3LlcSnapHeader_methods(root_module, cls): ## llc-snap-header.h: ns3::LlcSnapHeader::LlcSnapHeader() [constructor] cls.add_constructor([]) @@ -2423,34 +2451,6 @@ def register_Ns3SimpleNetDevice_methods(root_module, cls): visibility='protected', is_virtual=True) return -def register_Ns3SimpleChannel_methods(root_module, cls): - ## simple-channel.h: static ns3::TypeId ns3::SimpleChannel::GetTypeId() [member function] - cls.add_method('GetTypeId', - 'ns3::TypeId', - [], - is_static=True) - ## simple-channel.h: ns3::SimpleChannel::SimpleChannel() [constructor] - cls.add_constructor([]) - ## simple-channel.h: void ns3::SimpleChannel::Send(ns3::Ptr p, uint16_t protocol, ns3::Mac48Address to, ns3::Mac48Address from, ns3::Ptr sender) [member function] - cls.add_method('Send', - 'void', - [param('ns3::Ptr< ns3::Packet >', 'p'), param('uint16_t', 'protocol'), param('ns3::Mac48Address', 'to'), param('ns3::Mac48Address', 'from'), param('ns3::Ptr< ns3::SimpleNetDevice >', 'sender')]) - ## simple-channel.h: void ns3::SimpleChannel::Add(ns3::Ptr device) [member function] - cls.add_method('Add', - 'void', - [param('ns3::Ptr< ns3::SimpleNetDevice >', 'device')]) - ## simple-channel.h: uint32_t ns3::SimpleChannel::GetNDevices() const [member function] - cls.add_method('GetNDevices', - 'uint32_t', - [], - is_const=True, is_virtual=True) - ## simple-channel.h: ns3::Ptr ns3::SimpleChannel::GetDevice(uint32_t i) const [member function] - cls.add_method('GetDevice', - 'ns3::Ptr< ns3::NetDevice >', - [param('uint32_t', 'i')], - is_const=True, is_virtual=True) - return - def register_Ns3TcpSocketFactory_methods(root_module, cls): ## tcp-socket-factory.h: static ns3::TypeId ns3::TcpSocketFactory::GetTypeId() [member function] cls.add_method('GetTypeId', diff --git a/bindings/python/ns3_module_simulator.py b/bindings/python/ns3_module_simulator.py index 768adf504..923df6ad4 100644 --- a/bindings/python/ns3_module_simulator.py +++ b/bindings/python/ns3_module_simulator.py @@ -33,6 +33,10 @@ def register_types(module): module.add_class('EventKey', outer_class=root_module['ns3::Scheduler']) ## nstime.h: ns3::TimeValue [class] module.add_class('TimeValue', parent=root_module['ns3::AttributeValue']) + ## simulator-impl.h: ns3::SimulatorImpl [class] + module.add_class('SimulatorImpl', parent=root_module['ns3::Object']) + ## default-simulator-impl.h: ns3::DefaultSimulatorImpl [class] + module.add_class('DefaultSimulatorImpl', parent=root_module['ns3::SimulatorImpl']) ## heap-scheduler.h: ns3::HeapScheduler [class] module.add_class('HeapScheduler', parent=root_module['ns3::Scheduler']) ## list-scheduler.h: ns3::ListScheduler [class] @@ -96,6 +100,8 @@ def register_methods(root_module): register_Ns3Scheduler_methods(root_module, root_module['ns3::Scheduler']) register_Ns3SchedulerEventKey_methods(root_module, root_module['ns3::Scheduler::EventKey']) register_Ns3TimeValue_methods(root_module, root_module['ns3::TimeValue']) + register_Ns3SimulatorImpl_methods(root_module, root_module['ns3::SimulatorImpl']) + register_Ns3DefaultSimulatorImpl_methods(root_module, root_module['ns3::DefaultSimulatorImpl']) register_Ns3HeapScheduler_methods(root_module, root_module['ns3::HeapScheduler']) register_Ns3ListScheduler_methods(root_module, root_module['ns3::ListScheduler']) register_Ns3MapScheduler_methods(root_module, root_module['ns3::MapScheduler']) @@ -326,6 +332,11 @@ def register_Ns3Watchdog_methods(root_module, cls): return def register_Ns3Simulator_methods(root_module, cls): + ## simulator.h: static void ns3::Simulator::SetImplementation(ns3::Ptr impl) [member function] + #cls.add_method('SetImplementation', + # 'void', + # [param('ns3::Ptr< ns3::SimulatorImpl >', 'impl')], + # is_static=True) ## simulator.h: static void ns3::Simulator::SetScheduler(ns3::Ptr scheduler) [member function] cls.add_method('SetScheduler', 'void', @@ -597,6 +608,200 @@ def register_Ns3TimeValue_methods(root_module, cls): is_virtual=True) return +def register_Ns3SimulatorImpl_methods(root_module, cls): + ## simulator-impl.h: void ns3::SimulatorImpl::Destroy() [member function] + cls.add_method('Destroy', + 'void', + [], + is_pure_virtual=True, is_virtual=True) + ## simulator-impl.h: void ns3::SimulatorImpl::EnableLogTo(char const * filename) [member function] + cls.add_method('EnableLogTo', + 'void', + [param('char *', 'filename', transfer_ownership=False, is_const=True)], + is_pure_virtual=True, is_virtual=True) + ## simulator-impl.h: bool ns3::SimulatorImpl::IsFinished() const [member function] + cls.add_method('IsFinished', + 'bool', + [], + is_pure_virtual=True, is_const=True, is_virtual=True) + ## simulator-impl.h: ns3::Time ns3::SimulatorImpl::Next() const [member function] + cls.add_method('Next', + 'ns3::Time', + [], + is_pure_virtual=True, is_const=True, is_virtual=True) + ## simulator-impl.h: void ns3::SimulatorImpl::Stop() [member function] + cls.add_method('Stop', + 'void', + [], + is_pure_virtual=True, is_virtual=True) + ## simulator-impl.h: void ns3::SimulatorImpl::Stop(ns3::Time const & time) [member function] + cls.add_method('Stop', + 'void', + [param('ns3::Time&', 'time', is_const=True)], + is_pure_virtual=True, is_virtual=True) + ## simulator-impl.h: ns3::EventId ns3::SimulatorImpl::Schedule(ns3::Time const & time, ns3::Ptr const & event) [member function] + cls.add_method('Schedule', + 'ns3::EventId', + [param('ns3::Time&', 'time', is_const=True), param('ns3::Ptr< ns3::EventImpl >&', 'event', is_const=True)], + is_pure_virtual=True, is_virtual=True) + ## simulator-impl.h: ns3::EventId ns3::SimulatorImpl::ScheduleNow(ns3::Ptr const & event) [member function] + cls.add_method('ScheduleNow', + 'ns3::EventId', + [param('ns3::Ptr< ns3::EventImpl >&', 'event', is_const=True)], + is_pure_virtual=True, is_virtual=True) + ## simulator-impl.h: ns3::EventId ns3::SimulatorImpl::ScheduleDestroy(ns3::Ptr const & event) [member function] + cls.add_method('ScheduleDestroy', + 'ns3::EventId', + [param('ns3::Ptr< ns3::EventImpl >&', 'event', is_const=True)], + is_pure_virtual=True, is_virtual=True) + ## simulator-impl.h: void ns3::SimulatorImpl::Remove(ns3::EventId const & ev) [member function] + cls.add_method('Remove', + 'void', + [param('ns3::EventId&', 'ev', is_const=True)], + is_pure_virtual=True, is_virtual=True) + ## simulator-impl.h: void ns3::SimulatorImpl::Cancel(ns3::EventId const & ev) [member function] + cls.add_method('Cancel', + 'void', + [param('ns3::EventId&', 'ev', is_const=True)], + is_pure_virtual=True, is_virtual=True) + ## simulator-impl.h: bool ns3::SimulatorImpl::IsExpired(ns3::EventId const & ev) const [member function] + cls.add_method('IsExpired', + 'bool', + [param('ns3::EventId&', 'ev', is_const=True)], + is_pure_virtual=True, is_const=True, is_virtual=True) + ## simulator-impl.h: void ns3::SimulatorImpl::Run() [member function] + cls.add_method('Run', + 'void', + [], + is_pure_virtual=True, is_virtual=True) + ## simulator-impl.h: ns3::Time ns3::SimulatorImpl::Now() const [member function] + cls.add_method('Now', + 'ns3::Time', + [], + is_pure_virtual=True, is_const=True, is_virtual=True) + ## simulator-impl.h: ns3::Time ns3::SimulatorImpl::GetDelayLeft(ns3::EventId const & id) const [member function] + cls.add_method('GetDelayLeft', + 'ns3::Time', + [param('ns3::EventId&', 'id', is_const=True)], + is_pure_virtual=True, is_const=True, is_virtual=True) + ## simulator-impl.h: ns3::Time ns3::SimulatorImpl::GetMaximumSimulationTime() const [member function] + cls.add_method('GetMaximumSimulationTime', + 'ns3::Time', + [], + is_pure_virtual=True, is_const=True, is_virtual=True) + ## simulator-impl.h: void ns3::SimulatorImpl::SetScheduler(ns3::Ptr scheduler) [member function] + cls.add_method('SetScheduler', + 'void', + [param('ns3::Ptr< ns3::Scheduler >', 'scheduler')], + is_pure_virtual=True, is_virtual=True) + ## simulator-impl.h: ns3::Ptr ns3::SimulatorImpl::GetScheduler() const [member function] + cls.add_method('GetScheduler', + 'ns3::Ptr< ns3::Scheduler >', + [], + is_pure_virtual=True, is_const=True, is_virtual=True) + cls.add_constructor([]) + return + +def register_Ns3DefaultSimulatorImpl_methods(root_module, cls): + ## default-simulator-impl.h: static ns3::TypeId ns3::DefaultSimulatorImpl::GetTypeId() [member function] + cls.add_method('GetTypeId', + 'ns3::TypeId', + [], + is_static=True) + ## default-simulator-impl.h: ns3::DefaultSimulatorImpl::DefaultSimulatorImpl() [constructor] + cls.add_constructor([]) + ## default-simulator-impl.h: void ns3::DefaultSimulatorImpl::Destroy() [member function] + cls.add_method('Destroy', + 'void', + [], + is_virtual=True) + ## default-simulator-impl.h: void ns3::DefaultSimulatorImpl::EnableLogTo(char const * filename) [member function] + cls.add_method('EnableLogTo', + 'void', + [param('char *', 'filename', transfer_ownership=False, is_const=True)], + is_virtual=True) + ## default-simulator-impl.h: bool ns3::DefaultSimulatorImpl::IsFinished() const [member function] + cls.add_method('IsFinished', + 'bool', + [], + is_const=True, is_virtual=True) + ## default-simulator-impl.h: ns3::Time ns3::DefaultSimulatorImpl::Next() const [member function] + cls.add_method('Next', + 'ns3::Time', + [], + is_const=True, is_virtual=True) + ## default-simulator-impl.h: void ns3::DefaultSimulatorImpl::Stop() [member function] + cls.add_method('Stop', + 'void', + [], + is_virtual=True) + ## default-simulator-impl.h: void ns3::DefaultSimulatorImpl::Stop(ns3::Time const & time) [member function] + cls.add_method('Stop', + 'void', + [param('ns3::Time&', 'time', is_const=True)], + is_virtual=True) + ## default-simulator-impl.h: ns3::EventId ns3::DefaultSimulatorImpl::Schedule(ns3::Time const & time, ns3::Ptr const & event) [member function] + cls.add_method('Schedule', + 'ns3::EventId', + [param('ns3::Time&', 'time', is_const=True), param('ns3::Ptr< ns3::EventImpl >&', 'event', is_const=True)], + is_virtual=True) + ## default-simulator-impl.h: ns3::EventId ns3::DefaultSimulatorImpl::ScheduleNow(ns3::Ptr const & event) [member function] + cls.add_method('ScheduleNow', + 'ns3::EventId', + [param('ns3::Ptr< ns3::EventImpl >&', 'event', is_const=True)], + is_virtual=True) + ## default-simulator-impl.h: ns3::EventId ns3::DefaultSimulatorImpl::ScheduleDestroy(ns3::Ptr const & event) [member function] + cls.add_method('ScheduleDestroy', + 'ns3::EventId', + [param('ns3::Ptr< ns3::EventImpl >&', 'event', is_const=True)], + is_virtual=True) + ## default-simulator-impl.h: void ns3::DefaultSimulatorImpl::Remove(ns3::EventId const & ev) [member function] + cls.add_method('Remove', + 'void', + [param('ns3::EventId&', 'ev', is_const=True)], + is_virtual=True) + ## default-simulator-impl.h: void ns3::DefaultSimulatorImpl::Cancel(ns3::EventId const & ev) [member function] + cls.add_method('Cancel', + 'void', + [param('ns3::EventId&', 'ev', is_const=True)], + is_virtual=True) + ## default-simulator-impl.h: bool ns3::DefaultSimulatorImpl::IsExpired(ns3::EventId const & ev) const [member function] + cls.add_method('IsExpired', + 'bool', + [param('ns3::EventId&', 'ev', is_const=True)], + is_const=True, is_virtual=True) + ## default-simulator-impl.h: void ns3::DefaultSimulatorImpl::Run() [member function] + cls.add_method('Run', + 'void', + [], + is_virtual=True) + ## default-simulator-impl.h: ns3::Time ns3::DefaultSimulatorImpl::Now() const [member function] + cls.add_method('Now', + 'ns3::Time', + [], + is_const=True, is_virtual=True) + ## default-simulator-impl.h: ns3::Time ns3::DefaultSimulatorImpl::GetDelayLeft(ns3::EventId const & id) const [member function] + cls.add_method('GetDelayLeft', + 'ns3::Time', + [param('ns3::EventId&', 'id', is_const=True)], + is_const=True, is_virtual=True) + ## default-simulator-impl.h: ns3::Time ns3::DefaultSimulatorImpl::GetMaximumSimulationTime() const [member function] + cls.add_method('GetMaximumSimulationTime', + 'ns3::Time', + [], + is_const=True, is_virtual=True) + ## default-simulator-impl.h: void ns3::DefaultSimulatorImpl::SetScheduler(ns3::Ptr scheduler) [member function] + cls.add_method('SetScheduler', + 'void', + [param('ns3::Ptr< ns3::Scheduler >', 'scheduler')], + is_virtual=True) + ## default-simulator-impl.h: ns3::Ptr ns3::DefaultSimulatorImpl::GetScheduler() const [member function] + cls.add_method('GetScheduler', + 'ns3::Ptr< ns3::Scheduler >', + [], + is_const=True, is_virtual=True) + return + def register_Ns3HeapScheduler_methods(root_module, cls): ## heap-scheduler.h: ns3::HeapScheduler::HeapScheduler() [constructor] cls.add_constructor([]) diff --git a/bindings/python/ns3_module_wifi.py b/bindings/python/ns3_module_wifi.py index 14c660114..6ba85ee09 100644 --- a/bindings/python/ns3_module_wifi.py +++ b/bindings/python/ns3_module_wifi.py @@ -45,12 +45,14 @@ def register_types(module): module.add_class('WifiMac', parent=root_module['ns3::Object']) ## nqap-wifi-mac.h: ns3::NqapWifiMac [class] module.add_class('NqapWifiMac', parent=root_module['ns3::WifiMac']) - ## amrr-wifi-manager.h: ns3::AmrrWifiRemoteStation [class] - module.add_class('AmrrWifiRemoteStation', parent=root_module['ns3::WifiRemoteStation']) ## composite-propagation-loss-model.h: ns3::CompositePropagationLossModel [class] module.add_class('CompositePropagationLossModel', parent=root_module['ns3::PropagationLossModel']) + ## amrr-wifi-manager.h: ns3::AmrrWifiRemoteStation [class] + module.add_class('AmrrWifiRemoteStation', parent=root_module['ns3::WifiRemoteStation']) ## propagation-loss-model.h: ns3::FriisPropagationLossModel [class] module.add_class('FriisPropagationLossModel', parent=root_module['ns3::PropagationLossModel']) + ## nqsta-wifi-mac.h: ns3::NqstaWifiMac [class] + module.add_class('NqstaWifiMac', parent=root_module['ns3::WifiMac']) ## wifi-remote-station-manager.h: ns3::WifiRemoteStationManager [class] module.add_class('WifiRemoteStationManager', parent=root_module['ns3::Object']) ## wifi-mode.h: ns3::WifiModeValue [class] @@ -75,12 +77,10 @@ def register_types(module): module.add_class('AdhocWifiMac', parent=root_module['ns3::WifiMac']) ## jakes-propagation-loss-model.h: ns3::JakesPropagationLossModel [class] module.add_class('JakesPropagationLossModel', parent=root_module['ns3::PropagationLossModel']) - ## propagation-delay-model.h: ns3::ConstantSpeedPropagationDelayModel [class] - module.add_class('ConstantSpeedPropagationDelayModel', parent=root_module['ns3::PropagationDelayModel']) ## wifi-net-device.h: ns3::WifiNetDevice [class] module.add_class('WifiNetDevice', parent=root_module['ns3::NetDevice']) - ## nqsta-wifi-mac.h: ns3::NqstaWifiMac [class] - module.add_class('NqstaWifiMac', parent=root_module['ns3::WifiMac']) + ## propagation-delay-model.h: ns3::ConstantSpeedPropagationDelayModel [class] + module.add_class('ConstantSpeedPropagationDelayModel', parent=root_module['ns3::PropagationDelayModel']) ## propagation-loss-model.h: ns3::RandomPropagationLossModel [class] module.add_class('RandomPropagationLossModel', parent=root_module['ns3::PropagationLossModel']) ## propagation-delay-model.h: ns3::RandomPropagationDelayModel [class] @@ -155,9 +155,10 @@ def register_methods(root_module): register_Ns3ArfWifiRemoteStation_methods(root_module, root_module['ns3::ArfWifiRemoteStation']) register_Ns3WifiMac_methods(root_module, root_module['ns3::WifiMac']) register_Ns3NqapWifiMac_methods(root_module, root_module['ns3::NqapWifiMac']) - register_Ns3AmrrWifiRemoteStation_methods(root_module, root_module['ns3::AmrrWifiRemoteStation']) register_Ns3CompositePropagationLossModel_methods(root_module, root_module['ns3::CompositePropagationLossModel']) + register_Ns3AmrrWifiRemoteStation_methods(root_module, root_module['ns3::AmrrWifiRemoteStation']) register_Ns3FriisPropagationLossModel_methods(root_module, root_module['ns3::FriisPropagationLossModel']) + register_Ns3NqstaWifiMac_methods(root_module, root_module['ns3::NqstaWifiMac']) register_Ns3WifiRemoteStationManager_methods(root_module, root_module['ns3::WifiRemoteStationManager']) register_Ns3WifiModeValue_methods(root_module, root_module['ns3::WifiModeValue']) register_Ns3OnoeWifiManager_methods(root_module, root_module['ns3::OnoeWifiManager']) @@ -169,9 +170,8 @@ def register_methods(root_module): register_Ns3PropagationDelayModel_methods(root_module, root_module['ns3::PropagationDelayModel']) register_Ns3AdhocWifiMac_methods(root_module, root_module['ns3::AdhocWifiMac']) register_Ns3JakesPropagationLossModel_methods(root_module, root_module['ns3::JakesPropagationLossModel']) - register_Ns3ConstantSpeedPropagationDelayModel_methods(root_module, root_module['ns3::ConstantSpeedPropagationDelayModel']) register_Ns3WifiNetDevice_methods(root_module, root_module['ns3::WifiNetDevice']) - register_Ns3NqstaWifiMac_methods(root_module, root_module['ns3::NqstaWifiMac']) + register_Ns3ConstantSpeedPropagationDelayModel_methods(root_module, root_module['ns3::ConstantSpeedPropagationDelayModel']) register_Ns3RandomPropagationLossModel_methods(root_module, root_module['ns3::RandomPropagationLossModel']) register_Ns3RandomPropagationDelayModel_methods(root_module, root_module['ns3::RandomPropagationDelayModel']) register_Ns3AmrrWifiManager_methods(root_module, root_module['ns3::AmrrWifiManager']) @@ -1207,6 +1207,30 @@ def register_Ns3NqapWifiMac_methods(root_module, cls): visibility='private', is_virtual=True) return +def register_Ns3CompositePropagationLossModel_methods(root_module, cls): + ## composite-propagation-loss-model.h: static ns3::TypeId ns3::CompositePropagationLossModel::GetTypeId() [member function] + cls.add_method('GetTypeId', + 'ns3::TypeId', + [], + is_static=True) + ## composite-propagation-loss-model.h: ns3::CompositePropagationLossModel::CompositePropagationLossModel() [constructor] + cls.add_constructor([]) + ## composite-propagation-loss-model.h: double ns3::CompositePropagationLossModel::GetLoss(ns3::Ptr a, ns3::Ptr b) const [member function] + cls.add_method('GetLoss', + 'double', + [param('ns3::Ptr< ns3::MobilityModel >', 'a'), param('ns3::Ptr< ns3::MobilityModel >', 'b')], + is_const=True, is_virtual=True) + ## composite-propagation-loss-model.h: void ns3::CompositePropagationLossModel::AddPropagationLossModel(ns3::Ptr pl) [member function] + cls.add_method('AddPropagationLossModel', + 'void', + [param('ns3::Ptr< ns3::PropagationLossModel >', 'pl')]) + ## composite-propagation-loss-model.h: void ns3::CompositePropagationLossModel::AddDefaults() [member function] + cls.add_method('AddDefaults', + 'void', + [], + visibility='protected', is_virtual=True) + return + def register_Ns3AmrrWifiRemoteStation_methods(root_module, cls): ## amrr-wifi-manager.h: ns3::AmrrWifiRemoteStation::AmrrWifiRemoteStation(ns3::Ptr stations) [constructor] cls.add_constructor([param('ns3::Ptr< ns3::AmrrWifiManager >', 'stations')]) @@ -1262,30 +1286,6 @@ def register_Ns3AmrrWifiRemoteStation_methods(root_module, cls): visibility='private', is_virtual=True) return -def register_Ns3CompositePropagationLossModel_methods(root_module, cls): - ## composite-propagation-loss-model.h: static ns3::TypeId ns3::CompositePropagationLossModel::GetTypeId() [member function] - cls.add_method('GetTypeId', - 'ns3::TypeId', - [], - is_static=True) - ## composite-propagation-loss-model.h: ns3::CompositePropagationLossModel::CompositePropagationLossModel() [constructor] - cls.add_constructor([]) - ## composite-propagation-loss-model.h: double ns3::CompositePropagationLossModel::GetLoss(ns3::Ptr a, ns3::Ptr b) const [member function] - cls.add_method('GetLoss', - 'double', - [param('ns3::Ptr< ns3::MobilityModel >', 'a'), param('ns3::Ptr< ns3::MobilityModel >', 'b')], - is_const=True, is_virtual=True) - ## composite-propagation-loss-model.h: void ns3::CompositePropagationLossModel::AddPropagationLossModel(ns3::Ptr pl) [member function] - cls.add_method('AddPropagationLossModel', - 'void', - [param('ns3::Ptr< ns3::PropagationLossModel >', 'pl')]) - ## composite-propagation-loss-model.h: void ns3::CompositePropagationLossModel::AddDefaults() [member function] - cls.add_method('AddDefaults', - 'void', - [], - visibility='protected', is_virtual=True) - return - def register_Ns3FriisPropagationLossModel_methods(root_module, cls): ## propagation-loss-model.h: static ns3::TypeId ns3::FriisPropagationLossModel::GetTypeId() [member function] cls.add_method('GetTypeId', @@ -1332,6 +1332,122 @@ def register_Ns3FriisPropagationLossModel_methods(root_module, cls): is_const=True, is_virtual=True) return +def register_Ns3NqstaWifiMac_methods(root_module, cls): + ## nqsta-wifi-mac.h: static ns3::TypeId ns3::NqstaWifiMac::GetTypeId() [member function] + cls.add_method('GetTypeId', + 'ns3::TypeId', + [], + is_static=True) + ## nqsta-wifi-mac.h: ns3::NqstaWifiMac::NqstaWifiMac() [constructor] + cls.add_constructor([]) + ## nqsta-wifi-mac.h: void ns3::NqstaWifiMac::SetSlot(ns3::Time slotTime) [member function] + cls.add_method('SetSlot', + 'void', + [param('ns3::Time', 'slotTime')], + is_virtual=True) + ## nqsta-wifi-mac.h: void ns3::NqstaWifiMac::SetSifs(ns3::Time sifs) [member function] + cls.add_method('SetSifs', + 'void', + [param('ns3::Time', 'sifs')], + is_virtual=True) + ## nqsta-wifi-mac.h: void ns3::NqstaWifiMac::SetEifsNoDifs(ns3::Time eifsNoDifs) [member function] + cls.add_method('SetEifsNoDifs', + 'void', + [param('ns3::Time', 'eifsNoDifs')], + is_virtual=True) + ## nqsta-wifi-mac.h: ns3::Time ns3::NqstaWifiMac::GetSlot() const [member function] + cls.add_method('GetSlot', + 'ns3::Time', + [], + is_const=True, is_virtual=True) + ## nqsta-wifi-mac.h: ns3::Time ns3::NqstaWifiMac::GetSifs() const [member function] + cls.add_method('GetSifs', + 'ns3::Time', + [], + is_const=True, is_virtual=True) + ## nqsta-wifi-mac.h: ns3::Time ns3::NqstaWifiMac::GetEifsNoDifs() const [member function] + cls.add_method('GetEifsNoDifs', + 'ns3::Time', + [], + is_const=True, is_virtual=True) + ## nqsta-wifi-mac.h: void ns3::NqstaWifiMac::SetWifiPhy(ns3::Ptr phy) [member function] + cls.add_method('SetWifiPhy', + 'void', + [param('ns3::Ptr< ns3::WifiPhy >', 'phy')], + is_virtual=True) + ## nqsta-wifi-mac.h: void ns3::NqstaWifiMac::SetWifiRemoteStationManager(ns3::Ptr stationManager) [member function] + cls.add_method('SetWifiRemoteStationManager', + 'void', + [param('ns3::Ptr< ns3::WifiRemoteStationManager >', 'stationManager')], + is_virtual=True) + ## nqsta-wifi-mac.h: void ns3::NqstaWifiMac::Enqueue(ns3::Ptr packet, ns3::Mac48Address to) [member function] + cls.add_method('Enqueue', + 'void', + [param('ns3::Ptr< const ns3::Packet >', 'packet'), param('ns3::Mac48Address', 'to')], + is_virtual=True) + ## nqsta-wifi-mac.h: void ns3::NqstaWifiMac::SetForwardUpCallback(ns3::Callback, ns3::Mac48Address const&, ns3::empty, ns3::empty, ns3::empty, ns3::empty> upCallback) [member function] + cls.add_method('SetForwardUpCallback', + 'void', + [param('ns3::Callback< void, ns3::Ptr< ns3::Packet >, ns3::Mac48Address const&, ns3::empty, ns3::empty, ns3::empty, ns3::empty >', 'upCallback')], + is_virtual=True) + ## nqsta-wifi-mac.h: void ns3::NqstaWifiMac::SetLinkUpCallback(ns3::Callback linkUp) [member function] + cls.add_method('SetLinkUpCallback', + 'void', + [param('ns3::Callback< void, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty >', 'linkUp')], + is_virtual=True) + ## nqsta-wifi-mac.h: void ns3::NqstaWifiMac::SetLinkDownCallback(ns3::Callback linkDown) [member function] + cls.add_method('SetLinkDownCallback', + 'void', + [param('ns3::Callback< void, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty >', 'linkDown')], + is_virtual=True) + ## nqsta-wifi-mac.h: ns3::Mac48Address ns3::NqstaWifiMac::GetAddress() const [member function] + cls.add_method('GetAddress', + 'ns3::Mac48Address', + [], + is_const=True, is_virtual=True) + ## nqsta-wifi-mac.h: ns3::Ssid ns3::NqstaWifiMac::GetSsid() const [member function] + cls.add_method('GetSsid', + 'ns3::Ssid', + [], + is_const=True, is_virtual=True) + ## nqsta-wifi-mac.h: ns3::Mac48Address ns3::NqstaWifiMac::GetBssid() const [member function] + cls.add_method('GetBssid', + 'ns3::Mac48Address', + [], + is_const=True, is_virtual=True) + ## nqsta-wifi-mac.h: void ns3::NqstaWifiMac::SetAddress(ns3::Mac48Address address) [member function] + cls.add_method('SetAddress', + 'void', + [param('ns3::Mac48Address', 'address')], + is_virtual=True) + ## nqsta-wifi-mac.h: void ns3::NqstaWifiMac::SetSsid(ns3::Ssid ssid) [member function] + cls.add_method('SetSsid', + 'void', + [param('ns3::Ssid', 'ssid')], + is_virtual=True) + ## nqsta-wifi-mac.h: void ns3::NqstaWifiMac::SetMaxMissedBeacons(uint32_t missed) [member function] + cls.add_method('SetMaxMissedBeacons', + 'void', + [param('uint32_t', 'missed')]) + ## nqsta-wifi-mac.h: void ns3::NqstaWifiMac::SetProbeRequestTimeout(ns3::Time timeout) [member function] + cls.add_method('SetProbeRequestTimeout', + 'void', + [param('ns3::Time', 'timeout')]) + ## nqsta-wifi-mac.h: void ns3::NqstaWifiMac::SetAssocRequestTimeout(ns3::Time timeout) [member function] + cls.add_method('SetAssocRequestTimeout', + 'void', + [param('ns3::Time', 'timeout')]) + ## nqsta-wifi-mac.h: void ns3::NqstaWifiMac::StartActiveAssociation() [member function] + cls.add_method('StartActiveAssociation', + 'void', + []) + ## nqsta-wifi-mac.h: void ns3::NqstaWifiMac::DoDispose() [member function] + cls.add_method('DoDispose', + 'void', + [], + visibility='private', is_virtual=True) + return + def register_Ns3WifiRemoteStationManager_methods(root_module, cls): ## wifi-remote-station-manager.h: static ns3::TypeId ns3::WifiRemoteStationManager::GetTypeId() [member function] cls.add_method('GetTypeId', @@ -1895,30 +2011,6 @@ def register_Ns3JakesPropagationLossModel_methods(root_module, cls): [param('uint8_t', 'nOscillators')]) return -def register_Ns3ConstantSpeedPropagationDelayModel_methods(root_module, cls): - ## propagation-delay-model.h: static ns3::TypeId ns3::ConstantSpeedPropagationDelayModel::GetTypeId() [member function] - cls.add_method('GetTypeId', - 'ns3::TypeId', - [], - is_static=True) - ## propagation-delay-model.h: ns3::ConstantSpeedPropagationDelayModel::ConstantSpeedPropagationDelayModel() [constructor] - cls.add_constructor([]) - ## propagation-delay-model.h: ns3::Time ns3::ConstantSpeedPropagationDelayModel::GetDelay(ns3::Ptr a, ns3::Ptr b) const [member function] - cls.add_method('GetDelay', - 'ns3::Time', - [param('ns3::Ptr< ns3::MobilityModel >', 'a'), param('ns3::Ptr< ns3::MobilityModel >', 'b')], - is_const=True, is_virtual=True) - ## propagation-delay-model.h: void ns3::ConstantSpeedPropagationDelayModel::SetSpeed(double speed) [member function] - cls.add_method('SetSpeed', - 'void', - [param('double', 'speed')]) - ## propagation-delay-model.h: double ns3::ConstantSpeedPropagationDelayModel::GetSpeed() const [member function] - cls.add_method('GetSpeed', - 'double', - [], - is_const=True) - return - def register_Ns3WifiNetDevice_methods(root_module, cls): ## wifi-net-device.h: static ns3::TypeId ns3::WifiNetDevice::GetTypeId() [member function] cls.add_method('GetTypeId', @@ -2070,120 +2162,28 @@ def register_Ns3WifiNetDevice_methods(root_module, cls): visibility='private', is_virtual=True) return -def register_Ns3NqstaWifiMac_methods(root_module, cls): - ## nqsta-wifi-mac.h: static ns3::TypeId ns3::NqstaWifiMac::GetTypeId() [member function] +def register_Ns3ConstantSpeedPropagationDelayModel_methods(root_module, cls): + ## propagation-delay-model.h: static ns3::TypeId ns3::ConstantSpeedPropagationDelayModel::GetTypeId() [member function] cls.add_method('GetTypeId', 'ns3::TypeId', [], is_static=True) - ## nqsta-wifi-mac.h: ns3::NqstaWifiMac::NqstaWifiMac() [constructor] + ## propagation-delay-model.h: ns3::ConstantSpeedPropagationDelayModel::ConstantSpeedPropagationDelayModel() [constructor] cls.add_constructor([]) - ## nqsta-wifi-mac.h: void ns3::NqstaWifiMac::SetSlot(ns3::Time slotTime) [member function] - cls.add_method('SetSlot', - 'void', - [param('ns3::Time', 'slotTime')], - is_virtual=True) - ## nqsta-wifi-mac.h: void ns3::NqstaWifiMac::SetSifs(ns3::Time sifs) [member function] - cls.add_method('SetSifs', - 'void', - [param('ns3::Time', 'sifs')], - is_virtual=True) - ## nqsta-wifi-mac.h: void ns3::NqstaWifiMac::SetEifsNoDifs(ns3::Time eifsNoDifs) [member function] - cls.add_method('SetEifsNoDifs', - 'void', - [param('ns3::Time', 'eifsNoDifs')], - is_virtual=True) - ## nqsta-wifi-mac.h: ns3::Time ns3::NqstaWifiMac::GetSlot() const [member function] - cls.add_method('GetSlot', + ## propagation-delay-model.h: ns3::Time ns3::ConstantSpeedPropagationDelayModel::GetDelay(ns3::Ptr a, ns3::Ptr b) const [member function] + cls.add_method('GetDelay', 'ns3::Time', - [], + [param('ns3::Ptr< ns3::MobilityModel >', 'a'), param('ns3::Ptr< ns3::MobilityModel >', 'b')], is_const=True, is_virtual=True) - ## nqsta-wifi-mac.h: ns3::Time ns3::NqstaWifiMac::GetSifs() const [member function] - cls.add_method('GetSifs', - 'ns3::Time', + ## propagation-delay-model.h: void ns3::ConstantSpeedPropagationDelayModel::SetSpeed(double speed) [member function] + cls.add_method('SetSpeed', + 'void', + [param('double', 'speed')]) + ## propagation-delay-model.h: double ns3::ConstantSpeedPropagationDelayModel::GetSpeed() const [member function] + cls.add_method('GetSpeed', + 'double', [], - is_const=True, is_virtual=True) - ## nqsta-wifi-mac.h: ns3::Time ns3::NqstaWifiMac::GetEifsNoDifs() const [member function] - cls.add_method('GetEifsNoDifs', - 'ns3::Time', - [], - is_const=True, is_virtual=True) - ## nqsta-wifi-mac.h: void ns3::NqstaWifiMac::SetWifiPhy(ns3::Ptr phy) [member function] - cls.add_method('SetWifiPhy', - 'void', - [param('ns3::Ptr< ns3::WifiPhy >', 'phy')], - is_virtual=True) - ## nqsta-wifi-mac.h: void ns3::NqstaWifiMac::SetWifiRemoteStationManager(ns3::Ptr stationManager) [member function] - cls.add_method('SetWifiRemoteStationManager', - 'void', - [param('ns3::Ptr< ns3::WifiRemoteStationManager >', 'stationManager')], - is_virtual=True) - ## nqsta-wifi-mac.h: void ns3::NqstaWifiMac::Enqueue(ns3::Ptr packet, ns3::Mac48Address to) [member function] - cls.add_method('Enqueue', - 'void', - [param('ns3::Ptr< const ns3::Packet >', 'packet'), param('ns3::Mac48Address', 'to')], - is_virtual=True) - ## nqsta-wifi-mac.h: void ns3::NqstaWifiMac::SetForwardUpCallback(ns3::Callback, ns3::Mac48Address const&, ns3::empty, ns3::empty, ns3::empty, ns3::empty> upCallback) [member function] - cls.add_method('SetForwardUpCallback', - 'void', - [param('ns3::Callback< void, ns3::Ptr< ns3::Packet >, ns3::Mac48Address const&, ns3::empty, ns3::empty, ns3::empty, ns3::empty >', 'upCallback')], - is_virtual=True) - ## nqsta-wifi-mac.h: void ns3::NqstaWifiMac::SetLinkUpCallback(ns3::Callback linkUp) [member function] - cls.add_method('SetLinkUpCallback', - 'void', - [param('ns3::Callback< void, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty >', 'linkUp')], - is_virtual=True) - ## nqsta-wifi-mac.h: void ns3::NqstaWifiMac::SetLinkDownCallback(ns3::Callback linkDown) [member function] - cls.add_method('SetLinkDownCallback', - 'void', - [param('ns3::Callback< void, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty >', 'linkDown')], - is_virtual=True) - ## nqsta-wifi-mac.h: ns3::Mac48Address ns3::NqstaWifiMac::GetAddress() const [member function] - cls.add_method('GetAddress', - 'ns3::Mac48Address', - [], - is_const=True, is_virtual=True) - ## nqsta-wifi-mac.h: ns3::Ssid ns3::NqstaWifiMac::GetSsid() const [member function] - cls.add_method('GetSsid', - 'ns3::Ssid', - [], - is_const=True, is_virtual=True) - ## nqsta-wifi-mac.h: ns3::Mac48Address ns3::NqstaWifiMac::GetBssid() const [member function] - cls.add_method('GetBssid', - 'ns3::Mac48Address', - [], - is_const=True, is_virtual=True) - ## nqsta-wifi-mac.h: void ns3::NqstaWifiMac::SetAddress(ns3::Mac48Address address) [member function] - cls.add_method('SetAddress', - 'void', - [param('ns3::Mac48Address', 'address')], - is_virtual=True) - ## nqsta-wifi-mac.h: void ns3::NqstaWifiMac::SetSsid(ns3::Ssid ssid) [member function] - cls.add_method('SetSsid', - 'void', - [param('ns3::Ssid', 'ssid')], - is_virtual=True) - ## nqsta-wifi-mac.h: void ns3::NqstaWifiMac::SetMaxMissedBeacons(uint32_t missed) [member function] - cls.add_method('SetMaxMissedBeacons', - 'void', - [param('uint32_t', 'missed')]) - ## nqsta-wifi-mac.h: void ns3::NqstaWifiMac::SetProbeRequestTimeout(ns3::Time timeout) [member function] - cls.add_method('SetProbeRequestTimeout', - 'void', - [param('ns3::Time', 'timeout')]) - ## nqsta-wifi-mac.h: void ns3::NqstaWifiMac::SetAssocRequestTimeout(ns3::Time timeout) [member function] - cls.add_method('SetAssocRequestTimeout', - 'void', - [param('ns3::Time', 'timeout')]) - ## nqsta-wifi-mac.h: void ns3::NqstaWifiMac::StartActiveAssociation() [member function] - cls.add_method('StartActiveAssociation', - 'void', - []) - ## nqsta-wifi-mac.h: void ns3::NqstaWifiMac::DoDispose() [member function] - cls.add_method('DoDispose', - 'void', - [], - visibility='private', is_virtual=True) + is_const=True) return def register_Ns3RandomPropagationLossModel_methods(root_module, cls): diff --git a/bindings/python/ns3modulescan.py b/bindings/python/ns3modulescan.py index 3a460d953..8f77d5829 100644 --- a/bindings/python/ns3modulescan.py +++ b/bindings/python/ns3modulescan.py @@ -251,11 +251,21 @@ def ns3_module_scan(top_builddir, pygen_file_name, everything_h): module_parser.add_pre_scan_hook(pre_scan_hook) #module_parser.add_post_scan_hook(post_scan_hook) + + gccxml_options = dict( + include_paths=[top_builddir], + define_symbols={ + 'NS3_ASSERT_ENABLE': None, + 'NS3_LOG_ENABLE': None, + } + ) + module_parser.parse_init([everything_h], - include_paths=[top_builddir], whitelist_paths=[top_builddir, os.path.dirname(everything_h)], + None, whitelist_paths=[top_builddir, os.path.dirname(everything_h)], #includes=['"ns3/everything.h"'], pygen_sink=sections, - pygen_classifier=MyPygenClassifier(headers_map)) + pygen_classifier=MyPygenClassifier(headers_map), + gccxml_options=gccxml_options) module_parser.scan_types() callback_classes_file = open(os.path.join(os.path.dirname(pygen_file_name), "callbacks_list.py"), "wt") diff --git a/bindings/python/wscript b/bindings/python/wscript index 701123fae..9f0b33811 100644 --- a/bindings/python/wscript +++ b/bindings/python/wscript @@ -21,7 +21,7 @@ else: os.environ['PYTHONPATH'] = LOCAL_PYBINDGEN_PATH ## https://launchpad.net/pybindgen/ -REQUIRED_PYBINDGEN_VERSION = (0, 8, 0, 515) +REQUIRED_PYBINDGEN_VERSION = (0, 8, 0, 516) REQUIRED_PYGCCXML_VERSION = (0, 9, 5) From 0ad768c938418cbe506098328b8c9d4a243d027b Mon Sep 17 00:00:00 2001 From: Raj Bhattacharjea Date: Wed, 23 Jul 2008 16:09:17 -0400 Subject: [PATCH 192/495] Make PacketSink multitasking for TCP (closes bug 244) --- src/applications/packet-sink/packet-sink.cc | 14 +++++++++++++- src/applications/packet-sink/packet-sink.h | 7 ++++++- src/internet-stack/tcp-socket-impl.cc | 5 ++++- 3 files changed, 23 insertions(+), 3 deletions(-) diff --git a/src/applications/packet-sink/packet-sink.cc b/src/applications/packet-sink/packet-sink.cc index 1b4e14bad..a05b5e075 100644 --- a/src/applications/packet-sink/packet-sink.cc +++ b/src/applications/packet-sink/packet-sink.cc @@ -88,11 +88,17 @@ void PacketSink::StartApplication() // Called at time specified by Start m_socket->SetRecvCallback (MakeCallback(&PacketSink::HandleRead, this)); m_socket->SetAcceptCallback ( MakeNullCallback, const Address &> (), - MakeNullCallback, const Address&> ()); + MakeCallback(&PacketSink::HandleAccept, this)); } void PacketSink::StopApplication() // Called at time specified by Stop { + while(!m_socketList.empty()) //these are accepted sockets, close them + { + Ptr acceptedSocket = m_socketList.front(); + m_socketList.pop_front(); + acceptedSocket->Close(); + } if (m_socket) { m_socket->Close (); @@ -117,4 +123,10 @@ void PacketSink::HandleRead (Ptr socket) } } +void PacketSink::HandleAccept (Ptr s, const Address& from) +{ + s->SetRecvCallback (MakeCallback(&PacketSink::HandleRead, this)); + m_socketList.push_back (s); +} + } // Namespace ns3 diff --git a/src/applications/packet-sink/packet-sink.h b/src/applications/packet-sink/packet-sink.h index 440af90cd..f8a9a3c1a 100644 --- a/src/applications/packet-sink/packet-sink.h +++ b/src/applications/packet-sink/packet-sink.h @@ -81,8 +81,13 @@ private: virtual void StopApplication (void); // Called at time specified by Stop void HandleRead (Ptr socket); + void HandleAccept (Ptr, const Address& from); + + // In the case of TCP, each socket accept returns a new socket, so the + // listening socket is stored seperately from the accepted sockets + Ptr m_socket; // Listening socket + std::list > m_socketList; //the accepted sockets - Ptr m_socket; // Associated socket Address m_local; // Local address to bind to TypeId m_tid; // Protocol TypeId TracedCallback, const Address &> m_rxTrace; diff --git a/src/internet-stack/tcp-socket-impl.cc b/src/internet-stack/tcp-socket-impl.cc index fc0cf1b8b..cb970df79 100644 --- a/src/internet-stack/tcp-socket-impl.cc +++ b/src/internet-stack/tcp-socket-impl.cc @@ -86,7 +86,7 @@ TcpSocketImpl::GetTypeId () } TcpSocketImpl::TcpSocketImpl(const TcpSocketImpl& sock) - : TcpSocket(sock), //copy the base class callbacks + : TcpSocket(sock), //copy object::m_tid, copy socket::callbacks m_skipRetxResched (sock.m_skipRetxResched), m_dupAckCount (sock.m_dupAckCount), m_delAckCount (0), @@ -140,6 +140,9 @@ TcpSocketImpl::TcpSocketImpl(const TcpSocketImpl& sock) { m_rtt = sock.m_rtt->Copy(); } + //null out the socket base class recvcallback, + //make user of the socket register this explicitly + SetRecvCallback (MakeNullCallback > () ); //can't "copy" the endpoint just yes, must do this when we know the peer info //too; this is in SYN_ACK_TX } From dbb7f0f738a28a65bccf97090044312de54799e6 Mon Sep 17 00:00:00 2001 From: Craig Dowell Date: Wed, 23 Jul 2008 17:09:12 -0700 Subject: [PATCH 193/495] begin sorting out mtu woes --- src/devices/csma/csma-net-device.cc | 202 +++++++++++++++++++--------- src/devices/csma/csma-net-device.h | 20 ++- 2 files changed, 156 insertions(+), 66 deletions(-) diff --git a/src/devices/csma/csma-net-device.cc b/src/devices/csma/csma-net-device.cc index 15c353f94..b43ca9b6f 100644 --- a/src/devices/csma/csma-net-device.cc +++ b/src/devices/csma/csma-net-device.cc @@ -27,6 +27,7 @@ #include "ns3/error-model.h" #include "ns3/enum.h" #include "ns3/boolean.h" +#include "ns3/uinteger.h" #include "ns3/pointer.h" #include "ns3/trace-source-accessor.h" #include "csma-net-device.h" @@ -45,52 +46,61 @@ CsmaNetDevice::GetTypeId (void) .SetParent () .AddConstructor () .AddAttribute ("Address", - "The address of this device.", - Mac48AddressValue (Mac48Address ("ff:ff:ff:ff:ff:ff")), - MakeMac48AddressAccessor (&CsmaNetDevice::m_address), - MakeMac48AddressChecker ()) + "The MAC address of this device.", + Mac48AddressValue (Mac48Address ("ff:ff:ff:ff:ff:ff")), + MakeMac48AddressAccessor (&CsmaNetDevice::m_address), + MakeMac48AddressChecker ()) + .AddAttribute ("PayloadLength", + "The max PHY-level payload length of packets sent over this device.", + UintegerValue (DEFAULT_FRAME_LENGTH), + MakeUintegerAccessor (&CsmaNetDevice::m_maxPayloadLength), + MakeUintegerChecker ()) + .AddAttribute ("MTU", + "The MAC-level MTU (client payload) of packets sent over this device.", + UintegerValue (DEFAULT_MTU), + MakeUintegerAccessor (&CsmaNetDevice::m_mtu), + MakeUintegerChecker ()) .AddAttribute ("EncapsulationMode", - "The link-layer encapsulation type to use.", - EnumValue (LLC), - MakeEnumAccessor (&CsmaNetDevice::m_encapMode), - MakeEnumChecker (ETHERNET_V1, "EthernetV1", - IP_ARP, "IpArp", - RAW, "Raw", - LLC, "Llc")) + "The link-layer encapsulation type to use.", + EnumValue (LLC), + MakeEnumAccessor (&CsmaNetDevice::m_encapMode), + MakeEnumChecker (ETHERNET_V1, "EthernetV1", + IP_ARP, "IpArp", + RAW, "Raw", + LLC, "Llc")) .AddAttribute ("SendEnable", - "Enable or disable the transmitter section of the device.", - BooleanValue (true), - MakeBooleanAccessor (&CsmaNetDevice::m_sendEnable), - MakeBooleanChecker ()) + "Enable or disable the transmitter section of the device.", + BooleanValue (true), + MakeBooleanAccessor (&CsmaNetDevice::m_sendEnable), + MakeBooleanChecker ()) .AddAttribute ("ReceiveEnable", - "Enable or disable the receiver section of the device.", - BooleanValue (true), - MakeBooleanAccessor (&CsmaNetDevice::m_receiveEnable), - MakeBooleanChecker ()) + "Enable or disable the receiver section of the device.", + BooleanValue (true), + MakeBooleanAccessor (&CsmaNetDevice::m_receiveEnable), + MakeBooleanChecker ()) .AddAttribute ("RxErrorModel", - "The receiver error model used to simulate packet loss", - PointerValue (), - MakePointerAccessor (&CsmaNetDevice::m_receiveErrorModel), - MakePointerChecker ()) + "The receiver error model used to simulate packet loss", + PointerValue (), + MakePointerAccessor (&CsmaNetDevice::m_receiveErrorModel), + MakePointerChecker ()) .AddAttribute ("TxQueue", - "A queue to use as the transmit queue in the device.", - PointerValue (), - MakePointerAccessor (&CsmaNetDevice::m_queue), - MakePointerChecker ()) + "A queue to use as the transmit queue in the device.", + PointerValue (), + MakePointerAccessor (&CsmaNetDevice::m_queue), + MakePointerChecker ()) .AddTraceSource ("Rx", - "Trace source to fire on reception of a MAC packet.", - MakeTraceSourceAccessor (&CsmaNetDevice::m_rxTrace)) + "The trace source to fire on reception of a MAC packet.", + MakeTraceSourceAccessor (&CsmaNetDevice::m_rxTrace)) .AddTraceSource ("Drop", - "Trace source to fire on when a MAC packet is dropped.", - MakeTraceSourceAccessor (&CsmaNetDevice::m_dropTrace)) + "Trace source to fire on when a MAC packet is dropped.", + MakeTraceSourceAccessor (&CsmaNetDevice::m_dropTrace)) ; return tid; } CsmaNetDevice::CsmaNetDevice () : m_name (""), - m_linkUp (false), - m_mtu (0xffff) + m_linkUp (false) { NS_LOG_FUNCTION (this); m_txMachineState = READY; @@ -116,20 +126,21 @@ CsmaNetDevice::DoDispose () void CsmaNetDevice::SetAddress (Mac48Address self) { + NS_LOG_FUNCTION (self); m_address = self; } void CsmaNetDevice::SetSendEnable (bool sendEnable) { - NS_LOG_FUNCTION_NOARGS (); + NS_LOG_FUNCTION (sendEnable); m_sendEnable = sendEnable; } void CsmaNetDevice::SetReceiveEnable (bool receiveEnable) { - NS_LOG_FUNCTION_NOARGS (); + NS_LOG_FUNCTION (receiveEnable); m_receiveEnable = receiveEnable; } @@ -150,7 +161,7 @@ CsmaNetDevice::IsReceiveEnabled (void) void CsmaNetDevice::SetInterframeGap (Time t) { - NS_LOG_FUNCTION_NOARGS (); + NS_LOG_FUNCTION (t); m_tInterframeGap = t; } @@ -162,7 +173,7 @@ CsmaNetDevice::SetBackoffParams ( uint32_t ceiling, uint32_t maxRetries) { - NS_LOG_FUNCTION_NOARGS (); + NS_LOG_FUNCTION (slotTime << minSlots << maxSlots << ceiling << maxRetries); m_backoff.m_slotTime = slotTime; m_backoff.m_minSlots = minSlots; m_backoff.m_maxSlots = maxSlots; @@ -177,7 +188,7 @@ CsmaNetDevice::AddHeader ( Mac48Address dest, uint16_t protocolNumber) { - NS_LOG_FUNCTION_NOARGS (); + NS_LOG_FUNCTION (p << source << dest << protocolNumber); if (m_encapMode == RAW) { @@ -190,28 +201,58 @@ CsmaNetDevice::AddHeader ( EthernetTrailer trailer; + NS_LOG_LOGIC ("p->GetSize () = " << p->GetSize ()); + NS_LOG_LOGIC ("m_mtu = " << m_mtu); + NS_LOG_LOGIC ("m_maxPayloadLength = " << m_maxPayloadLength); + uint16_t lengthType = 0; switch (m_encapMode) { - case ETHERNET_V1: - lengthType = p->GetSize () + header.GetSerializedSize () + - trailer.GetSerializedSize (); - break; case IP_ARP: + NS_LOG_LOGIC ("Encapsulating packet as IP_ARP (type interpretation)"); +// +// This corresponds to the type interpretation of the lengthType field. +// lengthType = protocolNumber; break; - case LLC: { - lengthType = p->GetSize () + header.GetSerializedSize () + - trailer.GetSerializedSize (); - LlcSnapHeader llc; - llc.SetType (protocolNumber); - p->AddHeader (llc); - } break; + case ETHERNET_V1: + NS_LOG_LOGIC ("Encapsulating packet as ETHERNET_V1 " + "(length interpretation)"); +// +// This corresponds to the length interpretation of the lengthType field. +// The ethernet header and trailer are not counted, see RFC 1042 and +// http://standards.ieee.org/getieee802/download/802.3-2005_section1.pdf, +// Section 3.2.6 a. We just include the size of the "payload." +// + lengthType = p->GetSize (); + NS_ASSERT_MSG (lengthType <= m_maxPayloadLength, + "CsmaNetDevice::AddHeader(): 802.3 Length/Type field: " + "length interpretation must not exceed device max payload length"); + break; + case LLC: + { + NS_LOG_LOGIC ("Encapsulating packet as LLC (length interpretation)"); + + LlcSnapHeader llc; + llc.SetType (protocolNumber); + p->AddHeader (llc); +// +// This corresponds to the length interpretation of the lengthType field, +// but with an LLC/SNAP header added to the payload. +// + lengthType = llc.GetSerializedSize () + p->GetSize (); + NS_ASSERT_MSG (lengthType <= m_maxPayloadLength, + "CsmaNetDevice::AddHeader(): 802.3 Length/Type field with LLC/SNAP: " + "length interpretation must not exceed device max payload length"); + } + break; case RAW: + NS_LOG_LOGIC ("Encapsulating packet as RAW"); NS_ASSERT (false); break; } + NS_LOG_LOGIC ("header.SetLengthType (" << lengthType << ")"); header.SetLengthType (lengthType); p->AddHeader (header); @@ -222,7 +263,8 @@ CsmaNetDevice::AddHeader ( bool CsmaNetDevice::ProcessHeader (Ptr p, uint16_t & param) { - NS_LOG_FUNCTION_NOARGS (); + NS_LOG_FUNCTION (p << param); + if (m_encapMode == RAW) { return true; @@ -264,6 +306,7 @@ CsmaNetDevice::ProcessHeader (Ptr p, uint16_t & param) CsmaNetDevice::TransmitStart () { NS_LOG_FUNCTION_NOARGS (); + NS_LOG_LOGIC ("m_currentPkt=" << m_currentPkt); NS_LOG_LOGIC ("UID is " << m_currentPkt->GetUid ()); // @@ -344,6 +387,7 @@ CsmaNetDevice::TransmitStart () CsmaNetDevice::TransmitAbort (void) { NS_LOG_FUNCTION_NOARGS (); + NS_LOG_LOGIC ("Pkt UID is " << m_currentPkt->GetUid () << ")"); // @@ -366,6 +410,7 @@ CsmaNetDevice::TransmitAbort (void) CsmaNetDevice::TransmitCompleteEvent (void) { NS_LOG_FUNCTION_NOARGS (); + // // This function is called to finish the process of transmitting a packet. // We need to tell the channel that we've stopped wiggling the wire and @@ -390,6 +435,7 @@ CsmaNetDevice::TransmitCompleteEvent (void) CsmaNetDevice::TransmitReadyEvent (void) { NS_LOG_FUNCTION_NOARGS (); + // // This function is called to enable the transmitter after the interframe // gap has passed. If there are pending transmissions, we use this opportunity @@ -398,7 +444,9 @@ CsmaNetDevice::TransmitReadyEvent (void) NS_ASSERT_MSG (m_txMachineState == GAP, "Must be in interframe gap"); m_txMachineState = READY; - // Get the next packet from the queue for transmitting +// +// Get the next packet from the queue for transmitting +// if (m_queue->IsEmpty ()) { return; @@ -412,7 +460,7 @@ CsmaNetDevice::TransmitReadyEvent (void) } } -bool + bool CsmaNetDevice::Attach (Ptr ch) { NS_LOG_FUNCTION (this << &ch); @@ -441,7 +489,7 @@ CsmaNetDevice::Attach (Ptr ch) void CsmaNetDevice::SetQueue (Ptr q) { - NS_LOG_FUNCTION (this << q); + NS_LOG_FUNCTION (q); m_queue = q; } @@ -455,15 +503,14 @@ CsmaNetDevice::SetReceiveErrorModel (Ptr em) void CsmaNetDevice::Receive (Ptr packet, Ptr senderDevice) { - NS_LOG_FUNCTION_NOARGS (); + NS_LOG_FUNCTION (packet << senderDevice); NS_LOG_LOGIC ("UID is " << packet->GetUid ()); - - // - // We never forward up packets that we sent. Real devices don't do this since - // their receivers are disabled during send, so we don't. Drop the packet - // silently (no tracing) since it would really never get here in a real device. - // +// +// We never forward up packets that we sent. Real devices don't do this since +// their receivers are disabled during send, so we don't. Drop the packet +// silently (no tracing) since it would really never get here in a real device. +// if (senderDevice == this) { return; @@ -483,7 +530,8 @@ CsmaNetDevice::Receive (Ptr packet, Ptr senderDevice) m_rxTrace (packet); if (!m_promiscRxCallback.IsNull ()) { - m_promiscRxCallback (this, packet, 0, GetBroadcast (), GetAddress (), PACKET_HOST); + m_promiscRxCallback (this, packet, 0, GetBroadcast (), + GetAddress (), PACKET_HOST); } m_rxCallback (this, packet, 0, GetBroadcast ()); return; @@ -581,7 +629,8 @@ CsmaNetDevice::Receive (Ptr packet, Ptr senderDevice) if (!m_promiscRxCallback.IsNull ()) { - m_promiscRxCallback (this, packet, protocol, header.GetSource (), header.GetDestination (), packetType); + m_promiscRxCallback (this, packet, protocol, header.GetSource (), + header.GetDestination (), packetType); } if (packetType != PACKET_OTHERHOST) @@ -601,6 +650,8 @@ CsmaNetDevice::GetQueue (void) const void CsmaNetDevice::NotifyLinkUp (void) { + NS_LOG_FUNCTION_NOARGS (); + m_linkUp = true; if (m_linkChangeCallback.IsNull () == false) { @@ -611,42 +662,49 @@ CsmaNetDevice::NotifyLinkUp (void) void CsmaNetDevice::SetName (const std::string name) { + NS_LOG_FUNCTION (name); m_name = name; } std::string CsmaNetDevice::GetName (void) const { + NS_LOG_FUNCTION_NOARGS (); return m_name; } void CsmaNetDevice::SetIfIndex (const uint32_t index) { + NS_LOG_FUNCTION (index); m_ifIndex = index; } uint32_t CsmaNetDevice::GetIfIndex (void) const { + NS_LOG_FUNCTION_NOARGS (); return m_ifIndex; } Ptr CsmaNetDevice::GetChannel (void) const { + NS_LOG_FUNCTION_NOARGS (); return m_channel; } Address CsmaNetDevice::GetAddress (void) const { + NS_LOG_FUNCTION_NOARGS (); return m_address; } bool CsmaNetDevice::SetMtu (const uint16_t mtu) { + NS_LOG_FUNCTION (mtu); m_mtu = mtu; return true; } @@ -654,49 +712,56 @@ CsmaNetDevice::SetMtu (const uint16_t mtu) uint16_t CsmaNetDevice::GetMtu (void) const { + NS_LOG_FUNCTION_NOARGS (); return m_mtu; } bool CsmaNetDevice::IsLinkUp (void) const { + NS_LOG_FUNCTION_NOARGS (); return m_linkUp; } void CsmaNetDevice::SetLinkChangeCallback (Callback callback) { + NS_LOG_FUNCTION (&callback); m_linkChangeCallback = callback; } bool CsmaNetDevice::IsBroadcast (void) const { + NS_LOG_FUNCTION_NOARGS (); return true; } Address CsmaNetDevice::GetBroadcast (void) const { + NS_LOG_FUNCTION_NOARGS (); return Mac48Address ("ff:ff:ff:ff:ff:ff"); } bool CsmaNetDevice::IsMulticast (void) const { + NS_LOG_FUNCTION_NOARGS (); return true; } Address CsmaNetDevice::GetMulticast (void) const { + NS_LOG_FUNCTION_NOARGS (); return Mac48Address ("01:00:5e:00:00:00"); } Address CsmaNetDevice::MakeMulticastAddress (Ipv4Address multicastGroup) const { - NS_LOG_FUNCTION (this << multicastGroup); + NS_LOG_FUNCTION (multicastGroup); // // First, get the generic multicast address. // @@ -748,6 +813,7 @@ CsmaNetDevice::MakeMulticastAddress (Ipv4Address multicastGroup) const bool CsmaNetDevice::IsPointToPoint (void) const { + NS_LOG_FUNCTION_NOARGS (); return false; } @@ -756,6 +822,7 @@ CsmaNetDevice::Send (Ptr packet, const Address& dest, uint16_t protocolNumber) { + NS_LOG_FUNCTION (packet << dest << protocolNumber); return SendFrom (packet, m_address, dest, protocolNumber); } @@ -765,7 +832,7 @@ CsmaNetDevice::SendFrom (Ptr packet, const Address& dest, uint16_t protocolNumber) { - NS_LOG_FUNCTION_NOARGS (); + NS_LOG_FUNCTION (packet << src << dest << protocolNumber); NS_LOG_LOGIC ("p=" << packet); NS_LOG_LOGIC ("UID is " << packet->GetUid () << ")"); @@ -812,12 +879,15 @@ CsmaNetDevice::SendFrom (Ptr packet, Ptr CsmaNetDevice::GetNode (void) const { + NS_LOG_FUNCTION_NOARGS (); return m_node; } void CsmaNetDevice::SetNode (Ptr node) { + NS_LOG_FUNCTION (node); + m_node = node; int count = -1; if (m_name.size () == 0) @@ -843,6 +913,7 @@ CsmaNetDevice::SetNode (Ptr node) bool CsmaNetDevice::NeedsArp (void) const { + NS_LOG_FUNCTION_NOARGS (); if ((m_encapMode == IP_ARP) || (m_encapMode == LLC)) { return true; @@ -856,18 +927,21 @@ CsmaNetDevice::NeedsArp (void) const void CsmaNetDevice::SetReceiveCallback (NetDevice::ReceiveCallback cb) { + NS_LOG_FUNCTION (&cb); m_rxCallback = cb; } void CsmaNetDevice::SetPromiscReceiveCallback (NetDevice::PromiscReceiveCallback cb) { + NS_LOG_FUNCTION (&cb); m_promiscRxCallback = cb; } bool CsmaNetDevice::SupportsPromiscuous () const { + NS_LOG_FUNCTION_NOARGS (); return true; } diff --git a/src/devices/csma/csma-net-device.h b/src/devices/csma/csma-net-device.h index db22d7065..f84b2eb9b 100644 --- a/src/devices/csma/csma-net-device.h +++ b/src/devices/csma/csma-net-device.h @@ -332,6 +332,10 @@ protected: bool ProcessHeader (Ptr p, uint16_t & param); private: + + static const uint16_t DEFAULT_FRAME_LENGTH = 1500; + static const uint16_t DEFAULT_MTU = 1492; + /** * Operator = is declared but not implemented. This disables the assigment * operator for CsmaNetDevice objects. @@ -565,10 +569,22 @@ private: Callback m_linkChangeCallback; /** - * The maximum transmission unit (biggest packet) allowed to be sent or - * received by this network device. + * The MAC-level maximum transmission unit allowed to be sent or received by + * this network device. This corresponds to the maximum payload the device + * can accept for transmission. This is distinct from the PHY-level maximum + * as found in the 802.3 header Type/Length field. For example, if you + * choose "Llc" as your encapsulation mode, this will be reduced by the eight + * bytes consumed by the LLC/SNAP header. */ uint16_t m_mtu; + + /** + * The PHY-level maximum payload size. This corresponds to the maximum + * number of bytes that can be transmitted as a payload over a channel. + * This corresponds to the 1500 byte limit often seen on Ethernet in the + * length interpretation of the Type/Length field of the 802.3 header. + */ + uint32_t m_maxPayloadLength; }; }; // namespace ns3 From c51f635cfb2504bfa33dac43d1c589ac8de9b394 Mon Sep 17 00:00:00 2001 From: Craig Dowell Date: Wed, 23 Jul 2008 18:29:13 -0700 Subject: [PATCH 194/495] fix supidity in mtu stuff --- src/devices/csma/csma-net-device.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/devices/csma/csma-net-device.cc b/src/devices/csma/csma-net-device.cc index b43ca9b6f..32be6215a 100644 --- a/src/devices/csma/csma-net-device.cc +++ b/src/devices/csma/csma-net-device.cc @@ -240,7 +240,7 @@ CsmaNetDevice::AddHeader ( // This corresponds to the length interpretation of the lengthType field, // but with an LLC/SNAP header added to the payload. // - lengthType = llc.GetSerializedSize () + p->GetSize (); + lengthType = p->GetSize (); NS_ASSERT_MSG (lengthType <= m_maxPayloadLength, "CsmaNetDevice::AddHeader(): 802.3 Length/Type field with LLC/SNAP: " "length interpretation must not exceed device max payload length"); From f573eaa47a9af9fd3a85871a912e7f9501cb3615 Mon Sep 17 00:00:00 2001 From: "Gustavo J. A. M. Carneiro" Date: Thu, 24 Jul 2008 11:27:57 +0100 Subject: [PATCH 195/495] Add helper waf proxy script --- src/devices/wifi/waf | 1 + 1 file changed, 1 insertion(+) create mode 100755 src/devices/wifi/waf diff --git a/src/devices/wifi/waf b/src/devices/wifi/waf new file mode 100755 index 000000000..4283ec141 --- /dev/null +++ b/src/devices/wifi/waf @@ -0,0 +1 @@ +exec "`dirname "$0"`"/../../../waf "$@" From 732b7994dea661ef0df10362def6e073c61dcb6e Mon Sep 17 00:00:00 2001 From: "Gustavo J. A. M. Carneiro" Date: Thu, 24 Jul 2008 11:37:56 +0100 Subject: [PATCH 196/495] Add empty implementation of Simulator::SetImplementation, to make Python bindings work. --- src/simulator/simulator.cc | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/simulator/simulator.cc b/src/simulator/simulator.cc index 2abaf218a..0dd3c003c 100644 --- a/src/simulator/simulator.cc +++ b/src/simulator/simulator.cc @@ -276,6 +276,13 @@ Simulator::GetMaximumSimulationTime (void) return GetImpl ()->GetMaximumSimulationTime (); } +void +Simulator::SetImplementation (Ptr impl) +{ + NS_FATAL_ERROR ("TODO"); +} + + } // namespace ns3 From ca2fef3bd87d54394e891f8bbbfa98355a88b914 Mon Sep 17 00:00:00 2001 From: "Gustavo J. A. M. Carneiro" Date: Thu, 24 Jul 2008 11:41:15 +0100 Subject: [PATCH 197/495] Make the new NetDevice APIs pure virtual methods, by Mathieu's insistence. --- RELEASE_NOTES | 4 +++- bindings/python/ns3_module_node.py | 16 +++++++++++--- bindings/python/ns3_module_point_to_point.py | 10 +++++++++ bindings/python/ns3_module_simulator.py | 8 +++---- bindings/python/ns3_module_wifi.py | 15 +++++++++++++ .../point-to-point-net-device.cc | 12 +++++++++++ .../point-to-point-net-device.h | 3 +++ src/devices/wifi/wifi-net-device.cc | 19 +++++++++++++++++ src/devices/wifi/wifi-net-device.h | 4 ++++ src/node/net-device.cc | 21 ------------------- src/node/net-device.h | 6 +++--- src/node/simple-net-device.cc | 11 ++++++++++ src/node/simple-net-device.h | 2 ++ 13 files changed, 99 insertions(+), 32 deletions(-) diff --git a/RELEASE_NOTES b/RELEASE_NOTES index 7c4ce5cb1..f6dd3c125 100644 --- a/RELEASE_NOTES +++ b/RELEASE_NOTES @@ -36,7 +36,9 @@ API changes from 3.1 to 3.2 - remove references to Parameter in helper APIs (changeset 3cdd9d60f7c7, bug 232); old variants are currently deprecated API and will be removed in a future release -- New NetDevice APIs: SendFrom and SetPromiscRxCallback; +- New NetDevice APIs: SendFrom, SetPromiscRxCallback, + SupportsPromiscuous. These are pure virtual methods, so they need + to be implemented by NetDevice subclasses; In order to support the learning bridge, some API changes in Node and NetDevice were made. diff --git a/bindings/python/ns3_module_node.py b/bindings/python/ns3_module_node.py index 5d3741594..bb904c61f 100644 --- a/bindings/python/ns3_module_node.py +++ b/bindings/python/ns3_module_node.py @@ -1538,7 +1538,7 @@ def register_Ns3NetDevice_methods(root_module, cls): cls.add_method('SendFrom', 'bool', [param('ns3::Ptr< ns3::Packet >', 'packet'), param('ns3::Address&', 'source', is_const=True), param('ns3::Address&', 'dest', is_const=True), param('uint16_t', 'protocolNumber')], - is_virtual=True) + is_pure_virtual=True, is_virtual=True) ## net-device.h: ns3::Ptr ns3::NetDevice::GetNode() const [member function] cls.add_method('GetNode', 'ns3::Ptr< ns3::Node >', @@ -1563,12 +1563,12 @@ def register_Ns3NetDevice_methods(root_module, cls): cls.add_method('SetPromiscReceiveCallback', 'void', [param('ns3::Callback< bool, ns3::Ptr< ns3::NetDevice >, ns3::Ptr< ns3::Packet >, unsigned short, ns3::Address const&, ns3::Address const&, ns3::NetDevice::PacketType >', 'cb')], - is_virtual=True) + is_pure_virtual=True, is_virtual=True) ## net-device.h: bool ns3::NetDevice::SupportsPromiscuous() const [member function] cls.add_method('SupportsPromiscuous', 'bool', [], - is_const=True, is_virtual=True) + is_pure_virtual=True, is_const=True, is_virtual=True) cls.add_constructor([]) return @@ -2444,6 +2444,16 @@ def register_Ns3SimpleNetDevice_methods(root_module, cls): 'void', [param('ns3::Callback< bool, ns3::Ptr< ns3::NetDevice >, ns3::Ptr< ns3::Packet >, unsigned short, ns3::Address const&, ns3::empty, ns3::empty >', 'cb')], is_virtual=True) + ## simple-net-device.h: void ns3::SimpleNetDevice::SetPromiscReceiveCallback(ns3::Callback, ns3::Ptr, unsigned short, ns3::Address const&, ns3::Address const&, ns3::NetDevice::PacketType> cb) [member function] + cls.add_method('SetPromiscReceiveCallback', + 'void', + [param('ns3::Callback< bool, ns3::Ptr< ns3::NetDevice >, ns3::Ptr< ns3::Packet >, unsigned short, ns3::Address const&, ns3::Address const&, ns3::NetDevice::PacketType >', 'cb')], + is_virtual=True) + ## simple-net-device.h: bool ns3::SimpleNetDevice::SupportsPromiscuous() const [member function] + cls.add_method('SupportsPromiscuous', + 'bool', + [], + is_const=True, is_virtual=True) ## simple-net-device.h: void ns3::SimpleNetDevice::DoDispose() [member function] cls.add_method('DoDispose', 'void', diff --git a/bindings/python/ns3_module_point_to_point.py b/bindings/python/ns3_module_point_to_point.py index f83aa39ae..4d7cf9ff0 100644 --- a/bindings/python/ns3_module_point_to_point.py +++ b/bindings/python/ns3_module_point_to_point.py @@ -232,6 +232,16 @@ def register_Ns3PointToPointNetDevice_methods(root_module, cls): 'void', [param('ns3::Callback< bool, ns3::Ptr< ns3::NetDevice >, ns3::Ptr< ns3::Packet >, unsigned short, ns3::Address const&, ns3::empty, ns3::empty >', 'cb')], is_virtual=True) + ## point-to-point-net-device.h: void ns3::PointToPointNetDevice::SetPromiscReceiveCallback(ns3::Callback, ns3::Ptr, unsigned short, ns3::Address const&, ns3::Address const&, ns3::NetDevice::PacketType> cb) [member function] + cls.add_method('SetPromiscReceiveCallback', + 'void', + [param('ns3::Callback< bool, ns3::Ptr< ns3::NetDevice >, ns3::Ptr< ns3::Packet >, unsigned short, ns3::Address const&, ns3::Address const&, ns3::NetDevice::PacketType >', 'cb')], + is_virtual=True) + ## point-to-point-net-device.h: bool ns3::PointToPointNetDevice::SupportsPromiscuous() const [member function] + cls.add_method('SupportsPromiscuous', + 'bool', + [], + is_const=True, is_virtual=True) ## point-to-point-net-device.h: void ns3::PointToPointNetDevice::DoDispose() [member function] cls.add_method('DoDispose', 'void', diff --git a/bindings/python/ns3_module_simulator.py b/bindings/python/ns3_module_simulator.py index 923df6ad4..badde30a5 100644 --- a/bindings/python/ns3_module_simulator.py +++ b/bindings/python/ns3_module_simulator.py @@ -333,10 +333,10 @@ def register_Ns3Watchdog_methods(root_module, cls): def register_Ns3Simulator_methods(root_module, cls): ## simulator.h: static void ns3::Simulator::SetImplementation(ns3::Ptr impl) [member function] - #cls.add_method('SetImplementation', - # 'void', - # [param('ns3::Ptr< ns3::SimulatorImpl >', 'impl')], - # is_static=True) + cls.add_method('SetImplementation', + 'void', + [param('ns3::Ptr< ns3::SimulatorImpl >', 'impl')], + is_static=True) ## simulator.h: static void ns3::Simulator::SetScheduler(ns3::Ptr scheduler) [member function] cls.add_method('SetScheduler', 'void', diff --git a/bindings/python/ns3_module_wifi.py b/bindings/python/ns3_module_wifi.py index 6ba85ee09..339e4cdc0 100644 --- a/bindings/python/ns3_module_wifi.py +++ b/bindings/python/ns3_module_wifi.py @@ -2155,6 +2155,21 @@ def register_Ns3WifiNetDevice_methods(root_module, cls): 'void', [param('ns3::Callback< bool, ns3::Ptr< ns3::NetDevice >, ns3::Ptr< ns3::Packet >, unsigned short, ns3::Address const&, ns3::empty, ns3::empty >', 'cb')], is_virtual=True) + ## wifi-net-device.h: bool ns3::WifiNetDevice::SendFrom(ns3::Ptr packet, ns3::Address const & source, ns3::Address const & dest, uint16_t protocolNumber) [member function] + cls.add_method('SendFrom', + 'bool', + [param('ns3::Ptr< ns3::Packet >', 'packet'), param('ns3::Address&', 'source', is_const=True), param('ns3::Address&', 'dest', is_const=True), param('uint16_t', 'protocolNumber')], + is_virtual=True) + ## wifi-net-device.h: void ns3::WifiNetDevice::SetPromiscReceiveCallback(ns3::Callback, ns3::Ptr, unsigned short, ns3::Address const&, ns3::Address const&, ns3::NetDevice::PacketType> cb) [member function] + cls.add_method('SetPromiscReceiveCallback', + 'void', + [param('ns3::Callback< bool, ns3::Ptr< ns3::NetDevice >, ns3::Ptr< ns3::Packet >, unsigned short, ns3::Address const&, ns3::Address const&, ns3::NetDevice::PacketType >', 'cb')], + is_virtual=True) + ## wifi-net-device.h: bool ns3::WifiNetDevice::SupportsPromiscuous() const [member function] + cls.add_method('SupportsPromiscuous', + 'bool', + [], + is_const=True, is_virtual=True) ## wifi-net-device.h: void ns3::WifiNetDevice::DoDispose() [member function] cls.add_method('DoDispose', 'void', diff --git a/src/devices/point-to-point/point-to-point-net-device.cc b/src/devices/point-to-point/point-to-point-net-device.cc index b2953d070..d7fa004e2 100644 --- a/src/devices/point-to-point/point-to-point-net-device.cc +++ b/src/devices/point-to-point/point-to-point-net-device.cc @@ -467,4 +467,16 @@ PointToPointNetDevice::SetReceiveCallback (NetDevice::ReceiveCallback cb) m_rxCallback = cb; } + void +PointToPointNetDevice::SetPromiscReceiveCallback (PromiscReceiveCallback cb) +{ + NS_FATAL_ERROR ("not implemented"); +} + + bool +PointToPointNetDevice::SupportsPromiscuous (void) const +{ + return false; +} + } // namespace ns3 diff --git a/src/devices/point-to-point/point-to-point-net-device.h b/src/devices/point-to-point/point-to-point-net-device.h index 352050ec4..e5694e750 100644 --- a/src/devices/point-to-point/point-to-point-net-device.h +++ b/src/devices/point-to-point/point-to-point-net-device.h @@ -177,6 +177,9 @@ public: virtual void SetReceiveCallback (NetDevice::ReceiveCallback cb); + virtual void SetPromiscReceiveCallback (PromiscReceiveCallback cb); + virtual bool SupportsPromiscuous (void) const; + private: virtual void DoDispose (void); diff --git a/src/devices/wifi/wifi-net-device.cc b/src/devices/wifi/wifi-net-device.cc index f3bcad80d..7f2848540 100644 --- a/src/devices/wifi/wifi-net-device.cc +++ b/src/devices/wifi/wifi-net-device.cc @@ -332,5 +332,24 @@ WifiNetDevice::LinkDown (void) } } +bool +WifiNetDevice::SendFrom (Ptr packet, const Address& source, const Address& dest, uint16_t protocolNumber) +{ + NS_FATAL_ERROR ("TODO"); + return false; +} + +void +WifiNetDevice::SetPromiscReceiveCallback (PromiscReceiveCallback cb) +{ + NS_FATAL_ERROR ("TODO"); +} + +bool +WifiNetDevice::SupportsPromiscuous (void) const +{ + return false; // TODO +} + } // namespace ns3 diff --git a/src/devices/wifi/wifi-net-device.h b/src/devices/wifi/wifi-net-device.h index 08867ae89..690bb8ad5 100644 --- a/src/devices/wifi/wifi-net-device.h +++ b/src/devices/wifi/wifi-net-device.h @@ -101,6 +101,10 @@ public: virtual bool NeedsArp (void) const; virtual void SetReceiveCallback (NetDevice::ReceiveCallback cb); + virtual bool SendFrom(Ptr packet, const Address& source, const Address& dest, uint16_t protocolNumber); + virtual void SetPromiscReceiveCallback (PromiscReceiveCallback cb); + virtual bool SupportsPromiscuous (void) const; + private: virtual void DoDispose (void); void ForwardUp (Ptr packet, const Mac48Address &from); diff --git a/src/node/net-device.cc b/src/node/net-device.cc index 048fb1fe2..410cc3f49 100644 --- a/src/node/net-device.cc +++ b/src/node/net-device.cc @@ -38,25 +38,4 @@ TypeId NetDevice::GetTypeId (void) NetDevice::~NetDevice () {} -bool -NetDevice::SupportsPromiscuous () const -{ - return false; -} - -void -NetDevice::SetPromiscReceiveCallback (PromiscReceiveCallback cb) -{ - // assert that the virtual method was overridden in a subclass if it - // claims to support promiscuous mode. - NS_ASSERT (!SupportsPromiscuous ()); -} - -bool -NetDevice::SendFrom (Ptr packet, const Address& source, const Address& dest, uint16_t protocolNumber) -{ - NS_FATAL_ERROR ("NetDevice::SendFrom not implemented for " << GetInstanceTypeId ().GetName ()); - return false; -} - } // namespace ns3 diff --git a/src/node/net-device.h b/src/node/net-device.h index c718013c9..b8f799ed3 100644 --- a/src/node/net-device.h +++ b/src/node/net-device.h @@ -228,7 +228,7 @@ public: * * \return whether the Send operation succeeded */ - virtual bool SendFrom(Ptr packet, const Address& source, const Address& dest, uint16_t protocolNumber); + virtual bool SendFrom(Ptr packet, const Address& source, const Address& dest, uint16_t protocolNumber) = 0; /** * \returns the node base class which contains this network * interface. @@ -309,12 +309,12 @@ public: * sensed by the netdevice but which are intended to be received by * other hosts. */ - virtual void SetPromiscReceiveCallback (PromiscReceiveCallback cb); + virtual void SetPromiscReceiveCallback (PromiscReceiveCallback cb) = 0; /** * \return true if this interface supports a promiscuous mode, false otherwise. */ - virtual bool SupportsPromiscuous (void) const; + virtual bool SupportsPromiscuous (void) const = 0; }; diff --git a/src/node/simple-net-device.cc b/src/node/simple-net-device.cc index 8f1b0d718..481306da7 100644 --- a/src/node/simple-net-device.cc +++ b/src/node/simple-net-device.cc @@ -200,5 +200,16 @@ SimpleNetDevice::DoDispose (void) } +void +SimpleNetDevice::SetPromiscReceiveCallback (PromiscReceiveCallback cb) +{ + NS_FATAL_ERROR ("Not supported"); +} + +bool +SimpleNetDevice::SupportsPromiscuous (void) const +{ + return false; +} } // namespace ns3 diff --git a/src/node/simple-net-device.h b/src/node/simple-net-device.h index ac77c5cc5..cd441021f 100644 --- a/src/node/simple-net-device.h +++ b/src/node/simple-net-device.h @@ -68,6 +68,8 @@ public: virtual void SetNode (Ptr node); virtual bool NeedsArp (void) const; virtual void SetReceiveCallback (NetDevice::ReceiveCallback cb); + virtual void SetPromiscReceiveCallback (PromiscReceiveCallback cb); + virtual bool SupportsPromiscuous (void) const; protected: virtual void DoDispose (void); From 565483bc095e3a6d37ba9ae991698f8fe2a32856 Mon Sep 17 00:00:00 2001 From: "Gustavo J. A. M. Carneiro" Date: Thu, 24 Jul 2008 17:24:01 +0100 Subject: [PATCH 198/495] hg ignore the pybindgen checkout dir --- .hgignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.hgignore b/.hgignore index 37ab5d22a..95df8a6af 100644 --- a/.hgignore +++ b/.hgignore @@ -26,3 +26,4 @@ doc/manual/manual.vr ^doc/manual/figures/.*eps ^doc/manual/figures/.*pdf ^doc/manual/figures/.*png +^bindings/python/pybindgen/ From fbf681955e3f2c758dd0d9723d66b24612b96b18 Mon Sep 17 00:00:00 2001 From: "Gustavo J. A. M. Carneiro" Date: Fri, 25 Jul 2008 16:51:40 +0100 Subject: [PATCH 199/495] Make the LogComponent* utility functions available for optimized builds as well, albeit as noops. Closes #258. --- src/core/log.cc | 34 ++++++++++- src/core/log.h | 156 ++++++++++++++++++++++++------------------------ 2 files changed, 111 insertions(+), 79 deletions(-) diff --git a/src/core/log.cc b/src/core/log.cc index ec9fad101..cc050bfd0 100644 --- a/src/core/log.cc +++ b/src/core/log.cc @@ -17,13 +17,13 @@ * * Author: Mathieu Lacage */ +#include "log.h" #ifdef NS3_LOG_ENABLE #include #include #include -#include "log.h" #include "assert.h" #include "ns3/core-config.h" #include "fatal-error.h" @@ -368,4 +368,34 @@ ParameterLogger::ParameterLogger (std::ostream &os) } // namespace ns3 -#endif // NS3_LOG_ENABLE +#else // NS3_LOG_ENABLE + +namespace ns3 { + +void +LogComponentEnable (char const *name, enum LogLevel level) +{ + +} + +void +LogComponentEnableAll (enum LogLevel level) +{ + +} + +void +LogComponentDisable (char const *name, enum LogLevel level) +{ + +} + +void +LogComponentDisableAll (enum LogLevel level) +{ + +} + +} // namespace ns3 + +#endif diff --git a/src/core/log.h b/src/core/log.h index f2565d71a..fd6af9952 100644 --- a/src/core/log.h +++ b/src/core/log.h @@ -24,6 +24,85 @@ #include #include +namespace ns3 { + +enum LogLevel { + LOG_NONE = 0x00000000, // no logging + + LOG_ERROR = 0x00000001, // serious error messages only + LOG_LEVEL_ERROR = 0x00000001, + + LOG_WARN = 0x00000002, // warning messages + LOG_LEVEL_WARN = 0x00000003, + + LOG_DEBUG = 0x00000004, // rare ad-hoc debug messages + LOG_LEVEL_DEBUG = 0x00000007, + + LOG_INFO = 0x00000008, // informational messages (e.g., banners) + LOG_LEVEL_INFO = 0x0000000f, + + LOG_FUNCTION = 0x00000010, // function tracing + LOG_LEVEL_FUNCTION = 0x0000001f, + + LOG_LOGIC = 0x00000020, // control flow tracing within functions + LOG_LEVEL_LOGIC = 0x0000003f, + + LOG_ALL = 0x3fffffff, // print everything + LOG_LEVEL_ALL = LOG_ALL, + + LOG_PREFIX_FUNC = 0x80000000, // prefix all trace prints with function + LOG_PREFIX_TIME = 0x40000000 // prefix all trace prints with simulation time +}; + +/** + * \param name a log component name + * \param level a logging level + * \ingroup logging + * + * Enable the logging output associated with that log component. + * The logging output can be later disabled with a call + * to ns3::LogComponentDisable. + * + * Same as running your program with the NS_LOG environment + * variable set as NS_LOG='name=level' + */ +void LogComponentEnable (char const *name, enum LogLevel level); + +/** + * \param level a logging level + * \ingroup logging + * + * Enable the logging output for all registered log components. + * + * Same as running your program with the NS_LOG environment + * variable set as NS_LOG='*=level' + */ +void LogComponentEnableAll (enum LogLevel level); + + +/** + * \param name a log component name + * \param level a logging level + * \ingroup logging + * + * Disable the logging output associated with that log component. + * The logging output can be later re-enabled with a call + * to ns3::LogComponentEnable. + */ +void LogComponentDisable (char const *name, enum LogLevel level); + +/** + * \param level a logging level + * \ingroup logging + * + * Disable all logging for all components. + */ +void LogComponentDisableAll (enum LogLevel level); + + +} // namespace ns3 + + #ifdef NS3_LOG_ENABLE @@ -230,79 +309,6 @@ namespace ns3 { -enum LogLevel { - LOG_NONE = 0x00000000, // no logging - - LOG_ERROR = 0x00000001, // serious error messages only - LOG_LEVEL_ERROR = 0x00000001, - - LOG_WARN = 0x00000002, // warning messages - LOG_LEVEL_WARN = 0x00000003, - - LOG_DEBUG = 0x00000004, // rare ad-hoc debug messages - LOG_LEVEL_DEBUG = 0x00000007, - - LOG_INFO = 0x00000008, // informational messages (e.g., banners) - LOG_LEVEL_INFO = 0x0000000f, - - LOG_FUNCTION = 0x00000010, // function tracing - LOG_LEVEL_FUNCTION = 0x0000001f, - - LOG_LOGIC = 0x00000020, // control flow tracing within functions - LOG_LEVEL_LOGIC = 0x0000003f, - - LOG_ALL = 0x3fffffff, // print everything - LOG_LEVEL_ALL = LOG_ALL, - - LOG_PREFIX_FUNC = 0x80000000, // prefix all trace prints with function - LOG_PREFIX_TIME = 0x40000000 // prefix all trace prints with simulation time -}; - -/** - * \param name a log component name - * \param level a logging level - * \ingroup logging - * - * Enable the logging output associated with that log component. - * The logging output can be later disabled with a call - * to ns3::LogComponentDisable. - * - * Same as running your program with the NS_LOG environment - * variable set as NS_LOG='name=level' - */ -void LogComponentEnable (char const *name, enum LogLevel level); - -/** - * \param level a logging level - * \ingroup logging - * - * Enable the logging output for all registered log components. - * - * Same as running your program with the NS_LOG environment - * variable set as NS_LOG='*=level' - */ -void LogComponentEnableAll (enum LogLevel level); - - -/** - * \param name a log component name - * \param level a logging level - * \ingroup logging - * - * Disable the logging output associated with that log component. - * The logging output can be later re-enabled with a call - * to ns3::LogComponentEnable. - */ -void LogComponentDisable (char const *name, enum LogLevel level); - -/** - * \param level a logging level - * \ingroup logging - * - * Disable all logging for all components. - */ -void LogComponentDisableAll (enum LogLevel level); - /** * \ingroup logging @@ -373,10 +379,6 @@ public: #define NS_LOG_UNCOND(msg) #define LogComponentPrintList -#define LogComponentEnable(name,level) -#define LogComponentDisable(name,level) -#define LogComponentEnableAll(level) -#define LogComponentDisableAll(level) #define LogRegisterTimePrinter(printer) #define LogSetTimePrinter(printer) From 5e24aed9dd71348441af37c78e9e4ef44164bc48 Mon Sep 17 00:00:00 2001 From: "Gustavo J. A. M. Carneiro" Date: Fri, 25 Jul 2008 16:54:29 +0100 Subject: [PATCH 200/495] When python scanning API, remove again the NS3_LOG_ENABLE define; it is no longer needed. --- bindings/python/ns3_module_common.py | 4 +-- bindings/python/ns3_module_core.py | 51 ++-------------------------- bindings/python/ns3modulescan.py | 4 +-- 3 files changed, 6 insertions(+), 53 deletions(-) diff --git a/bindings/python/ns3_module_common.py b/bindings/python/ns3_module_common.py index b6a44c031..2b9ad84e3 100644 --- a/bindings/python/ns3_module_common.py +++ b/bindings/python/ns3_module_common.py @@ -609,10 +609,10 @@ def register_Ns3BufferIterator_methods(root_module, cls): return def register_Ns3Chunk_methods(root_module, cls): - ## chunk.h: ns3::Chunk::Chunk(ns3::Chunk const & arg0) [copy constructor] - cls.add_constructor([param('ns3::Chunk&', 'arg0', is_const=True)]) ## chunk.h: ns3::Chunk::Chunk() [constructor] cls.add_constructor([]) + ## chunk.h: ns3::Chunk::Chunk(ns3::Chunk const & arg0) [copy constructor] + cls.add_constructor([param('ns3::Chunk&', 'arg0', is_const=True)]) ## chunk.h: static ns3::TypeId ns3::Chunk::GetTypeId() [member function] cls.add_method('GetTypeId', 'ns3::TypeId', diff --git a/bindings/python/ns3_module_core.py b/bindings/python/ns3_module_core.py index c2ebbafaa..a0d187ade 100644 --- a/bindings/python/ns3_module_core.py +++ b/bindings/python/ns3_module_core.py @@ -119,8 +119,6 @@ def register_types(module): module.add_class('TracedCallback', template_parameters=['unsigned int', 'unsigned int', 'ns3::empty', 'ns3::empty']) ## random-variable.h: ns3::DeterministicVariable [class] module.add_class('DeterministicVariable', parent=root_module['ns3::RandomVariable']) - ## log.h: ns3::LogComponent [class] - module.add_class('LogComponent') ## attribute-list.h: ns3::AttributeList [class] module.add_class('AttributeList') ## attribute.h: ns3::AttributeValue [class] @@ -272,7 +270,6 @@ def register_methods(root_module): register_Ns3TracedCallback__Ns3Ptr__lt__ns3Packet_const__gt___Double_Ns3WifiMode_Ns3WifiPreamble_methods(root_module, root_module['ns3::TracedCallback< ns3::Ptr, double, ns3::WifiMode, ns3::WifiPreamble >']) register_Ns3TracedCallback__Unsigned_int_Unsigned_int_Ns3Empty_Ns3Empty_methods(root_module, root_module['ns3::TracedCallback< unsigned int, unsigned int, ns3::empty, ns3::empty >']) register_Ns3DeterministicVariable_methods(root_module, root_module['ns3::DeterministicVariable']) - register_Ns3LogComponent_methods(root_module, root_module['ns3::LogComponent']) register_Ns3AttributeList_methods(root_module, root_module['ns3::AttributeList']) register_Ns3AttributeValue_methods(root_module, root_module['ns3::AttributeValue']) register_Ns3UniformVariable_methods(root_module, root_module['ns3::UniformVariable']) @@ -892,10 +889,10 @@ def register_Ns3Empty_methods(root_module, cls): return def register_Ns3ObjectBase_methods(root_module, cls): - ## object-base.h: ns3::ObjectBase::ObjectBase(ns3::ObjectBase const & arg0) [copy constructor] - cls.add_constructor([param('ns3::ObjectBase&', 'arg0', is_const=True)]) ## object-base.h: ns3::ObjectBase::ObjectBase() [constructor] cls.add_constructor([]) + ## object-base.h: ns3::ObjectBase::ObjectBase(ns3::ObjectBase const & arg0) [copy constructor] + cls.add_constructor([param('ns3::ObjectBase&', 'arg0', is_const=True)]) ## object-base.h: static ns3::TypeId ns3::ObjectBase::GetTypeId() [member function] cls.add_method('GetTypeId', 'ns3::TypeId', @@ -1332,38 +1329,6 @@ def register_Ns3DeterministicVariable_methods(root_module, cls): cls.add_constructor([param('double *', 'd'), param('uint32_t', 'c')]) return -def register_Ns3LogComponent_methods(root_module, cls): - ## log.h: ns3::LogComponent::LogComponent(char const * name) [constructor] - cls.add_constructor([param('char *', 'name', transfer_ownership=False, is_const=True)]) - ## log.h: void ns3::LogComponent::EnvVarCheck(char const * name) [member function] - cls.add_method('EnvVarCheck', - 'void', - [param('char *', 'name', transfer_ownership=False, is_const=True)]) - ## log.h: bool ns3::LogComponent::IsEnabled(ns3::LogLevel level) const [member function] - cls.add_method('IsEnabled', - 'bool', - [param('ns3::LogLevel', 'level')], - is_const=True) - ## log.h: bool ns3::LogComponent::IsNoneEnabled() const [member function] - cls.add_method('IsNoneEnabled', - 'bool', - [], - is_const=True) - ## log.h: void ns3::LogComponent::Enable(ns3::LogLevel level) [member function] - cls.add_method('Enable', - 'void', - [param('ns3::LogLevel', 'level')]) - ## log.h: void ns3::LogComponent::Disable(ns3::LogLevel level) [member function] - cls.add_method('Disable', - 'void', - [param('ns3::LogLevel', 'level')]) - ## log.h: char const * ns3::LogComponent::Name() const [member function] - cls.add_method('Name', - retval('char *', is_const=True, caller_owns_return=False), - [], - is_const=True) - return - def register_Ns3AttributeList_methods(root_module, cls): ## attribute-list.h: ns3::AttributeList::AttributeList() [constructor] cls.add_constructor([]) @@ -2090,10 +2055,6 @@ def register_functions(root_module): module.add_function('MakeObjectFactoryChecker', 'ns3::Ptr< ns3::AttributeChecker const >', []) - ## log.h: extern ns3::LogTimePrinter ns3::LogGetTimePrinter() [free function] - module.add_function('LogGetTimePrinter', - 'ns3::LogTimePrinter *', - []) ## log.h: extern void ns3::LogComponentDisableAll(ns3::LogLevel level) [free function] module.add_function('LogComponentDisableAll', 'void', @@ -2106,10 +2067,6 @@ def register_functions(root_module): module.add_function('MakeRandomVariableChecker', 'ns3::Ptr< ns3::AttributeChecker const >', []) - ## log.h: extern void ns3::LogSetTimePrinter(ns3::LogTimePrinter arg0) [free function] - module.add_function('LogSetTimePrinter', - 'void', - [param('ns3::LogTimePrinter *', 'arg0')]) ## log.h: extern void ns3::LogComponentDisable(char const * name, ns3::LogLevel level) [free function] module.add_function('LogComponentDisable', 'void', @@ -2118,10 +2075,6 @@ def register_functions(root_module): module.add_function('LogComponentEnable', 'void', [param('char *', 'name', transfer_ownership=False, is_const=True), param('ns3::LogLevel', 'level')]) - ## log.h: extern void ns3::LogComponentPrintList() [free function] - module.add_function('LogComponentPrintList', - 'void', - []) register_functions_ns3_internal(module.get_submodule('internal'), root_module) register_functions_ns3_TimeStepPrecision(module.get_submodule('TimeStepPrecision'), root_module) register_functions_ns3_Config(module.get_submodule('Config'), root_module) diff --git a/bindings/python/ns3modulescan.py b/bindings/python/ns3modulescan.py index 8f77d5829..05be63d55 100644 --- a/bindings/python/ns3modulescan.py +++ b/bindings/python/ns3modulescan.py @@ -255,8 +255,8 @@ def ns3_module_scan(top_builddir, pygen_file_name, everything_h): gccxml_options = dict( include_paths=[top_builddir], define_symbols={ - 'NS3_ASSERT_ENABLE': None, - 'NS3_LOG_ENABLE': None, + #'NS3_ASSERT_ENABLE': None, + #'NS3_LOG_ENABLE': None, } ) From c95c773d1750de4f1bbdf451ea38aef8d1ed196d Mon Sep 17 00:00:00 2001 From: "Gustavo J. A. M. Carneiro" Date: Sat, 26 Jul 2008 15:10:34 +0100 Subject: [PATCH 201/495] When generating the everything.h header file for Python, handle ns3 headers inside subdirectories properly. --- bindings/python/wscript | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/bindings/python/wscript b/bindings/python/wscript index 9f0b33811..9713505e6 100644 --- a/bindings/python/wscript +++ b/bindings/python/wscript @@ -186,9 +186,19 @@ def get_header_prio(header): return prio return 1 + +def calc_header_include(path): + (head, tail) = os.path.split (path) + if tail == 'ns3': + return '' + else: + return os.path.join (calc_header_include (head), tail) + + def gen_ns3_metaheader(task): assert len(task.m_outputs) == 1 - header_files = [os.path.basename(node.abspath(task.m_env)) for node in task.m_inputs] + + header_files = [calc_header_include(node.abspath(task.m_env)) for node in task.m_inputs] outfile = file(task.m_outputs[0].bldpath(task.m_env), "w") def sort_func(h1, h2): @@ -243,8 +253,8 @@ class all_ns3_headers_taskgen(Object.task_gen): continue for source in ns3headers.to_list(ns3headers.source): - source = os.path.basename(source) - node = ns3_dir_node.find_build(os.path.basename(source)) + #source = os.path.basename(source) + node = ns3_dir_node.find_build(source) if node is None: fatal("missing header file %s" % (source,)) all_headers_inputs.append(node) From 91f0ef0320b2016fea819f1e5c63578edd9e67d9 Mon Sep 17 00:00:00 2001 From: "Gustavo J. A. M. Carneiro" Date: Sat, 26 Jul 2008 15:23:41 +0100 Subject: [PATCH 202/495] Only generate everything.h if python bindings are enabled. Based on patch by Mathieu Lacage. Closes #260. --- bindings/python/wscript | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/bindings/python/wscript b/bindings/python/wscript index 9713505e6..c691e3fc1 100644 --- a/bindings/python/wscript +++ b/bindings/python/wscript @@ -301,7 +301,8 @@ def build(bld): #Object.register('all-ns3-headers', AllNs3Headers) Action.Action('gen-ns3-metaheader', func=gen_ns3_metaheader, color='BLUE') - obj = bld.create_obj('all_ns3_headers') + if env['ENABLE_PYTHON_BINDINGS']: + obj = bld.create_obj('all_ns3_headers') if Params.g_options.python_scan: if not env['ENABLE_PYTHON_SCANNING']: From b157853a0c33586b570f585e90d3ecdf6afc4f49 Mon Sep 17 00:00:00 2001 From: "Gustavo J. A. M. Carneiro" Date: Mon, 28 Jul 2008 16:06:46 +0100 Subject: [PATCH 203/495] OLSR: HELLO messages hold time should be 3 times hello interval, not hello interval. --- src/routing/olsr/olsr-agent-impl.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/routing/olsr/olsr-agent-impl.cc b/src/routing/olsr/olsr-agent-impl.cc index 851deef3d..942ae8181 100644 --- a/src/routing/olsr/olsr-agent-impl.cc +++ b/src/routing/olsr/olsr-agent-impl.cc @@ -1388,7 +1388,7 @@ AgentImpl::SendHello () msg.SetMessageSequenceNumber (GetMessageSequenceNumber ()); olsr::MessageHeader::Hello &hello = msg.GetHello (); - hello.SetHTime (m_helloInterval); + hello.SetHTime (Scalar (3) * m_helloInterval); hello.willingness = m_willingness; std::vector From 8d844b7502a3be1639dd7861c37f6c9740901829 Mon Sep 17 00:00:00 2001 From: Sebastien Vincent Date: Mon, 28 Jul 2008 08:30:32 -0700 Subject: [PATCH 204/495] bug 262: fix g++ 4.3 build --- src/core/unix-system-mutex.cc | 1 + src/core/unix-system-thread.cc | 1 + 2 files changed, 2 insertions(+) diff --git a/src/core/unix-system-mutex.cc b/src/core/unix-system-mutex.cc index afbaf518c..9a01a3a33 100644 --- a/src/core/unix-system-mutex.cc +++ b/src/core/unix-system-mutex.cc @@ -19,6 +19,7 @@ */ #include +#include #include #include "fatal-error.h" #include "system-mutex.h" diff --git a/src/core/unix-system-thread.cc b/src/core/unix-system-thread.cc index 9fbd7a73e..c607b3b43 100644 --- a/src/core/unix-system-thread.cc +++ b/src/core/unix-system-thread.cc @@ -19,6 +19,7 @@ */ #include +#include #include "fatal-error.h" #include "system-thread.h" #include "log.h" From 36f196a9a0d54a75b61b4f52562febf7c4fadfd9 Mon Sep 17 00:00:00 2001 From: Mathieu Lacage Date: Mon, 28 Jul 2008 08:54:20 -0700 Subject: [PATCH 205/495] bug 252: get rid of dead code. --- src/simulator/default-simulator-impl.cc | 31 --- src/simulator/default-simulator-impl.h | 2 - src/simulator/simulator-impl.h | 1 - src/simulator/simulator.cc | 5 +- src/simulator/simulator.h | 16 +- utils/bench-simulator.cc | 6 - utils/replay-simulation.cc | 330 ------------------------ utils/wscript | 3 - 8 files changed, 3 insertions(+), 391 deletions(-) delete mode 100644 utils/replay-simulation.cc diff --git a/src/simulator/default-simulator-impl.cc b/src/simulator/default-simulator-impl.cc index fca228dd3..57a11d6f8 100644 --- a/src/simulator/default-simulator-impl.cc +++ b/src/simulator/default-simulator-impl.cc @@ -57,7 +57,6 @@ DefaultSimulatorImpl::DefaultSimulatorImpl () m_uid = 4; // before ::Run is entered, the m_currentUid will be zero m_currentUid = 0; - m_logEnable = false; m_currentTs = 0; m_unscheduledEvents = 0; } @@ -106,12 +105,6 @@ DefaultSimulatorImpl::GetScheduler (void) const return m_events; } -void -DefaultSimulatorImpl::EnableLogTo (char const *filename) -{ - m_log.open (filename); - m_logEnable = true; -} void DefaultSimulatorImpl::ProcessOneEvent (void) @@ -124,10 +117,6 @@ DefaultSimulatorImpl::ProcessOneEvent (void) NS_LOG_LOGIC ("handle " << next.GetTs ()); m_currentTs = next.GetTs (); m_currentUid = next.GetUid (); - if (m_logEnable) - { - m_log << "e "<Invoke (); } @@ -190,11 +179,6 @@ DefaultSimulatorImpl::Schedule (Time const &time, const Ptr &event) NS_ASSERT (time >= TimeStep (m_currentTs)); uint64_t ts = (uint64_t) time.GetTimeStep (); EventId id (event, ts, m_uid); - if (m_logEnable) - { - m_log << "i "<Insert (id); @@ -205,11 +189,6 @@ EventId DefaultSimulatorImpl::ScheduleNow (const Ptr &event) { EventId id (event, m_currentTs, m_uid); - if (m_logEnable) - { - m_log << "i "<Insert (id); @@ -221,11 +200,6 @@ DefaultSimulatorImpl::ScheduleDestroy (const Ptr &event) { EventId id (event, m_currentTs, 2); m_destroyEvents.push_back (id); - if (m_logEnable) - { - m_log << "id " << m_currentUid << " " << Now ().GetTimeStep () << " " - << m_uid << std::endl; - } m_uid++; return id; } @@ -272,11 +246,6 @@ DefaultSimulatorImpl::Remove (const EventId &ev) m_events->Remove (ev); Cancel (ev); - if (m_logEnable) - { - m_log << "r " << m_currentUid << " " << m_currentTs << " " - << ev.GetUid () << " " << ev.GetTs () << std::endl; - } --m_unscheduledEvents; } diff --git a/src/simulator/default-simulator-impl.h b/src/simulator/default-simulator-impl.h index a3c321018..c2ca1d31c 100644 --- a/src/simulator/default-simulator-impl.h +++ b/src/simulator/default-simulator-impl.h @@ -45,8 +45,6 @@ public: void Destroy (); - void EnableLogTo (char const *filename); - bool IsFinished (void) const; Time Next (void) const; void Stop (void); diff --git a/src/simulator/simulator-impl.h b/src/simulator/simulator-impl.h index 86b871d58..7887e5b45 100644 --- a/src/simulator/simulator-impl.h +++ b/src/simulator/simulator-impl.h @@ -38,7 +38,6 @@ class SimulatorImpl : public Object { public: virtual void Destroy () = 0; - virtual void EnableLogTo (char const *filename) = 0; virtual bool IsFinished (void) const = 0; virtual Time Next (void) const = 0; virtual void Stop (void) = 0; diff --git a/src/simulator/simulator.cc b/src/simulator/simulator.cc index 0dd3c003c..9df1f1b85 100644 --- a/src/simulator/simulator.cc +++ b/src/simulator/simulator.cc @@ -122,10 +122,7 @@ Simulator::SetScheduler (Ptr scheduler) void Simulator::EnableLogTo (char const *filename) -{ - NS_LOG_FUNCTION (filename); - GetImpl ()->EnableLogTo (filename); -} +{} bool Simulator::IsFinished (void) diff --git a/src/simulator/simulator.h b/src/simulator/simulator.h index 8b833dede..6972c5f6c 100644 --- a/src/simulator/simulator.h +++ b/src/simulator/simulator.h @@ -27,6 +27,7 @@ #include "scheduler.h" #include "ns3/type-traits.h" +#include "ns3/deprecated.h" #include #include @@ -79,20 +80,7 @@ public: */ static void SetScheduler (Ptr scheduler); - /** - * Enable logging to the file identified by filename. If the file - * does not exist, it is created. If it exists, it is destroyed and - * re-created. Every scheduling event is logged to this file in a - * simple text format which can be read back by the event replay - * utility. This allows you to record the scheduling behavior of - * a simulation, and measure the exact overhead related to - * event scheduling with the event replay utility. It is also possible - * to compare the performance of every scheduling algorithms on this - * specific scheduling load. - * This method must be invoked before any call to Simulator::run - * @param filename the name of the file to log to - */ - static void EnableLogTo (char const *filename); + static void EnableLogTo (char const *filename) NS_DEPRECATED; /** * Every event scheduled by the Simulator::insertAtDestroy method is diff --git a/utils/bench-simulator.cc b/utils/bench-simulator.cc index 6480ab5f5..1c096b113 100644 --- a/utils/bench-simulator.cc +++ b/utils/bench-simulator.cc @@ -130,7 +130,6 @@ PrintHelp (void) std::cout << " --list: use std::list scheduler"< - */ - -#include "ns3/simulator-module.h" -#include "ns3/core-module.h" -#include -#include -#include -#include -#include - -using namespace ns3; - -class LogReader { -public: - void ReadFromFilename (char const *filename); - void Run (void); - void PrintStats (void); -private: - struct Command { - enum { - REMOVE = 100, - INSERT, - INSERT_LATER, - INSERT_REMOVE - } m_type; - // uid at which this command is supposed to be executed. - uint32_t m_uid; - union { - struct { - // time at which the event is supposed to expire - uint64_t m_evNs; - uint32_t m_evUid; - } insert; - struct { - // location in the array of events to remove where - // to insert this event once it is inserted in - // the scheduler. - uint32_t m_evLoc; - // time at which the event is supposed to expire - uint64_t m_evNs; - } insertRemove; - }; - }; - void ExecuteLogCommands (uint32_t uid); - - typedef std::vector Commands; - typedef std::vector::iterator CommandsI; - typedef std::vector RemoveEvents; - typedef std::vector::iterator RemoveEventsI; - - - Commands m_commands; - CommandsI m_command; - RemoveEvents m_removeEvents; - uint32_t m_uid; -}; - -typedef std::vector > Removes; -typedef std::vector >::iterator RemovesI; - -void -LogReader::ReadFromFilename (char const *filename) -{ - std::ifstream log; - std::cout << "read log..." << std::endl; - Removes removes; - log.open (filename); - while (!log.eof ()) - { - std::string type; - log >> type; - if (type == "i") - { - uint32_t nowUid, evUid; - uint64_t nowNs, evNs; - log >> nowUid >> nowNs >> evUid >> evNs; - struct Command cmd; - cmd.m_type = Command::INSERT; - cmd.m_uid = nowUid; - cmd.insert.m_evNs = evNs; - cmd.insert.m_evUid = evUid; - m_commands.push_back (cmd); - } - else if (type == "r") - { - uint32_t nowUid, evUid; - uint64_t nowNs, evNs; - log >> nowUid >> nowNs >> evUid >> evNs; - struct Command cmd; - cmd.m_type = Command::REMOVE; - cmd.m_uid = nowUid; - m_commands.push_back (cmd); - removes.push_back (std::make_pair (nowUid, evUid)); - } - else if (type == "il") - { - uint32_t nowUid, evUid; - uint64_t nowNs, evNs; - log >> nowUid >> nowNs >> evUid >> evNs; - struct Command cmd; - cmd.m_type = Command::INSERT_LATER; - cmd.m_uid = nowUid; - m_commands.push_back (cmd); - } - } - log.close (); - - std::cout << "gather insert/removes, commands="<m_type == Command::INSERT) - { - for (RemovesI j = removes.begin (); j != removes.end (); j++) - { - if (j->second == i->insert.m_evUid) - { - // this insert will be removed later. - uint64_t ns = i->insert.m_evNs; - uint32_t uid = i->m_uid; - i->m_type = Command::INSERT_REMOVE; - i->m_uid = uid; - i->insertRemove.m_evNs = ns; - i->insertRemove.m_evLoc = j->first; - break; - } - } - } - } - std::cout << "calculate remove locations..." << std::endl; - // calculate the final insert/remove location. - for (CommandsI i = m_commands.begin (); i != m_commands.end (); i++) - { - if (i->m_type == Command::INSERT_REMOVE) - { - uint32_t loc = 0; - for (CommandsI tmp = i; tmp != m_commands.end (); tmp++) - { - if (tmp->m_type == Command::REMOVE) - { - if (tmp->m_uid == i->insertRemove.m_evLoc) - { - i->insertRemove.m_evLoc = loc; - break; - } - loc++; - } - } - } - } -} -void -LogReader::ExecuteLogCommands (uint32_t uid) -{ - if (m_command == m_commands.end ()) - { - return; - } - //std::cout << "one event, uid=" < m_removeEvents.size ()) - { - uint32_t missing = cmd.insertRemove.m_evLoc + 1 - m_removeEvents.size (); - m_removeEvents.insert (m_removeEvents.begin (), - missing, id); - } - uint32_t index = m_removeEvents.size () - cmd.insertRemove.m_evLoc - 1; - m_removeEvents[index] = id; - m_uid++; - } break; - default: - NS_ASSERT (false); - break; - } - cmd = *m_command; - } -} - -void -LogReader::PrintStats (void) -{ - uint32_t nInserts = 0; - uint32_t nRemoves = 0; - for (CommandsI i = m_commands.begin (); i != m_commands.end (); i++) - { - switch (i->m_type) { - case Command::INSERT: - nInserts++; - break; - case Command::INSERT_LATER: - nInserts++; - break; - case Command::INSERT_REMOVE: - nInserts++; - break; - case Command::REMOVE: - nRemoves++; - break; - } - } - std::cout << "inserts="< 0) - { - if (strcmp ("--list", argv[0]) == 0) - { - is_list = true; - } - else if (strcmp ("--heap", argv[0]) == 0) - { - is_heap = true; - } - else if (strcmp ("--map", argv[0]) == 0) - { - is_map = true; - } - else if (strncmp ("--n=", argv[0], strlen("--n=")) == 0) - { - n = atoi (argv[0]+strlen ("--n=")); - } - else if (strncmp ("--input=", argv[0],strlen ("--input=")) == 0) - { - input = argv[0] + strlen ("--input="); - } - else if (strncmp ("--log=", argv[0],strlen ("--log=")) == 0) - { - char const *filename = argv[0] + strlen ("--log="); - Simulator::EnableLogTo (filename); - } - argc--; - argv++; - } - if (input == 0) - { - std::cerr << "need --input=[filename] option" << std::endl; - return 1; - } - LogReader log; - log.ReadFromFilename (input); - std::cout << "start runs..." << std::endl; - for (uint32_t i = 0; i < n; i++) - { - if (is_map) - { - Simulator::SetScheduler (CreateObject ()); - } - else if (is_list) - { - Simulator::SetScheduler (CreateObject ()); - } - else if (is_heap) - { - Simulator::SetScheduler (CreateObject ()); - } - log.Run (); - Simulator::Destroy (); - } -} diff --git a/utils/wscript b/utils/wscript index f6cc97626..dfbd84c1f 100644 --- a/utils/wscript +++ b/utils/wscript @@ -24,9 +24,6 @@ def build(bld): obj = bld.create_ns3_program('bench-packets', ['common']) obj.source = 'bench-packets.cc' - obj = bld.create_ns3_program('replay-simulation', ['simulator']) - obj.source = 'replay-simulation.cc' - obj = bld.create_ns3_program('print-introspected-doxygen', ['internet-stack', 'csma-cd', 'point-to-point']) obj.source = 'print-introspected-doxygen.cc' From 89cb48c524fef92b1a598da900a7d7ff24982b29 Mon Sep 17 00:00:00 2001 From: Mathieu Lacage Date: Mon, 28 Jul 2008 08:59:05 -0700 Subject: [PATCH 206/495] bug 252: make python bindings compile --- bindings/python/ns3_module_simulator.py | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/bindings/python/ns3_module_simulator.py b/bindings/python/ns3_module_simulator.py index badde30a5..1c68ef1cd 100644 --- a/bindings/python/ns3_module_simulator.py +++ b/bindings/python/ns3_module_simulator.py @@ -614,11 +614,6 @@ def register_Ns3SimulatorImpl_methods(root_module, cls): 'void', [], is_pure_virtual=True, is_virtual=True) - ## simulator-impl.h: void ns3::SimulatorImpl::EnableLogTo(char const * filename) [member function] - cls.add_method('EnableLogTo', - 'void', - [param('char *', 'filename', transfer_ownership=False, is_const=True)], - is_pure_virtual=True, is_virtual=True) ## simulator-impl.h: bool ns3::SimulatorImpl::IsFinished() const [member function] cls.add_method('IsFinished', 'bool', @@ -715,11 +710,6 @@ def register_Ns3DefaultSimulatorImpl_methods(root_module, cls): 'void', [], is_virtual=True) - ## default-simulator-impl.h: void ns3::DefaultSimulatorImpl::EnableLogTo(char const * filename) [member function] - cls.add_method('EnableLogTo', - 'void', - [param('char *', 'filename', transfer_ownership=False, is_const=True)], - is_virtual=True) ## default-simulator-impl.h: bool ns3::DefaultSimulatorImpl::IsFinished() const [member function] cls.add_method('IsFinished', 'bool', From 5857618635c69d198bd4d85ee91205b5e7b5a1af Mon Sep 17 00:00:00 2001 From: Mathieu Lacage Date: Mon, 28 Jul 2008 09:03:10 -0700 Subject: [PATCH 207/495] bug 251: mobility helper has no ascii output --- src/helper/mobility-helper.cc | 36 +++++++++++++++++++++++++++++++++++ src/helper/mobility-helper.h | 30 ++++++++++++++++++++++++++++- 2 files changed, 65 insertions(+), 1 deletion(-) diff --git a/src/helper/mobility-helper.cc b/src/helper/mobility-helper.cc index 1976f0c63..9429ccdf6 100644 --- a/src/helper/mobility-helper.cc +++ b/src/helper/mobility-helper.cc @@ -23,6 +23,8 @@ #include "ns3/hierarchical-mobility-model.h" #include "ns3/log.h" #include "ns3/pointer.h" +#include "ns3/config.h" +#include "ns3/simulator.h" namespace ns3 { @@ -153,4 +155,38 @@ MobilityHelper::InstallAll (void) Install (NodeContainer::GetGlobal ()); } +void +MobilityHelper::CourseChanged (std::ostream *os, Ptr mobility) +{ + Ptr node = mobility->GetObject (); + *os << "now=" << Simulator::Now () + << " node=" << node->GetId () + << " pos=" << mobility->GetPosition () + << " vel=" << mobility->GetVelocity () + << std::endl; +} + +void +MobilityHelper::EnableAscii (std::ostream &os, uint32_t nodeid) +{ + std::ostringstream oss; + oss << "/NodeList/" << nodeid << "/$ns3::MobilityModel/CourseChange"; + Config::ConnectWithoutContext (oss.str (), + MakeBoundCallback (&MobilityHelper::CourseChanged, &os)); +} +void +MobilityHelper::EnableAscii (std::ostream &os, NodeContainer n) +{ + for (NodeContainer::Iterator i = n.Begin (); i != n.End (); ++i) + { + EnableAscii (os, (*i)->GetId ()); + } +} +void +MobilityHelper::EnableAsciiAll (std::ostream &os) +{ + EnableAscii (os, NodeContainer::GetGlobal ()); +} + + } // namespace ns3 diff --git a/src/helper/mobility-helper.h b/src/helper/mobility-helper.h index d37eb36c6..21ee5d9d6 100644 --- a/src/helper/mobility-helper.h +++ b/src/helper/mobility-helper.h @@ -163,8 +163,36 @@ public: * exist in the simulation. */ void InstallAll (void); -private: + /** + * \param os output stream + * \param nodeid the id of the node to generate ascii output for. + * + * Enable ascii output on the mobility model associated to the + * specified nodeid and dump that to the specified stdc++ output + * stream. + */ + static void EnableAscii (std::ostream &os, uint32_t nodeid); + /** + * \param os output stream + * \param n node container + * + * Enable ascii output on the mobility model associated each of + * the nodes in the input container and dump that to the + * specified stdc++ output stream. + */ + static void EnableAscii (std::ostream &os, NodeContainer n); + /** + * \param os output stream + * + * Enable ascii output on the mobility model associated + * every node in the system and dump that to the specified + * stdc++ output stream. + */ + static void EnableAsciiAll (std::ostream &os); + +private: + static void CourseChanged (std::ostream *os, Ptr mobility); std::vector > m_mobilityStack; ObjectFactory m_mobility; Ptr m_position; From 1f86e826e5e95e84dbdd1455b3203ff7708d47d4 Mon Sep 17 00:00:00 2001 From: Mathieu Lacage Date: Tue, 29 Jul 2008 11:19:16 -0700 Subject: [PATCH 208/495] bug 264: NS_BREAKPOINT never stops the debugger at the right location. --- src/core/assert.h | 13 ++++++------- src/core/fatal-error.h | 11 ++++++----- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/core/assert.h b/src/core/assert.h index 3dadf537c..235ad9db1 100644 --- a/src/core/assert.h +++ b/src/core/assert.h @@ -24,8 +24,6 @@ #include -#include "breakpoint.h" - /** * \ingroup core * \defgroup debugging Debugging @@ -49,8 +47,7 @@ * * At runtime, in debugging builds, if this condition is not * true, the program prints the source file, line number and - * unverified condition and halts in the ns3::AssertBreakpoint - * function. + * unverified condition and halts by dereferencing a null pointer. */ #define NS_ASSERT(condition) \ do \ @@ -60,7 +57,8 @@ std::cerr << "assert failed. file=" << __FILE__ << \ ", line=" << __LINE__ << ", cond=\""#condition << \ "\"" << std::endl; \ - NS_BREAKPOINT (); \ + int *a = 0; \ + *a = 0; \ } \ } \ while (false) @@ -73,7 +71,7 @@ * * At runtime, in debugging builds, if this condition is not * true, the program prints the message to output and - * halts in the ns3::AssertBreakpoint function. + * halts by dereferencing a null pointer. */ #define NS_ASSERT_MSG(condition, message) \ do \ @@ -81,7 +79,8 @@ if (!(condition)) \ { \ std::cerr << message << std::endl; \ - NS_BREAKPOINT (); \ + int *a = 0; \ + *a = 0; \ } \ } \ while (false) diff --git a/src/core/fatal-error.h b/src/core/fatal-error.h index 8e896cf2f..05711780c 100644 --- a/src/core/fatal-error.h +++ b/src/core/fatal-error.h @@ -20,7 +20,6 @@ #ifndef FATAL_ERROR_H #define FATAL_ERROR_H -#include "breakpoint.h" #include /** @@ -30,15 +29,17 @@ * \param msg message to output when this macro is hit. * * When this macro is hit at runtime, the user-specified - * error message is output and the program is halted by calling - * the NS_BREAKPOINT macro. This macro is enabled unconditionally - * in all builds, including debug and optimized builds. + * error message is output and the program is halted by + * dereferencing a null pointer. This macro is enabled + * unconditionally in all builds, including debug and + * optimized builds. */ #define NS_FATAL_ERROR(msg) \ do \ { \ std::cerr << msg << std::endl; \ - NS_BREAKPOINT (); \ + int *a = 0; \ + *a = 0; \ } \ while (false) From caaae1c1dd4d00f96ac10e23955f527f65d3496d Mon Sep 17 00:00:00 2001 From: Raj Bhattacharjea Date: Tue, 29 Jul 2008 15:36:41 -0400 Subject: [PATCH 209/495] Fix TcpSocketImpl rx buffer logic (closes 248) --- src/internet-stack/tcp-socket-impl.cc | 147 +++++++++++++++++++++----- src/internet-stack/tcp-socket-impl.h | 1 + 2 files changed, 121 insertions(+), 27 deletions(-) diff --git a/src/internet-stack/tcp-socket-impl.cc b/src/internet-stack/tcp-socket-impl.cc index cb970df79..abd008ee1 100644 --- a/src/internet-stack/tcp-socket-impl.cc +++ b/src/internet-stack/tcp-socket-impl.cc @@ -1053,11 +1053,21 @@ void TcpSocketImpl::NewRx (Ptr p, // 3) Received seq is > expected, just re-ack previous and buffer data if (tcpHeader.GetSequenceNumber () == m_nextRxSequence) { // If seq is expected seq + // Trim the end if necessary // 1) Update nextRxSeq // 2) Buffer this packet so Recv can read it // 3) Send the ack + UnAckData_t::iterator next = m_bufferedData.upper_bound (m_nextRxSequence); + if (next != m_bufferedData.end ()) + { + SequenceNumber nextBufferedSeq = next->first; + if (m_nextRxSequence + SequenceNumber(s) > nextBufferedSeq) + {//tail end isn't all new, trim enough off the end + s = nextBufferedSeq - m_nextRxSequence; + } + } + p = p->CreateFragment (0,s); m_nextRxSequence += s; // Advance next expected sequence - //bytesReceived += s; // Statistics NS_LOG_LOGIC("Case 1, advanced nrxs to " << m_nextRxSequence ); SocketAddressTag tag; tag.SetAddress (fromAddress); @@ -1072,27 +1082,7 @@ void TcpSocketImpl::NewRx (Ptr p, // Save for later delivery m_bufferedData[tcpHeader.GetSequenceNumber () ] = p; m_rxAvailable += p->GetSize (); - //putting this into the buffer might have filled in a sequence gap - //so we have to iterate through the list to find the largest contiguous - //sequenced chunk, and update m_rxAvailable appropriately - i = m_bufferedData.find (tcpHeader.GetSequenceNumber () ); - UnAckData_t::iterator next = i; - next++; - while(next != m_bufferedData.end()) - { - if(i->first + SequenceNumber(i->second->GetSize ()) == next->first) - { - //next packet is in sequence, count it - m_rxAvailable += next->second->GetSize(); - m_nextRxSequence += next->second->GetSize(); - } - else - { - break; //no more in this contiguous chunk - } - ++i; - ++next; - } + RxBufFinishInsert (tcpHeader.GetSequenceNumber ()); NotifyDataRecv (); if (m_closeNotified) { @@ -1107,20 +1097,93 @@ void TcpSocketImpl::NewRx (Ptr p, } } } - else if (SequenceNumber (tcpHeader.GetSequenceNumber ()) >= m_nextRxSequence) - { // Need to buffer this one + else if (tcpHeader.GetSequenceNumber () > m_nextRxSequence) + { // Need to buffer this one, but trim off the front and back if necessary NS_LOG_LOGIC ("Case 2, buffering " << tcpHeader.GetSequenceNumber () ); + UnAckData_t::iterator previous = + m_bufferedData.lower_bound (tcpHeader.GetSequenceNumber ()); + SequenceNumber startSeq = tcpHeader.GetSequenceNumber(); + if (previous != m_bufferedData.begin ()) + { + --previous; + startSeq = previous->first + SequenceNumber(previous->second->GetSize()); + if (startSeq > tcpHeader.GetSequenceNumber ()) + { + s = tcpHeader.GetSequenceNumber () + SequenceNumber(s) - startSeq; + } + else + { + startSeq = tcpHeader.GetSequenceNumber(); + } + } + //possibly trim off the end + UnAckData_t::iterator next = m_bufferedData.upper_bound (tcpHeader.GetSequenceNumber()); + if (next != m_bufferedData.end ()) + { + SequenceNumber nextBufferedSeq = next->first; + if (startSeq + SequenceNumber(s) > nextBufferedSeq) + {//tail end isn't all new either, trim enough off the end + s = nextBufferedSeq - startSeq; + } + } + p = p->CreateFragment (startSeq - tcpHeader.GetSequenceNumber (),s); UnAckData_t::iterator i = - m_bufferedData.find (tcpHeader.GetSequenceNumber () ); + m_bufferedData.find (startSeq); if (i != m_bufferedData.end () ) { - i->second = 0; // relase reference to already buffered + if(p->GetSize() > i->second->GetSize()) + { + i->second = 0; // relase reference to already buffered + } + else + { + p = i->second; + } } // Save for later delivery SocketAddressTag tag; tag.SetAddress (fromAddress); p->AddTag (tag); - m_bufferedData[tcpHeader.GetSequenceNumber () ] = p; + m_bufferedData[startSeq] = p; + i = m_bufferedData.find (startSeq); + next = i; + ++next; + if(next != m_bufferedData.end()) + { + NS_ASSERT(next->first >= i->first + SequenceNumber(i->second->GetSize ())); + } + } + else if (tcpHeader.GetSequenceNumber () + SequenceNumber(s) > m_nextRxSequence) + {//parial new data case, only part of the packet is new data + //trim the beginning + s = tcpHeader.GetSequenceNumber () + SequenceNumber(s) - m_nextRxSequence; //how much new + //possibly trim off the end + UnAckData_t::iterator next = m_bufferedData.upper_bound (m_nextRxSequence); + if (next != m_bufferedData.end ()) + { + SequenceNumber nextBufferedSeq = next->first; + if (m_nextRxSequence + SequenceNumber(s) > nextBufferedSeq) + {//tail end isn't all new either, trim enough off the end + s = nextBufferedSeq - m_nextRxSequence; + } + } + p = p->CreateFragment (m_nextRxSequence - tcpHeader.GetSequenceNumber (),s); + SequenceNumber start = m_nextRxSequence; + m_nextRxSequence += s; // Advance next expected sequence + SocketAddressTag tag; + tag.SetAddress (fromAddress); + p->AddTag (tag); + //buffer the new fragment, it'll be read by call to Recv + UnAckData_t::iterator i = m_bufferedData.find (start); + if (i != m_bufferedData.end () ) //we found it already in the buffer + { + i->second = 0; // relase reference to already buffered + } + // Save for later delivery + m_bufferedData[start] = p; + m_rxAvailable += p->GetSize (); + RxBufFinishInsert(start); + NotifyDataRecv (); } else { // debug @@ -1142,6 +1205,36 @@ void TcpSocketImpl::NewRx (Ptr p, } } +void TcpSocketImpl::RxBufFinishInsert (SequenceNumber seq) +{ + //putting data into the buffer might have filled in a sequence gap so we have + //to iterate through the list to find the largest contiguous sequenced chunk, + //and update m_rxAvailable and m_nextRxSequence appropriately + UnAckData_t::iterator i = m_bufferedData.find (seq); + UnAckData_t::iterator next = i; + ++next; + //make sure the buffer is logically sequenced + if(next != m_bufferedData.end()) + { + NS_ASSERT(next->first >= i->first + SequenceNumber(i->second->GetSize ())); + } + while(next != m_bufferedData.end()) + { + if(i->first + SequenceNumber(i->second->GetSize ()) == next->first) + { + //next packet is in sequence, count it + m_rxAvailable += next->second->GetSize(); + m_nextRxSequence += next->second->GetSize(); + } + else + { + break; //no more in this contiguous chunk + } + ++i; + ++next; + } +} + void TcpSocketImpl::DelAckTimeout () { m_delAckCount = 0; diff --git a/src/internet-stack/tcp-socket-impl.h b/src/internet-stack/tcp-socket-impl.h index 3817a28c1..8f2597124 100644 --- a/src/internet-stack/tcp-socket-impl.h +++ b/src/internet-stack/tcp-socket-impl.h @@ -123,6 +123,7 @@ private: // Manage data tx/rx void NewRx (Ptr, const TcpHeader&, const Address&); + void RxBufFinishInsert (SequenceNumber); // XXX This should be virtual and overridden Ptr Copy (); void NewAck (SequenceNumber seq); From 3af1dc723509e24653b2de6775b7df3b6a203698 Mon Sep 17 00:00:00 2001 From: Tom Henderson Date: Wed, 30 Jul 2008 06:30:42 -0700 Subject: [PATCH 210/495] revised patch to fix bug 253 --- src/internet-stack/arp-cache.cc | 124 +++++++++++++++++++++++++- src/internet-stack/arp-cache.h | 56 +++++++++++- src/internet-stack/arp-l3-protocol.cc | 12 +-- src/internet-stack/arp-l3-protocol.h | 2 +- 4 files changed, 178 insertions(+), 16 deletions(-) diff --git a/src/internet-stack/arp-cache.cc b/src/internet-stack/arp-cache.cc index cee855236..4da9c4091 100644 --- a/src/internet-stack/arp-cache.cc +++ b/src/internet-stack/arp-cache.cc @@ -22,6 +22,8 @@ #include "ns3/simulator.h" #include "ns3/uinteger.h" #include "ns3/log.h" +#include "ns3/node.h" +#include "ns3/trace-source-accessor.h" #include "arp-cache.h" #include "arp-header.h" @@ -47,15 +49,23 @@ ArpCache::GetTypeId (void) MakeTimeAccessor (&ArpCache::m_deadTimeout), MakeTimeChecker ()) .AddAttribute ("WaitReplyTimeout", - "When this timeout expires, the matching cache entry is marked dead", + "When this timeout expires, the cache entries will be scanned and entries in WaitReply state will resend ArpRequest unless MaxRetries has been exceeded, in which case the entry is marked dead", TimeValue (Seconds (1)), MakeTimeAccessor (&ArpCache::m_waitReplyTimeout), MakeTimeChecker ()) + .AddAttribute ("MaxRetries", + "Number of retransmissions of ArpRequest before marking dead", + UintegerValue (3), + MakeUintegerAccessor (&ArpCache::m_maxRetries), + MakeUintegerChecker ()) .AddAttribute ("PendingQueueSize", "The size of the queue for packets pending an arp reply.", UintegerValue (3), MakeUintegerAccessor (&ArpCache::m_pendingQueueSize), MakeUintegerChecker ()) + .AddTraceSource ("Drop", + "Packet dropped due to ArpCache entry in WaitReply expiring.", + MakeTraceSourceAccessor (&ArpCache::m_dropTrace)) ; return tid; } @@ -79,6 +89,10 @@ ArpCache::DoDispose (void) Flush (); m_device = 0; m_interface = 0; + if (!m_waitReplyTimer.IsRunning ()) + { + Simulator::Remove (m_waitReplyTimer); + } Object::DoDispose (); } @@ -142,6 +156,73 @@ ArpCache::GetWaitReplyTimeout (void) const return m_waitReplyTimeout; } +void +ArpCache::SetArpRequestCallback (Callback, + Ipv4Address> arpRequestCallback) +{ + NS_LOG_FUNCTION_NOARGS (); + m_arpRequestCallback = arpRequestCallback; +} + +void +ArpCache::StartWaitReplyTimer (void) +{ + NS_LOG_FUNCTION_NOARGS (); + if (!m_waitReplyTimer.IsRunning ()) + { + NS_LOG_LOGIC ("Starting WaitReplyTimer at " << Simulator::Now ().GetSeconds ()); + m_waitReplyTimer = Simulator::Schedule (m_waitReplyTimeout, + &ArpCache::HandleWaitReplyTimeout, this); + } +} + +void +ArpCache::HandleWaitReplyTimeout (void) +{ + NS_LOG_FUNCTION_NOARGS (); + ArpCache::Entry* entry; + bool restartWaitReplyTimer = false; + for (CacheI i = m_arpCache.begin (); i != m_arpCache.end (); i++) + { + entry = (*i).second; + if (entry != 0 && entry->IsWaitReply () && entry->IsExpired ()) + { + if (entry->GetRetries () < m_maxRetries) + { + NS_LOG_LOGIC ("node="<< m_device->GetNode ()->GetId () << + ", ArpWaitTimeout for " << entry->GetIpv4Address () << + " expired -- retransmitting arp request since retries = " << + entry->GetRetries ()); + m_arpRequestCallback (this, entry->GetIpv4Address ()); + restartWaitReplyTimer = true; + entry->IncrementRetries (); + } + else + { + NS_LOG_LOGIC ("node="<GetNode ()->GetId () << + ", wait reply for " << entry->GetIpv4Address () << + " expired -- drop since max retries exceeded: " << + entry->GetRetries ()); + entry->MarkDead (); + entry->ClearRetries (); + Ptr pending = entry->DequeuePending(); + while (pending != 0) + { + m_dropTrace (pending); + pending = entry->DequeuePending(); + } + } + } + + } + if (restartWaitReplyTimer) + { + NS_LOG_LOGIC ("Restarting WaitReplyTimer at " << Simulator::Now ().GetSeconds ()); + m_waitReplyTimer = Simulator::Schedule (m_waitReplyTimeout, + &ArpCache::HandleWaitReplyTimeout, this); + } +} + void ArpCache::Flush (void) { @@ -173,12 +254,14 @@ ArpCache::Add (Ipv4Address to) ArpCache::Entry *entry = new ArpCache::Entry (this); m_arpCache[to] = entry; + entry->SetIpv4Address (to); return entry; } ArpCache::Entry::Entry (ArpCache *arp) : m_arp (arp), - m_state (ALIVE) + m_state (ALIVE), + m_retries (0) { NS_LOG_FUNCTION_NOARGS (); } @@ -209,6 +292,7 @@ ArpCache::Entry::MarkDead (void) { NS_LOG_FUNCTION_NOARGS (); m_state = DEAD; + ClearRetries (); UpdateSeen (); } void @@ -218,6 +302,7 @@ ArpCache::Entry::MarkAlive (Address macAddress) NS_ASSERT (m_state == WAIT_REPLY); m_macAddress = macAddress; m_state = ALIVE; + ClearRetries (); UpdateSeen (); } @@ -246,15 +331,29 @@ ArpCache::Entry::MarkWaitReply (Ptr waiting) m_state = WAIT_REPLY; m_pending.push_back (waiting); UpdateSeen (); + m_arp->StartWaitReplyTimer (); } Address -ArpCache::Entry::GetMacAddress (void) +ArpCache::Entry::GetMacAddress (void) const { NS_LOG_FUNCTION_NOARGS (); NS_ASSERT (m_state == ALIVE); return m_macAddress; } +Ipv4Address +ArpCache::Entry::GetIpv4Address (void) const +{ + NS_LOG_FUNCTION_NOARGS (); + return m_ipv4Address; +} +void +ArpCache::Entry::SetIpv4Address (Ipv4Address destination) +{ + NS_LOG_FUNCTION (this << destination); + m_ipv4Address = destination; +} + bool ArpCache::Entry::IsExpired (void) { @@ -307,6 +406,25 @@ ArpCache::Entry::UpdateSeen (void) NS_LOG_FUNCTION_NOARGS (); m_lastSeen = Simulator::Now (); } +uint32_t +ArpCache::Entry::GetRetries (void) const +{ + NS_LOG_FUNCTION_NOARGS (); + return m_retries; +} +void +ArpCache::Entry::IncrementRetries (void) +{ + NS_LOG_FUNCTION_NOARGS (); + m_retries++; + UpdateSeen (); +} +void +ArpCache::Entry::ClearRetries (void) +{ + NS_LOG_FUNCTION_NOARGS (); + m_retries = 0; +} } // namespace ns3 diff --git a/src/internet-stack/arp-cache.h b/src/internet-stack/arp-cache.h index 899bd70d9..1a27ff4f7 100644 --- a/src/internet-stack/arp-cache.h +++ b/src/internet-stack/arp-cache.h @@ -22,6 +22,8 @@ #include #include +#include "ns3/simulator.h" +#include "ns3/callback.h" #include "ns3/packet.h" #include "ns3/nstime.h" #include "ns3/net-device.h" @@ -29,6 +31,7 @@ #include "ns3/address.h" #include "ns3/ptr.h" #include "ns3/object.h" +#include "ns3/traced-callback.h" #include "sgi-hashmap.h" namespace ns3 { @@ -72,7 +75,22 @@ public: Time GetWaitReplyTimeout (void) const; /** - * \brief Do lookup in the ARP chache against an IP address + * This callback is set when the ArpCache is set up and allows + * the cache to generate an Arp request when the WaitReply + * time expires and a retransmission must be sent + * + * \param arpRequestCallback Callback for transmitting an Arp request. + */ + void SetArpRequestCallback (Callback, + Ipv4Address> arpRequestCallback); + /** + * This method will schedule a timeout at WaitReplyTimeout interval + * in the future, unless a timer is already running for the cache, + * in which case this method does nothing. + */ + void StartWaitReplyTimer (void); + /** + * \brief Do lookup in the ARP cache against an IP address * \param destination The destination IPv4 address to lookup the MAC address * of * \return An ArpCache::Entry with info about layer 2 @@ -131,7 +149,15 @@ public: /** * \return The MacAddress of this entry */ - Address GetMacAddress (void); + Address GetMacAddress (void) const; + /** + * \return The Ipv4Address for this entry + */ + Ipv4Address GetIpv4Address (void) const; + /** + * \param The Ipv4Address for this entry + */ + void SetIpv4Address (Ipv4Address destination); /** * \return True if this entry has timedout; false otherwise. */ @@ -142,6 +168,20 @@ public: * packets are pending. */ Ptr DequeuePending (void); + /** + * \returns number of retries that have been sent for an ArpRequest + * in WaitReply state. + */ + uint32_t GetRetries (void) const; + /** + * \brief Increment the counter of number of retries for an entry + */ + void IncrementRetries (void); + /** + * \brief Zero the counter of number of retries for an entry + */ + void ClearRetries (void); + private: enum ArpCacheEntryState_e { ALIVE, @@ -154,7 +194,9 @@ public: ArpCacheEntryState_e m_state; Time m_lastSeen; Address m_macAddress; + Ipv4Address m_ipv4Address; std::list > m_pending; + uint32_t m_retries; }; private: @@ -168,8 +210,18 @@ private: Time m_aliveTimeout; Time m_deadTimeout; Time m_waitReplyTimeout; + EventId m_waitReplyTimer; + Callback, Ipv4Address> m_arpRequestCallback; + uint32_t m_maxRetries; + /** + * This function is an event handler for the event that the + * ArpCache wants to check whether it must retry any Arp requests. + * If there are no Arp requests pending, this event is not scheduled. + */ + void HandleWaitReplyTimeout (void); uint32_t m_pendingQueueSize; Cache m_arpCache; + TracedCallback > m_dropTrace; }; diff --git a/src/internet-stack/arp-l3-protocol.cc b/src/internet-stack/arp-l3-protocol.cc index 894a4cf83..7620b7046 100644 --- a/src/internet-stack/arp-l3-protocol.cc +++ b/src/internet-stack/arp-l3-protocol.cc @@ -95,6 +95,7 @@ ArpL3Protocol::CreateCache (Ptr device, Ptr interface) cache->SetDevice (device, interface); NS_ASSERT (device->IsBroadcast ()); device->SetLinkChangeCallback (MakeCallback (&ArpCache::Flush, cache)); + cache->SetArpRequestCallback (MakeCallback (&ArpL3Protocol::SendArpRequest, this)); m_cacheList.push_back (cache); return cache; } @@ -218,16 +219,7 @@ ArpL3Protocol::Lookup (Ptr packet, Ipv4Address destination, } else if (entry->IsWaitReply ()) { - NS_LOG_LOGIC ("node="<GetId ()<< - ", wait reply for " << destination << " expired -- drop"); - entry->MarkDead (); - Ptr pending = entry->DequeuePending(); - while (pending != 0) - { - m_dropTrace (pending); - pending = entry->DequeuePending(); - } - m_dropTrace (packet); + NS_FATAL_ERROR ("Test for possibly unreachable code-- please file a bug report if this is ever hit"); } } else diff --git a/src/internet-stack/arp-l3-protocol.h b/src/internet-stack/arp-l3-protocol.h index 0f131a71b..61507a13b 100644 --- a/src/internet-stack/arp-l3-protocol.h +++ b/src/internet-stack/arp-l3-protocol.h @@ -52,7 +52,7 @@ public: Ptr CreateCache (Ptr device, Ptr interface); /** - * \brief Recieve a packet + * \brief Receive a packet */ void Receive(Ptr device, Ptr p, uint16_t protocol, const Address &from, const Address &to, NetDevice::PacketType packetType); From 317878411aeee38308c3449b6eec65b3f8b7f344 Mon Sep 17 00:00:00 2001 From: Mathieu Lacage Date: Wed, 30 Jul 2008 12:43:43 -0700 Subject: [PATCH 211/495] kill dead code --- src/simulator/default-simulator-impl.cc | 2 -- src/simulator/default-simulator-impl.h | 3 --- 2 files changed, 5 deletions(-) diff --git a/src/simulator/default-simulator-impl.cc b/src/simulator/default-simulator-impl.cc index 57a11d6f8..3fc8c6aca 100644 --- a/src/simulator/default-simulator-impl.cc +++ b/src/simulator/default-simulator-impl.cc @@ -154,8 +154,6 @@ DefaultSimulatorImpl::Run (void) // If the simulator stopped naturally by lack of events, make a // consistency test to check that we didn't lose any events along the way. NS_ASSERT(!m_events->IsEmpty () || m_unscheduledEvents == 0); - - m_log.close (); } void diff --git a/src/simulator/default-simulator-impl.h b/src/simulator/default-simulator-impl.h index c2ca1d31c..d61025fa6 100644 --- a/src/simulator/default-simulator-impl.h +++ b/src/simulator/default-simulator-impl.h @@ -75,9 +75,6 @@ private: uint32_t m_uid; uint32_t m_currentUid; uint64_t m_currentTs; - std::ofstream m_log; - std::ifstream m_inputLog; - bool m_logEnable; // number of events that have been inserted but not yet scheduled, // not counting the "destroy" events; this is used for validation int m_unscheduledEvents; From 660c536a496596a57b1d4784b2205a2b6597eb9e Mon Sep 17 00:00:00 2001 From: Mathieu Lacage Date: Wed, 30 Jul 2008 12:44:34 -0700 Subject: [PATCH 212/495] use fully-qualified c++ typename to allow using macros outside of the ns3 namespace. --- src/core/log.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/log.h b/src/core/log.h index fd6af9952..ff0fd5b1b 100644 --- a/src/core/log.h +++ b/src/core/log.h @@ -151,7 +151,7 @@ void LogComponentDisableAll (enum LogLevel level); #define NS_LOG_APPEND_TIME_PREFIX \ if (g_log.IsEnabled (ns3::LOG_PREFIX_TIME)) \ { \ - LogTimePrinter printer = LogGetTimePrinter (); \ + ns3::LogTimePrinter printer = ns3::LogGetTimePrinter (); \ if (printer != 0) \ { \ (*printer) (std::clog); \ From 172db792a86c493b721c3072b614b99781b71fe8 Mon Sep 17 00:00:00 2001 From: Raj Bhattacharjea Date: Wed, 30 Jul 2008 16:36:57 -0400 Subject: [PATCH 213/495] Misspelling in AUTHORS file --- AUTHORS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/AUTHORS b/AUTHORS index 4f0da03d7..969ea04dd 100644 --- a/AUTHORS +++ b/AUTHORS @@ -1,4 +1,4 @@ -Raj Bhattarcharjea (raj.b@gatech.edu) +Raj Bhattacharjea (raj.b@gatech.edu) Gustavo Carneiro (gjc@inescporto.pt, gjcarneiro@gmail.com) Craig Dowell (craigdo@ee.washington.edu) Tom Henderson (tomhend@u.washington.edu) From 4ba6e58745fa04e1da4abcf02540a873ab67bf40 Mon Sep 17 00:00:00 2001 From: Mathieu Lacage Date: Thu, 31 Jul 2008 15:04:01 -0700 Subject: [PATCH 214/495] bug 266: src/wscript unconditionally sets conf.env['NS3_MODULE_PATH'] --- src/wscript | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/wscript b/src/wscript index 1ebbc2bf7..e8e2938ec 100644 --- a/src/wscript +++ b/src/wscript @@ -51,7 +51,7 @@ def configure(conf): conf.sub_config('contrib') blddir = os.path.abspath(os.path.join(conf.m_blddir, conf.env.variant())) - conf.env['NS3_MODULE_PATH'] = [blddir] + conf.env.append_value('NS3_MODULE_PATH', blddir) if Params.g_options.enable_rpath: conf.env.append_value('RPATH', '-Wl,-rpath=%s' % (os.path.join(blddir),)) From 27df0a5c92ac468b01ec2ac93ef29b86b951bb4e Mon Sep 17 00:00:00 2001 From: "Gustavo J. A. M. Carneiro" Date: Fri, 1 Aug 2008 23:11:42 +0100 Subject: [PATCH 215/495] Python: use hash() as temporary workaround to check if two objects with different wrappers are underneath the same. --- bindings/python/wscript | 2 +- utils/python-unit-tests.py | 16 +++++++++++++++- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/bindings/python/wscript b/bindings/python/wscript index c691e3fc1..799fa5e82 100644 --- a/bindings/python/wscript +++ b/bindings/python/wscript @@ -21,7 +21,7 @@ else: os.environ['PYTHONPATH'] = LOCAL_PYBINDGEN_PATH ## https://launchpad.net/pybindgen/ -REQUIRED_PYBINDGEN_VERSION = (0, 8, 0, 516) +REQUIRED_PYBINDGEN_VERSION = (0, 9, 0, 526) REQUIRED_PYGCCXML_VERSION = (0, 9, 5) diff --git a/utils/python-unit-tests.py b/utils/python-unit-tests.py index 18d6b5d96..623b16b7c 100644 --- a/utils/python-unit-tests.py +++ b/utils/python-unit-tests.py @@ -105,8 +105,22 @@ class TestSimulator(unittest.TestCase): ptr = ns3.PointerValue() mobility.GetAttribute("Position", ptr) self.assert_(ptr.GetObject() is not None) - + def testIdentity(self): + csma = ns3.CsmaNetDevice() + channel = ns3.CsmaChannel() + csma.Attach(channel) + + c1 = csma.GetChannel() + c2 = csma.GetChannel() + + ## FIXME: it is a PyBindGen bug that comparison via hash + ## functions is required. However it should be noted that + ## hash(channel) here basically returns the self->obj pointer, + ## so if hash(c1) == hash(c2) then we know for sure that c1 + ## and c2 are the same channel, even if with different python + ## wrappers. + self.assertEqual(hash(c1), hash(c2)) if __name__ == '__main__': unittest.main() From 7a711ae53ebb86aaf79926987f2d31342c144186 Mon Sep 17 00:00:00 2001 From: Mathieu Lacage Date: Sun, 3 Aug 2008 09:14:07 -0700 Subject: [PATCH 216/495] bug 269: revert parts of 9e763021e045 and add comments to avoid getting these again. --- src/simulator/simulator.cc | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/simulator/simulator.cc b/src/simulator/simulator.cc index 9df1f1b85..183e0c5a8 100644 --- a/src/simulator/simulator.cc +++ b/src/simulator/simulator.cc @@ -67,8 +67,9 @@ TimePrinter (std::ostream &os) SimulatorImpl * Simulator::GetImpl (void) { - NS_LOG_FUNCTION_NOARGS (); - + /* Please, don't include any calls to logging macros in this function + * or pay the price, that is, stack explosions. + */ if (m_impl == 0) { ObjectFactory factory; @@ -90,7 +91,6 @@ Simulator::GetImpl (void) // LogSetTimePrinter (&TimePrinter); } - NS_LOG_LOGIC ("priv " << m_impl); return PeekPointer (m_impl); } @@ -162,7 +162,9 @@ Simulator::Stop (Time const &time) Time Simulator::Now (void) { - NS_LOG_FUNCTION_NOARGS (); + /* Please, don't include any calls to logging macros in this function + * or pay the price, that is, stack explosions. + */ return GetImpl ()->Now (); } From 3a519a71da60a2b2baaf22f67622ebf881acdbb3 Mon Sep 17 00:00:00 2001 From: Craig Dowell Date: Sun, 3 Aug 2008 21:55:49 -0700 Subject: [PATCH 217/495] 128 column pages --- src/devices/csma/backoff.cc | 33 ++- src/devices/csma/backoff.h | 60 ++-- src/devices/csma/csma-channel.cc | 20 +- src/devices/csma/csma-channel.h | 54 ++-- src/devices/csma/csma-net-device.cc | 426 +++++++++++++--------------- src/devices/csma/csma-net-device.h | 54 ++-- 6 files changed, 320 insertions(+), 327 deletions(-) diff --git a/src/devices/csma/backoff.cc b/src/devices/csma/backoff.cc index e01355efa..e249104fa 100644 --- a/src/devices/csma/backoff.cc +++ b/src/devices/csma/backoff.cc @@ -22,7 +22,7 @@ namespace ns3 { -Backoff::Backoff() +Backoff::Backoff () { m_slotTime = MicroSeconds(1); m_minSlots = 1; @@ -33,8 +33,7 @@ Backoff::Backoff() ResetBackoffTime(); } -Backoff::Backoff(Time slotTime, uint32_t minSlots, uint32_t maxSlots, - uint32_t ceiling, uint32_t maxRetries) +Backoff::Backoff(Time slotTime, uint32_t minSlots, uint32_t maxSlots, uint32_t ceiling, uint32_t maxRetries) { m_slotTime = slotTime; m_minSlots = minSlots; @@ -50,32 +49,42 @@ Backoff::GetBackoffTime (void) uint32_t ceiling; if ((m_ceiling > 0) &&(m_numBackoffRetries > m_ceiling)) - ceiling = m_ceiling; + { + ceiling = m_ceiling; + } else - ceiling = m_numBackoffRetries; + { + ceiling = m_numBackoffRetries; + } uint32_t minSlot = m_minSlots; - uint32_t maxSlot = (uint32_t)pow(2, ceiling) - 1; + uint32_t maxSlot = (uint32_t)pow (2, ceiling) - 1; if (maxSlot > m_maxSlots) - maxSlot = m_maxSlots; + { + maxSlot = m_maxSlots; + } - uint32_t backoffSlots = - (uint32_t)UniformVariable::GetSingleValue(minSlot, maxSlot); + uint32_t backoffSlots = (uint32_t)UniformVariable::GetSingleValue(minSlot, maxSlot); backoff = Scalar(backoffSlots) * m_slotTime; return (backoff); } -void Backoff::ResetBackoffTime (void) +void +Backoff::ResetBackoffTime (void) { m_numBackoffRetries = 0; } -bool Backoff::MaxRetriesReached(void) { +bool +Backoff::MaxRetriesReached (void) +{ return (m_numBackoffRetries >= m_maxRetries); } -void Backoff::IncrNumRetries(void) { +void +Backoff::IncrNumRetries (void) +{ m_numBackoffRetries++; } diff --git a/src/devices/csma/backoff.h b/src/devices/csma/backoff.h index adf270076..d15de4452 100644 --- a/src/devices/csma/backoff.h +++ b/src/devices/csma/backoff.h @@ -36,49 +36,63 @@ namespace ns3 { class Backoff { public: - uint32_t m_minSlots; // Minimum number of backoff slots (when - // multiplied by m_slotTime, determines minimum - // backoff time) - uint32_t m_maxSlots; // Maximim number of backoff slots (when - // multiplied by m_slotTime, determines - // maximum backoff time) - uint32_t m_ceiling; // Caps the exponential function when the - // number of retries reaches m_ceiling - uint32_t m_maxRetries; // Maximum number of transmission retries - // before the packet is dropped. - Time m_slotTime; // Length of one slot. A slot time, it usually - // the packet transmission time, if the packet - // size is fixed. + /** + * Minimum number of backoff slots (when multiplied by m_slotTime, determines minimum backoff time) + */ + uint32_t m_minSlots; - Backoff(); - Backoff(Time slotTime, uint32_t minSlots, uint32_t maxSlots, - uint32_t ceiling, uint32_t maxRetries); + /** + * Maximim number of backoff slots (when multiplied by m_slotTime, determines maximum backoff time) + */ + uint32_t m_maxSlots; + + /** + * Caps the exponential function when the number of retries reaches m_ceiling. + */ + uint32_t m_ceiling; + + /** + * Maximum number of transmission retries before the packet is dropped. + */ + uint32_t m_maxRetries; + + /** + * Length of one slot. A slot time, it usually the packet transmission time, if the packet size is fixed. + */ + Time m_slotTime; + + Backoff (void); + Backoff (Time slotTime, uint32_t minSlots, uint32_t maxSlots, uint32_t ceiling, uint32_t maxRetries); /** * \return The amount of time that the net device should wait before * trying to retransmit the packet */ Time GetBackoffTime(); + /** * Indicates to the backoff object that the last packet was * successfully transmitted and that the number of retries should be * reset to 0. */ - void ResetBackoffTime(); + void ResetBackoffTime (void); + /** * \return True if the maximum number of retries has been reached */ - bool MaxRetriesReached(); + bool MaxRetriesReached (void); + /** * Increments the number of retries by 1. */ - void IncrNumRetries(); + void IncrNumRetries (void); private: - uint32_t m_numBackoffRetries; // Number of times that the - // transmitter has tried to - // unsuccessfully transmit the current - // packet + + /** + * Number of times that the transmitter has tried to unsuccessfully transmit the current packet. + */ + uint32_t m_numBackoffRetries; }; }; // namespace ns3 diff --git a/src/devices/csma/csma-channel.cc b/src/devices/csma/csma-channel.cc index 3ba7564e5..ab2a83bf3 100644 --- a/src/devices/csma/csma-channel.cc +++ b/src/devices/csma/csma-channel.cc @@ -37,8 +37,7 @@ CsmaChannel::GetTypeId (void) .SetParent () .AddConstructor () .AddAttribute ("DataRate", - "The transmission data rate to be provided to devices " - "connected to the channel", + "The transmission data rate to be provided to devices connected to the channel", DataRateValue (DataRate (0xffffffff)), MakeDataRateAccessor (&CsmaChannel::m_bps), MakeDataRateChecker ()) @@ -126,16 +125,15 @@ CsmaChannel::Detach (uint32_t deviceId) { if (!m_deviceList[deviceId].active) { - NS_LOG_WARN ("CsmaChannel::Detach(): " - "Device is already detached (" << deviceId << ")"); + NS_LOG_WARN ("CsmaChannel::Detach(): Device is already detached (" << deviceId << ")"); return false; } m_deviceList[deviceId].active = false; + if ((m_state == TRANSMITTING) && (m_currentSrc == deviceId)) { - NS_LOG_WARN ("CsmaChannel::Detach(): Device is currently" << - "transmitting (" << deviceId << ")"); + NS_LOG_WARN ("CsmaChannel::Detach(): Device is currently" << "transmitting (" << deviceId << ")"); } return true; @@ -178,8 +176,7 @@ CsmaChannel::TransmitStart (Ptr p, uint32_t srcId) if (!IsActive(srcId)) { - NS_LOG_ERROR ("CsmaChannel::TransmitStart(): " - "Seclected source is not currently attached to network"); + NS_LOG_ERROR ("CsmaChannel::TransmitStart(): Seclected source is not currently attached to network"); return false; } @@ -209,8 +206,7 @@ CsmaChannel::TransmitEnd() if (!IsActive (m_currentSrc)) { - NS_LOG_ERROR ("CsmaChannel::TransmitEnd(): " - "Seclected source was detached before the end of the transmission"); + NS_LOG_ERROR ("CsmaChannel::TransmitEnd(): Seclected source was detached before the end of the transmission"); retVal = false; } @@ -259,10 +255,6 @@ CsmaChannel::GetNumActDevices (void) return numActDevices; } -// -// This is not the number of active devices. This is the total number -// of devices even if some were detached after. -// uint32_t CsmaChannel::GetNDevices (void) const { diff --git a/src/devices/csma/csma-channel.h b/src/devices/csma/csma-channel.h index f2771ccb9..ff92825b3 100644 --- a/src/devices/csma/csma-channel.h +++ b/src/devices/csma/csma-channel.h @@ -32,39 +32,37 @@ class Packet; class CsmaNetDevice; +/** + * \brief CsmaNetDevice Record + * + * Stores the information related to each net device that is + * connected to the channel. + */ +class CsmaDeviceRec { +public: + Ptr< CsmaNetDevice > devicePtr; /// Pointer to the net device + bool active; /// Is net device enabled to TX/RX + + CsmaDeviceRec(); + CsmaDeviceRec(Ptr< CsmaNetDevice > device); + /** - * \brief CsmaNetDevice Record - * - * Stores the information related to each net device that is - * connected to the channel. + * \return If the net device pointed to by the devicePtr is active + * and ready to RX/TX. */ - class CsmaDeviceRec { - public: - Ptr< CsmaNetDevice > devicePtr; /// Pointer to the net device - bool active; /// Is net device enabled to TX/RX + bool IsActive(); +}; - CsmaDeviceRec(); - CsmaDeviceRec(Ptr< CsmaNetDevice > device); - /* - * \return If the net device pointed to by the devicePtr is active - * and ready to RX/TX. - */ - bool IsActive(); +/** + * Current state of the channel + */ +enum WireState + { + IDLE, /**< Channel is IDLE, no packet is being transmitted */ + TRANSMITTING, /**< Channel is BUSY, a packet is being written by a net device */ + PROPAGATING /**< Channel is BUSY, packet is propagating to all attached net devices */ }; - /** - * Current state of the channel - */ - enum WireState - { - IDLE, /**< Channel is IDLE, no packet is being - transmitted */ - TRANSMITTING, /**< Channel is BUSY, a packet is being written - by a net device */ - PROPAGATING /**< Channel is BUSY, packet is propagating to - all attached net devices */ - }; - /** * \brief Csma Channel. * diff --git a/src/devices/csma/csma-net-device.cc b/src/devices/csma/csma-net-device.cc index 32be6215a..10822a015 100644 --- a/src/devices/csma/csma-net-device.cc +++ b/src/devices/csma/csma-net-device.cc @@ -39,61 +39,61 @@ namespace ns3 { NS_OBJECT_ENSURE_REGISTERED (CsmaNetDevice); -TypeId + TypeId CsmaNetDevice::GetTypeId (void) { static TypeId tid = TypeId ("ns3::CsmaNetDevice") .SetParent () .AddConstructor () .AddAttribute ("Address", - "The MAC address of this device.", - Mac48AddressValue (Mac48Address ("ff:ff:ff:ff:ff:ff")), - MakeMac48AddressAccessor (&CsmaNetDevice::m_address), - MakeMac48AddressChecker ()) + "The MAC address of this device.", + Mac48AddressValue (Mac48Address ("ff:ff:ff:ff:ff:ff")), + MakeMac48AddressAccessor (&CsmaNetDevice::m_address), + MakeMac48AddressChecker ()) .AddAttribute ("PayloadLength", - "The max PHY-level payload length of packets sent over this device.", - UintegerValue (DEFAULT_FRAME_LENGTH), - MakeUintegerAccessor (&CsmaNetDevice::m_maxPayloadLength), - MakeUintegerChecker ()) + "The max PHY-level payload length of packets sent over this device.", + UintegerValue (DEFAULT_FRAME_LENGTH), + MakeUintegerAccessor (&CsmaNetDevice::m_maxPayloadLength), + MakeUintegerChecker ()) .AddAttribute ("MTU", - "The MAC-level MTU (client payload) of packets sent over this device.", - UintegerValue (DEFAULT_MTU), - MakeUintegerAccessor (&CsmaNetDevice::m_mtu), - MakeUintegerChecker ()) + "The MAC-level MTU (client payload) of packets sent over this device.", + UintegerValue (DEFAULT_MTU), + MakeUintegerAccessor (&CsmaNetDevice::m_mtu), + MakeUintegerChecker ()) .AddAttribute ("EncapsulationMode", - "The link-layer encapsulation type to use.", - EnumValue (LLC), - MakeEnumAccessor (&CsmaNetDevice::m_encapMode), - MakeEnumChecker (ETHERNET_V1, "EthernetV1", - IP_ARP, "IpArp", - RAW, "Raw", - LLC, "Llc")) + "The link-layer encapsulation type to use.", + EnumValue (LLC), + MakeEnumAccessor (&CsmaNetDevice::m_encapMode), + MakeEnumChecker (ETHERNET_V1, "EthernetV1", + IP_ARP, "IpArp", + RAW, "Raw", + LLC, "Llc")) .AddAttribute ("SendEnable", - "Enable or disable the transmitter section of the device.", - BooleanValue (true), - MakeBooleanAccessor (&CsmaNetDevice::m_sendEnable), - MakeBooleanChecker ()) + "Enable or disable the transmitter section of the device.", + BooleanValue (true), + MakeBooleanAccessor (&CsmaNetDevice::m_sendEnable), + MakeBooleanChecker ()) .AddAttribute ("ReceiveEnable", - "Enable or disable the receiver section of the device.", - BooleanValue (true), - MakeBooleanAccessor (&CsmaNetDevice::m_receiveEnable), - MakeBooleanChecker ()) + "Enable or disable the receiver section of the device.", + BooleanValue (true), + MakeBooleanAccessor (&CsmaNetDevice::m_receiveEnable), + MakeBooleanChecker ()) .AddAttribute ("RxErrorModel", - "The receiver error model used to simulate packet loss", - PointerValue (), - MakePointerAccessor (&CsmaNetDevice::m_receiveErrorModel), - MakePointerChecker ()) + "The receiver error model used to simulate packet loss", + PointerValue (), + MakePointerAccessor (&CsmaNetDevice::m_receiveErrorModel), + MakePointerChecker ()) .AddAttribute ("TxQueue", - "A queue to use as the transmit queue in the device.", - PointerValue (), - MakePointerAccessor (&CsmaNetDevice::m_queue), - MakePointerChecker ()) + "A queue to use as the transmit queue in the device.", + PointerValue (), + MakePointerAccessor (&CsmaNetDevice::m_queue), + MakePointerChecker ()) .AddTraceSource ("Rx", - "The trace source to fire on reception of a MAC packet.", - MakeTraceSourceAccessor (&CsmaNetDevice::m_rxTrace)) + "The trace source to fire on reception of a MAC packet.", + MakeTraceSourceAccessor (&CsmaNetDevice::m_rxTrace)) .AddTraceSource ("Drop", - "Trace source to fire on when a MAC packet is dropped.", - MakeTraceSourceAccessor (&CsmaNetDevice::m_dropTrace)) + "Trace source to fire on when a MAC packet is dropped.", + MakeTraceSourceAccessor (&CsmaNetDevice::m_dropTrace)) ; return tid; } @@ -148,14 +148,14 @@ CsmaNetDevice::SetReceiveEnable (bool receiveEnable) CsmaNetDevice::IsSendEnabled (void) { NS_LOG_FUNCTION_NOARGS (); - return (m_sendEnable); + return m_sendEnable; } bool CsmaNetDevice::IsReceiveEnabled (void) { NS_LOG_FUNCTION_NOARGS (); - return (m_receiveEnable); + return m_receiveEnable; } void @@ -166,12 +166,7 @@ CsmaNetDevice::SetInterframeGap (Time t) } void -CsmaNetDevice::SetBackoffParams ( - Time slotTime, - uint32_t minSlots, - uint32_t maxSlots, - uint32_t ceiling, - uint32_t maxRetries) +CsmaNetDevice::SetBackoffParams (Time slotTime, uint32_t minSlots, uint32_t maxSlots, uint32_t ceiling, uint32_t maxRetries) { NS_LOG_FUNCTION (slotTime << minSlots << maxSlots << ceiling << maxRetries); m_backoff.m_slotTime = slotTime; @@ -182,11 +177,7 @@ CsmaNetDevice::SetBackoffParams ( } void -CsmaNetDevice::AddHeader ( - Ptr p, - Mac48Address source, - Mac48Address dest, - uint16_t protocolNumber) +CsmaNetDevice::AddHeader (Ptr p, Mac48Address source, Mac48Address dest, uint16_t protocolNumber) { NS_LOG_FUNCTION (p << source << dest << protocolNumber); @@ -210,24 +201,24 @@ CsmaNetDevice::AddHeader ( { case IP_ARP: NS_LOG_LOGIC ("Encapsulating packet as IP_ARP (type interpretation)"); -// -// This corresponds to the type interpretation of the lengthType field. -// + // + // This corresponds to the type interpretation of the lengthType field. + // lengthType = protocolNumber; break; case ETHERNET_V1: NS_LOG_LOGIC ("Encapsulating packet as ETHERNET_V1 " "(length interpretation)"); -// -// This corresponds to the length interpretation of the lengthType field. -// The ethernet header and trailer are not counted, see RFC 1042 and -// http://standards.ieee.org/getieee802/download/802.3-2005_section1.pdf, -// Section 3.2.6 a. We just include the size of the "payload." -// + // + // This corresponds to the length interpretation of the lengthType field. + // The ethernet header and trailer are not counted, see RFC 1042 and + // http://standards.ieee.org/getieee802/download/802.3-2005_section1.pdf, + // Section 3.2.6 a. We just include the size of the "payload." + // lengthType = p->GetSize (); NS_ASSERT_MSG (lengthType <= m_maxPayloadLength, - "CsmaNetDevice::AddHeader(): 802.3 Length/Type field: " - "length interpretation must not exceed device max payload length"); + "CsmaNetDevice::AddHeader(): 802.3 Length/Type field: " + "length interpretation must not exceed device max payload length"); break; case LLC: { @@ -236,10 +227,10 @@ CsmaNetDevice::AddHeader ( LlcSnapHeader llc; llc.SetType (protocolNumber); p->AddHeader (llc); -// -// This corresponds to the length interpretation of the lengthType field, -// but with an LLC/SNAP header added to the payload. -// + // + // This corresponds to the length interpretation of the lengthType field, + // but with an LLC/SNAP header added to the payload. + // lengthType = p->GetSize (); NS_ASSERT_MSG (lengthType <= m_maxPayloadLength, "CsmaNetDevice::AddHeader(): 802.3 Length/Type field with LLC/SNAP: " @@ -309,18 +300,18 @@ CsmaNetDevice::TransmitStart () NS_LOG_LOGIC ("m_currentPkt=" << m_currentPkt); NS_LOG_LOGIC ("UID is " << m_currentPkt->GetUid ()); -// -// This function is called to start the process of transmitting a packet. -// We need to tell the channel that we've started wiggling the wire and -// schedule an event that will be executed when it's time to tell the -// channel that we're done wiggling the wire. -// + // + // This function is called to start the process of transmitting a packet. + // We need to tell the channel that we've started wiggling the wire and + // schedule an event that will be executed when it's time to tell the + // channel that we're done wiggling the wire. + // NS_ASSERT_MSG ((m_txMachineState == READY) || (m_txMachineState == BACKOFF), - "Must be READY to transmit. Tx state is: " << m_txMachineState); + "Must be READY to transmit. Tx state is: " << m_txMachineState); -// -// Only transmit if send side of net device is enabled -// + // + // Only transmit if send side of net device is enabled + // if (IsSendEnabled () == false) { return; @@ -328,16 +319,16 @@ CsmaNetDevice::TransmitStart () if (m_channel->GetState () != IDLE) { -// -// The channel is busy -- backoff and rechedule TransmitStart () -// + // + // The channel is busy -- backoff and rechedule TransmitStart () + // m_txMachineState = BACKOFF; if (m_backoff.MaxRetriesReached ()) { -// -// Too many retries, abort transmission of packet -// + // + // Too many retries, abort transmission of packet + // TransmitAbort (); } else @@ -345,38 +336,33 @@ CsmaNetDevice::TransmitStart () m_backoff.IncrNumRetries (); Time backoffTime = m_backoff.GetBackoffTime (); - NS_LOG_LOGIC ("Channel busy, backing off for " << - backoffTime.GetSeconds () << " sec"); + NS_LOG_LOGIC ("Channel busy, backing off for " << backoffTime.GetSeconds () << " sec"); - Simulator::Schedule (backoffTime, &CsmaNetDevice::TransmitStart, - this); + Simulator::Schedule (backoffTime, &CsmaNetDevice::TransmitStart, this); } } else { -// -// The channel is free, transmit the packet -// + // + // The channel is free, transmit the packet + // m_txMachineState = BUSY; Time tEvent = Seconds (m_bps.CalculateTxTime (m_currentPkt->GetSize ())); - NS_LOG_LOGIC ("Schedule TransmitCompleteEvent in " << - tEvent.GetSeconds () << "sec"); + NS_LOG_LOGIC ("Schedule TransmitCompleteEvent in " << tEvent.GetSeconds () << "sec"); - Simulator::Schedule (tEvent, &CsmaNetDevice::TransmitCompleteEvent, - this); + Simulator::Schedule (tEvent, &CsmaNetDevice::TransmitCompleteEvent, this); if (m_channel->TransmitStart (m_currentPkt, m_deviceId) == false) { - NS_LOG_WARN ("Channel transmit start did not work at " << - tEvent.GetSeconds () << "sec"); + NS_LOG_WARN ("Channel transmit start did not work at " << tEvent.GetSeconds () << "sec"); m_txMachineState = READY; } else { -// -// Transmission succeeded, reset the backoff time parameters. -// + // + // Transmission succeeded, reset the backoff time parameters. + // m_backoff.ResetBackoffTime (); } } @@ -390,17 +376,15 @@ CsmaNetDevice::TransmitAbort (void) NS_LOG_LOGIC ("Pkt UID is " << m_currentPkt->GetUid () << ")"); -// -// Since we were transmitting a packet, that packet had better be on the -// transmit queue. -// + // + // Since we were transmitting a packet, that packet had better be on the transmit queue. + // m_currentPkt = m_queue->Dequeue (); - NS_ASSERT_MSG (m_currentPkt != 0, "No Packet on queue during" - "CsmaNetDevice::TransmitAbort()"); + NS_ASSERT_MSG (m_currentPkt != 0, "No Packet on queue during CsmaNetDevice::TransmitAbort()"); -// -// The last one failed. Let's try to transmit the next one (if there) -// + // + // The last one failed. Let's try to transmit the next one (if there) + // m_backoff.ResetBackoffTime (); m_txMachineState = READY; TransmitStart (); @@ -411,12 +395,12 @@ CsmaNetDevice::TransmitCompleteEvent (void) { NS_LOG_FUNCTION_NOARGS (); -// -// This function is called to finish the process of transmitting a packet. -// We need to tell the channel that we've stopped wiggling the wire and -// schedule an event that will be executed when it's time to re-enable -// the transmitter after the interframe gap. -// + // + // This function is called to finish the process of transmitting a packet. + // We need to tell the channel that we've stopped wiggling the wire and + // schedule an event that will be executed when it's time to re-enable + // the transmitter after the interframe gap. + // NS_ASSERT_MSG (m_txMachineState == BUSY, "Must be BUSY if transmitting"); NS_ASSERT (m_channel->GetState () == TRANSMITTING); m_txMachineState = GAP; @@ -424,11 +408,9 @@ CsmaNetDevice::TransmitCompleteEvent (void) NS_LOG_LOGIC ("Pkt UID is " << m_currentPkt->GetUid () << ")"); m_channel->TransmitEnd (); - NS_LOG_LOGIC ("Schedule TransmitReadyEvent in " - << m_tInterframeGap.GetSeconds () << "sec"); + NS_LOG_LOGIC ("Schedule TransmitReadyEvent in " << m_tInterframeGap.GetSeconds () << "sec"); - Simulator::Schedule (m_tInterframeGap, &CsmaNetDevice::TransmitReadyEvent, - this); + Simulator::Schedule (m_tInterframeGap, &CsmaNetDevice::TransmitReadyEvent, this); } void @@ -436,17 +418,17 @@ CsmaNetDevice::TransmitReadyEvent (void) { NS_LOG_FUNCTION_NOARGS (); -// -// This function is called to enable the transmitter after the interframe -// gap has passed. If there are pending transmissions, we use this opportunity -// to start the next transmit. -// + // + // This function is called to enable the transmitter after the interframe + // gap has passed. If there are pending transmissions, we use this opportunity + // to start the next transmit. + // NS_ASSERT_MSG (m_txMachineState == GAP, "Must be in interframe gap"); m_txMachineState = READY; -// -// Get the next packet from the queue for transmitting -// + // + // Get the next packet from the queue for transmitting + // if (m_queue->IsEmpty ()) { return; @@ -454,8 +436,7 @@ CsmaNetDevice::TransmitReadyEvent (void) else { m_currentPkt = m_queue->Dequeue (); - NS_ASSERT_MSG (m_currentPkt != 0, "CsmaNetDevice::TransmitReadyEvent():" - " IsEmpty false but no Packet on queue?"); + NS_ASSERT_MSG (m_currentPkt != 0, "CsmaNetDevice::TransmitReadyEvent(): IsEmpty false but no Packet on queue?"); TransmitStart (); } } @@ -469,19 +450,19 @@ CsmaNetDevice::Attach (Ptr ch) m_deviceId = m_channel->Attach (this); -// -// The channel provides us with the transmitter data rate. -// + // + // The channel provides us with the transmitter data rate. + // m_bps = m_channel->GetDataRate (); -// -// We use the Ethernet interframe gap of 96 bit times. -// + // + // We use the Ethernet interframe gap of 96 bit times. + // m_tInterframeGap = Seconds (m_bps.CalculateTxTime (96/8)); -// -// This device is up whenever a channel is attached to it. -// + // + // This device is up whenever a channel is attached to it. + // NotifyLinkUp (); return true; } @@ -500,25 +481,25 @@ CsmaNetDevice::SetReceiveErrorModel (Ptr em) m_receiveErrorModel = em; } -void + void CsmaNetDevice::Receive (Ptr packet, Ptr senderDevice) { NS_LOG_FUNCTION (packet << senderDevice); NS_LOG_LOGIC ("UID is " << packet->GetUid ()); -// -// We never forward up packets that we sent. Real devices don't do this since -// their receivers are disabled during send, so we don't. Drop the packet -// silently (no tracing) since it would really never get here in a real device. -// + // + // We never forward up packets that we sent. Real devices don't do this since + // their receivers are disabled during send, so we don't. Drop the packet + // silently (no tracing) since it would really never get here in a real device. + // if (senderDevice == this) { return; } -// -// Only receive if the send side of net device is enabled -// + // + // Only receive if the send side of net device is enabled + // if (IsReceiveEnabled () == false) { m_dropTrace (packet); @@ -530,17 +511,16 @@ CsmaNetDevice::Receive (Ptr packet, Ptr senderDevice) m_rxTrace (packet); if (!m_promiscRxCallback.IsNull ()) { - m_promiscRxCallback (this, packet, 0, GetBroadcast (), - GetAddress (), PACKET_HOST); + m_promiscRxCallback (this, packet, 0, GetBroadcast (), GetAddress (), PACKET_HOST); } m_rxCallback (this, packet, 0, GetBroadcast ()); return; } -// -// Trace sinks will expect complete packets, not packets without some of the -// headers. -// + // + // Trace sinks will expect complete packets, not packets without some of the + // headers. + // Ptr originalPacket = packet->Copy (); EthernetTrailer trailer; @@ -553,14 +533,14 @@ CsmaNetDevice::Receive (Ptr packet, Ptr senderDevice) NS_LOG_LOGIC ("Pkt source is " << header.GetSource ()); NS_LOG_LOGIC ("Pkt destination is " << header.GetDestination ()); -// -// An IP host group address is mapped to an Ethernet multicast address -// by placing the low-order 23-bits of the IP address into the low-order -// 23 bits of the Ethernet multicast address 01-00-5E-00-00-00 (hex). -// -// We are going to receive all packets destined to any multicast address, -// which means clearing the low-order 23 bits the header destination -// + // + // An IP host group address is mapped to an Ethernet multicast address + // by placing the low-order 23-bits of the IP address into the low-order + // 23 bits of the Ethernet multicast address 01-00-5E-00-00-00 (hex). + // + // We are going to receive all packets destined to any multicast address, + // which means clearing the low-order 23 bits the header destination + // Mac48Address mcDest; uint8_t mcBuf[6]; @@ -581,10 +561,9 @@ CsmaNetDevice::Receive (Ptr packet, Ptr senderDevice) } else { -// -// variable must be initialized to avoid a compiler warning in the -// RAW case that breaks the optimized build. -// + // + // variable must be initialized to avoid a compiler warning in the RAW case that breaks the optimized build. + // uint16_t protocol = 0; switch (m_encapMode) @@ -629,8 +608,7 @@ CsmaNetDevice::Receive (Ptr packet, Ptr senderDevice) if (!m_promiscRxCallback.IsNull ()) { - m_promiscRxCallback (this, packet, protocol, header.GetSource (), - header.GetDestination (), packetType); + m_promiscRxCallback (this, packet, protocol, header.GetSource (), header.GetDestination (), packetType); } if (packetType != PACKET_OTHERHOST) @@ -762,49 +740,55 @@ CsmaNetDevice::GetMulticast (void) const CsmaNetDevice::MakeMulticastAddress (Ipv4Address multicastGroup) const { NS_LOG_FUNCTION (multicastGroup); -// -// First, get the generic multicast address. -// + // + // First, get the generic multicast address. + // Address hardwareDestination = GetMulticast (); NS_LOG_LOGIC ("Device multicast address: " << hardwareDestination); -// -// It's our address, and we know we're playing with an EUI-48 address here -// primarily since we know that by construction, but also since the parameter -// is an Ipv4Address. -// + + // + // It's our address, and we know we're playing with an EUI-48 address here + // primarily since we know that by construction, but also since the parameter + // is an Ipv4Address. + // Mac48Address etherAddr = Mac48Address::ConvertFrom (hardwareDestination); -// -// We now have the multicast address in an abstract 48-bit container. We -// need to pull it out so we can play with it. When we're done, we have the -// high order bits in etherBuffer[0], etc. -// + + // + // We now have the multicast address in an abstract 48-bit container. We + // need to pull it out so we can play with it. When we're done, we have the + // high order bits in etherBuffer[0], etc. + // uint8_t etherBuffer[6]; etherAddr.CopyTo (etherBuffer); -// -// Now we need to pull the raw bits out of the Ipv4 destination address. -// + + // + // Now we need to pull the raw bits out of the Ipv4 destination address. + // uint8_t ipBuffer[4]; multicastGroup.Serialize (ipBuffer); -// -// RFC 1112 says that an Ipv4 host group address is mapped to an EUI-48 -// multicast address by placing the low-order 23-bits of the IP address into -// the low-order 23 bits of the Ethernet multicast address -// 01-00-5E-00-00-00 (hex). -// + + // + // RFC 1112 says that an Ipv4 host group address is mapped to an EUI-48 + // multicast address by placing the low-order 23-bits of the IP address into + // the low-order 23 bits of the Ethernet multicast address + // 01-00-5E-00-00-00 (hex). + // etherBuffer[3] |= ipBuffer[1] & 0x7f; etherBuffer[4] = ipBuffer[2]; etherBuffer[5] = ipBuffer[3]; -// -// Now, etherBuffer has the desired ethernet multicast address. We have to -// suck these bits back into the Mac48Address, -// + + // + // Now, etherBuffer has the desired ethernet multicast address. We have to + // suck these bits back into the Mac48Address, + // etherAddr.CopyFrom (etherBuffer); -// -// Implicit conversion (operator Address ()) is defined for Mac48Address, so -// use it by just returning the EUI-48 address which is automagically converted -// to an Address. -// + + // + // Implicit conversion (operator Address ()) is defined for Mac48Address, so + // use it by just returning the EUI-48 address which is automagically converted + // to an Address. + // NS_LOG_LOGIC ("multicast address is " << etherAddr); return etherAddr; @@ -817,20 +801,15 @@ CsmaNetDevice::IsPointToPoint (void) const return false; } -bool -CsmaNetDevice::Send (Ptr packet, - const Address& dest, - uint16_t protocolNumber) + bool +CsmaNetDevice::Send (Ptr packet,const Address& dest, uint16_t protocolNumber) { NS_LOG_FUNCTION (packet << dest << protocolNumber); return SendFrom (packet, m_address, dest, protocolNumber); } -bool -CsmaNetDevice::SendFrom (Ptr packet, - const Address& src, - const Address& dest, - uint16_t protocolNumber) + bool +CsmaNetDevice::SendFrom (Ptr packet, const Address& src, const Address& dest, uint16_t protocolNumber) { NS_LOG_FUNCTION (packet << src << dest << protocolNumber); NS_LOG_LOGIC ("p=" << packet); @@ -838,9 +817,9 @@ CsmaNetDevice::SendFrom (Ptr packet, NS_ASSERT (IsLinkUp ()); -// -// Only transmit if send side of net device is enabled -// + // + // Only transmit if send side of net device is enabled + // if (IsSendEnabled () == false) { return false; @@ -850,23 +829,24 @@ CsmaNetDevice::SendFrom (Ptr packet, Mac48Address source = Mac48Address::ConvertFrom (src); AddHeader (packet, source, destination, protocolNumber); -// -// Place the packet to be sent on the send queue -// + // + // Place the packet to be sent on the send queue + // if (m_queue->Enqueue(packet) == false) { return false; } -// -// If the device is idle, we need to start a transmission. Otherwise, -// the transmission will be started when the current packet finished -// transmission (see TransmitCompleteEvent) -// + + // + // If the device is idle, we need to start a transmission. Otherwise, + // the transmission will be started when the current packet finished + // transmission (see TransmitCompleteEvent) + // if (m_txMachineState == READY) { -// -// The next packet to be transmitted goes in m_currentPkt -// + // + // The next packet to be transmitted goes in m_currentPkt + // m_currentPkt = m_queue->Dequeue (); if (m_currentPkt != 0) { @@ -931,14 +911,14 @@ CsmaNetDevice::SetReceiveCallback (NetDevice::ReceiveCallback cb) m_rxCallback = cb; } -void + void CsmaNetDevice::SetPromiscReceiveCallback (NetDevice::PromiscReceiveCallback cb) { NS_LOG_FUNCTION (&cb); m_promiscRxCallback = cb; } -bool + bool CsmaNetDevice::SupportsPromiscuous () const { NS_LOG_FUNCTION_NOARGS (); diff --git a/src/devices/csma/csma-net-device.h b/src/devices/csma/csma-net-device.h index f84b2eb9b..d05bc2342 100644 --- a/src/devices/csma/csma-net-device.h +++ b/src/devices/csma/csma-net-device.h @@ -103,7 +103,7 @@ public: * Set the backoff parameters used to determine the wait to retry * transmitting a packet when the channel is busy. * - * @see Attach () + * \see Attach () * \param slotTime Length of a packet slot (or average packet time) * \param minSlots Minimum number of slots to wait * \param maxSlots Maximum number of slots to wait @@ -118,8 +118,8 @@ public: * * The function Attach is used to add a CsmaNetDevice to a CsmaChannel. * - * @see SetDataRate () - * @see SetInterframeGap () + * \see SetDataRate () + * \see SetInterframeGap () * \param ch a pointer to the channel to which this object is being attached. */ bool Attach (Ptr ch); @@ -131,8 +131,8 @@ public: * level topology objects to implement a particular queueing method such as * DropTail or RED. * - * @see Queue - * @see DropTailQueue + * \see Queue + * \see DropTailQueue * \param queue a Ptr to the queue for being assigned to the device. */ void SetQueue (Ptr queue); @@ -143,8 +143,8 @@ public: * The CsmaNetDevice may optionally include an ErrorModel in * the packet receive chain to simulate data errors in during transmission. * - * @see ErrorModel - * @param em a pointer to the ErrorModel + * \see ErrorModel + * \param em a pointer to the ErrorModel */ void SetReceiveErrorModel (Ptr em); @@ -156,7 +156,7 @@ public: * used by the channel to indicate that the last bit of a packet has * arrived at the device. * - * @see CsmaChannel + * \see CsmaChannel * \param p a reference to the received packet * \param sender the CsmaNetDevice that transmitted the packet in the first place */ @@ -216,7 +216,7 @@ public: virtual Address GetMulticast (void) const; /** - * @brief Make and return a MAC multicast address using the provided + * \brief Make and return a MAC multicast address using the provided * multicast group * * RFC 1112 says that an Ipv4 host group address is mapped to an Ethernet @@ -228,14 +228,14 @@ public: * to an EUI-48-based CSMA device. This MAC address is encapsulated in an * abstract Address to avoid dependencies on the exact address format. * - * @param multicastGroup The IP address for the multicast group destination + * \param multicastGroup The IP address for the multicast group destination * of the packet. - * @return The MAC multicast Address used to send packets to the provided + * \return The MAC multicast Address used to send packets to the provided * multicast group. * - * @see Ipv4Address - * @see Mac48Address - * @see Address + * \see Ipv4Address + * \see Mac48Address + * \see Address */ virtual Address MakeMulticastAddress (Ipv4Address multicastGroup) const; @@ -368,8 +368,8 @@ private: * If the channel is found to be BUSY, this method reschedules itself for * execution at a later time (within the backoff period). * - * @see CsmaChannel::TransmitStart () - * @see TransmitCompleteEvent () + * \see CsmaChannel::TransmitStart () + * \see TransmitCompleteEvent () */ void TransmitStart (); @@ -386,8 +386,8 @@ private: * method, the net device also schedules the TransmitReadyEvent at which * time the transmitter becomes ready to send the next packet. * - * @see CsmaChannel::TransmitEnd () - * @see TransmitReadyEvent () + * \see CsmaChannel::TransmitEnd () + * \see TransmitReadyEvent () */ void TransmitCompleteEvent (void); @@ -403,7 +403,7 @@ private: * If a packet is in the queue, it is extracted for the queue as the * next packet to be transmitted by the net device. * - * @see TransmitStart () + * \see TransmitStart () */ void TransmitReadyEvent (void); @@ -451,7 +451,7 @@ private: /** * The state of the Net Device transmit state machine. - * @see TxMachineState + * \see TxMachineState */ TxMachineState m_txMachineState; @@ -465,14 +465,14 @@ private: /** * The data rate that the Net Device uses to simulate packet transmission * timing. - * @see class DataRate + * \see class DataRate */ DataRate m_bps; /** * The interframe gap that the Net Device uses insert time between packet * transmission - * @see class Time + * \see class Time */ Time m_tInterframeGap; @@ -493,7 +493,7 @@ private: /** * The CsmaChannel to which this CsmaNetDevice has been * attached. - * @see class CsmaChannel + * \see class CsmaChannel */ Ptr m_channel; @@ -501,8 +501,8 @@ private: * The Queue which this CsmaNetDevice uses as a packet source. * Management of this Queue has been delegated to the CsmaNetDevice * and it has the responsibility for deletion. - * @see class Queue - * @see class DropTailQueue + * \see class Queue + * \see class DropTailQueue */ Ptr m_queue; @@ -515,7 +515,7 @@ private: * The trace source for the packet reception events that the device can * fire. * - * @see class CallBackTraceSource + * \see class CallBackTraceSource */ TracedCallback > m_rxTrace; @@ -523,7 +523,7 @@ private: * The trace source for the packet drop events that the device can * fire. * - * @see class CallBackTraceSource + * \see class CallBackTraceSource */ TracedCallback > m_dropTrace; From b6a0e35db1b1de2899ebc87594d55645fd83733e Mon Sep 17 00:00:00 2001 From: Tom Henderson Date: Mon, 4 Aug 2008 14:43:53 -0700 Subject: [PATCH 218/495] Add CHANGES.html --- CHANGES.html | 164 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 164 insertions(+) create mode 100644 CHANGES.html diff --git a/CHANGES.html b/CHANGES.html new file mode 100644 index 000000000..32362296c --- /dev/null +++ b/CHANGES.html @@ -0,0 +1,164 @@ + + + + + ns-3 Change Log + + + +

+ns-3: API and model change history

+ +

+ns-3 is an evolving system and there will be API or behavioral changes +from time to time. Users who try to use scripts or models across +versions of ns-3 may encounter problems at compile time, run time, or +may see the simulation output change.

+

+We have adopted the development policy that we are going to try to ease +the impact of these changes on users by documenting these changes in a +single place (this file), and not by providing a temporary or permanent +backward-compatibility software layer.

+

+The goal is that users who encounter a problem when trying to use older +code with newer code should be able to consult this file to find +guidance as to how to fix the problem. For instance, if a method name +or signature has changed, it should be stated what the new replacement +name is.

+

+Note that users who upgrade the simulator across versions, or who work +directly out of the development tree, may find that simulation output +changes even when the compilation doesn't break, such as when a +simulator default value is changed. Therefore, it is good practice for +_anyone_ using code across multiple ns-3 releases to consult this file, +as well as the RELEASE_NOTES, to understand what has changed over time. +

+

+This file is a best-effort approach to solving this issue; we will do +our best but can guarantee that there will be things that fall through +the cracks, unfortunately. If you, as a user, can suggest improvements +to this file based on your experience, please contribute a patch or drop +us a note on ns-developers mailing list.

+ +
+

changes from ns-3.1 to ns-3.2

+

new API in existing classes:

+ +
    +
  • 01-08-2008; changeset +a18520551cdf
  • +
      +
    • class ArpCache has two new attributes: MaxRetries +and a Drop trace. It also has some new public methods but these are +mostly for internal use. +
    + +
+ +

changes to existing API:

+ +
    +
  • 21-07-2008; changeset +99698bc858e8
  • +
      +
    • class NetDevice has added a pure virtual method that +must be implemented by all subclasses: +
      +virtual void SetPromiscReceiveCallback (PromiscReceiveCallback cb) = 0;
      +
      +All NetDevices must support this method, and must call this callback +when processing packets in the receive direction (the appropriate place +to call this is device-dependent). An approach to stub this out +temporarily, if you do not care about immediately enabling this +functionality, would be to add this to your device: +
      +void
      +ExampleNetDevice::SetPromiscReceiveCallback
      +(NetDevice::PromiscReceiveCallback cb)
      +{ 
      +  NS_ASSERT_MSG (false, "No implementation yet for
      +SetPromiscReceiveCallback");
      +}
      +
      +To implement this properly, consult the CsmaNetDevice for examples of +when the m_promiscRxCallback is called. +
    • +
    + +
+ +
    +
  • 03-07-2008; changeset +d5f8e5fae1c6
  • +
      +
    • +Miscellaneous cleanup of Udp Helper API, to fix bug 234 +
      +class UdpEchoServerHelper
      +{
      +public:
      +- UdpEchoServerHelper ();
      +- void SetPort (uint16_t port); 
      ++ UdpEchoServerHelper (uint16_t port);
      ++ 
      ++ void SetAttribute (std::string name, const AttributeValue &value);
      +ApplicationContainer Install (NodeContainer c);
      +
      +class UdpEchoClientHelper
      +{
      +public:
      +- UdpEchoClientHelper ();
      ++ UdpEchoClientHelper (Ipv4Address ip, uint16_t port);
      +- void SetRemote (Ipv4Address ip, uint16_t port);
      +- void SetAppAttribute (std::string name, const AttributeValue &value);
      ++ void SetAttribute (std::string name, const AttributeValue &value);
      +ApplicationContainer Install (NodeContainer c);
      +
      +
    • +
    + +
+ +
    +
  • 03-07-2008; changeset +3cdd9d60f7c7
  • +
      +
    • +Rename all instances method names using "Set..Parameter" to "Set..Attribute" +(bug 232) +
    • +
    • How to fix your code: Any use of helper API that was using a method +"Set...Parameter()" should be changed to read "Set...Attribute()". e.g. +
      +- csma.SetChannelParameter ("DataRate", DataRateValue (5000000));
      +- csma.SetChannelParameter ("Delay", TimeValue (MilliSeconds (2)));
      ++ csma.SetChannelAttribute ("DataRate", DataRateValue (5000000));
      ++ csma.SetChannelAttribute ("Delay", TimeValue (MilliSeconds (2)));
      +
      +
    • +
    + +
+ +

changed behavior:

+
    +
  • 28-07-2008; changeset +6f68f1044df1 +
      +
    • +OLSR: HELLO messages hold time changed to 3*hello +interval from hello interval. This is an important bug fix as +hold time == refresh time was never intentional, as it leads to +instability in neighbor detection. +
    +
  • +
+ + + + From 6c7bdf5845d35041d86f46bdd63dc869e365d6e0 Mon Sep 17 00:00:00 2001 From: Craig Dowell Date: Mon, 4 Aug 2008 17:32:32 -0700 Subject: [PATCH 219/495] sort out various MTU options --- examples/udp-echo.cc | 1 + src/devices/csma/csma-net-device.cc | 164 ++++++++++++++++++++++++---- src/devices/csma/csma-net-device.h | 141 ++++++++++++++++++++++-- 3 files changed, 276 insertions(+), 30 deletions(-) diff --git a/examples/udp-echo.cc b/examples/udp-echo.cc index 362c398ab..d9d2e8222 100644 --- a/examples/udp-echo.cc +++ b/examples/udp-echo.cc @@ -89,6 +89,7 @@ main (int argc, char *argv[]) CsmaHelper csma; csma.SetChannelAttribute ("DataRate", DataRateValue (DataRate(5000000))); csma.SetChannelAttribute ("Delay", TimeValue (MilliSeconds (2))); + csma.SetDeviceAttribute ("MTU", UintegerValue (1400)); NetDeviceContainer d = csma.Install (n); Ipv4AddressHelper ipv4; diff --git a/src/devices/csma/csma-net-device.cc b/src/devices/csma/csma-net-device.cc index 10822a015..f0a739631 100644 --- a/src/devices/csma/csma-net-device.cc +++ b/src/devices/csma/csma-net-device.cc @@ -52,18 +52,20 @@ CsmaNetDevice::GetTypeId (void) MakeMac48AddressChecker ()) .AddAttribute ("PayloadLength", "The max PHY-level payload length of packets sent over this device.", - UintegerValue (DEFAULT_FRAME_LENGTH), - MakeUintegerAccessor (&CsmaNetDevice::m_maxPayloadLength), + UintegerValue (DEFAULT_PAYLOAD_LENGTH), + MakeUintegerAccessor (&CsmaNetDevice::SetMaxPayloadLength, + &CsmaNetDevice::GetMaxPayloadLength), MakeUintegerChecker ()) .AddAttribute ("MTU", "The MAC-level MTU (client payload) of packets sent over this device.", UintegerValue (DEFAULT_MTU), - MakeUintegerAccessor (&CsmaNetDevice::m_mtu), + MakeUintegerAccessor (&CsmaNetDevice::SetMacMtu, + &CsmaNetDevice::GetMacMtu), MakeUintegerChecker ()) .AddAttribute ("EncapsulationMode", "The link-layer encapsulation type to use.", EnumValue (LLC), - MakeEnumAccessor (&CsmaNetDevice::m_encapMode), + MakeEnumAccessor (&CsmaNetDevice::SetEncapsulationMode), MakeEnumChecker (ETHERNET_V1, "EthernetV1", IP_ARP, "IpArp", RAW, "Raw", @@ -106,6 +108,14 @@ CsmaNetDevice::CsmaNetDevice () m_txMachineState = READY; m_tInterframeGap = Seconds (0); m_channel = 0; + + m_encapMode = LLC; + m_maxPayloadLength = DEFAULT_PAYLOAD_LENGTH; + m_mtu = MacMtuFromPayload (m_maxPayloadLength); + + NS_LOG_LOGIC ("m_encapMode = " << m_encapMode); + NS_LOG_LOGIC ("m_maxPayloadLength = " << m_maxPayloadLength); + NS_LOG_LOGIC ("m_mtu = " << m_mtu); } CsmaNetDevice::~CsmaNetDevice() @@ -123,6 +133,133 @@ CsmaNetDevice::DoDispose () NetDevice::DoDispose (); } + uint16_t +CsmaNetDevice::MacMtuFromPayload (uint16_t payloadLength) +{ + NS_LOG_FUNCTION (payloadLength); + + switch (m_encapMode) + { + case RAW: + case IP_ARP: + case ETHERNET_V1: + return payloadLength; + case LLC: + { + LlcSnapHeader llc; + + NS_ASSERT_MSG (payloadLength >= llc.GetSerializedSize (), "CsmaNetDevice::MacMtuFromPayload(): " + "Given payload too small to support LLC mode"); + return payloadLength - llc.GetSerializedSize (); + } + } + + NS_ASSERT_MSG (false, "CsmaNetDevice::MacMtuFromPayload(): Unexpected encapsulation mode"); + return 0; +} + + uint16_t +CsmaNetDevice::PayloadFromMacMtu (uint16_t mtu) +{ + NS_LOG_FUNCTION (mtu); + + switch (m_encapMode) + { + case RAW: + case IP_ARP: + case ETHERNET_V1: + return mtu; + case LLC: + { + LlcSnapHeader llc; + return mtu + llc.GetSerializedSize (); + } + } + + NS_ASSERT_MSG (false, "CsmaNetDevice::PayloadFromMacMtu(): Unexpected encapsulation mode"); + return 0; +} + + void +CsmaNetDevice::SetEncapsulationMode (enum EncapsulationMode mode) +{ + NS_LOG_FUNCTION (mode); + + m_encapMode = mode; + m_mtu = MacMtuFromPayload (m_maxPayloadLength); + + NS_LOG_LOGIC ("m_encapMode = " << m_encapMode); + NS_LOG_LOGIC ("m_maxPayloadLength = " << m_maxPayloadLength); + NS_LOG_LOGIC ("m_mtu = " << m_mtu); +} + + CsmaNetDevice::EncapsulationMode +CsmaNetDevice::GetEncapsulationMode (void) +{ + NS_LOG_FUNCTION_NOARGS (); + return m_encapMode; +} + + void +CsmaNetDevice::SetMacMtu (uint16_t mtu) +{ + NS_LOG_FUNCTION (mtu); + + m_maxPayloadLength = PayloadFromMacMtu (mtu); + m_mtu = mtu; + + NS_LOG_LOGIC ("m_encapMode = " << m_encapMode); + NS_LOG_LOGIC ("m_maxPayloadLength = " << m_maxPayloadLength); + NS_LOG_LOGIC ("m_mtu = " << m_mtu); +} + + uint16_t +CsmaNetDevice::GetMacMtu (void) const +{ + NS_LOG_FUNCTION_NOARGS (); + return m_mtu; +} + +// +// The SetMtu method in the net device base class always refers to the MAC-level MTU by definition. +// + bool +CsmaNetDevice::SetMtu (const uint16_t mtu) +{ + NS_LOG_FUNCTION (mtu); + SetMacMtu (mtu); + return true; +} + +// +// The GetMtu method in the net device base class always refers to the MAC-level MTU by definition. +// + uint16_t +CsmaNetDevice::GetMtu (void) const +{ + NS_LOG_FUNCTION_NOARGS (); + return GetMacMtu (); +} + + void +CsmaNetDevice::SetMaxPayloadLength (uint16_t maxPayloadLength) +{ + NS_LOG_FUNCTION (maxPayloadLength); + + m_maxPayloadLength = maxPayloadLength; + m_mtu = MacMtuFromPayload (maxPayloadLength); + + NS_LOG_LOGIC ("m_encapMode = " << m_encapMode); + NS_LOG_LOGIC ("m_maxPayloadLength = " << m_maxPayloadLength); + NS_LOG_LOGIC ("m_mtu = " << m_mtu); +} + + uint16_t +CsmaNetDevice::GetMaxPayloadLength (void) const +{ + return m_maxPayloadLength; +} + void CsmaNetDevice::SetAddress (Mac48Address self) { @@ -193,6 +330,7 @@ CsmaNetDevice::AddHeader (Ptr p, Mac48Address source, Mac48Address de EthernetTrailer trailer; NS_LOG_LOGIC ("p->GetSize () = " << p->GetSize ()); + NS_LOG_LOGIC ("m_encapMode = " << m_encapMode); NS_LOG_LOGIC ("m_mtu = " << m_mtu); NS_LOG_LOGIC ("m_maxPayloadLength = " << m_maxPayloadLength); @@ -238,8 +376,7 @@ CsmaNetDevice::AddHeader (Ptr p, Mac48Address source, Mac48Address de } break; case RAW: - NS_LOG_LOGIC ("Encapsulating packet as RAW"); - NS_ASSERT (false); + NS_ASSERT_MSG (false, "CsmaNetDevice::AddHeader(): RAW packet encapsulation not supported"); break; } @@ -679,21 +816,6 @@ CsmaNetDevice::GetAddress (void) const return m_address; } - bool -CsmaNetDevice::SetMtu (const uint16_t mtu) -{ - NS_LOG_FUNCTION (mtu); - m_mtu = mtu; - return true; -} - - uint16_t -CsmaNetDevice::GetMtu (void) const -{ - NS_LOG_FUNCTION_NOARGS (); - return m_mtu; -} - bool CsmaNetDevice::IsLinkUp (void) const { diff --git a/src/devices/csma/csma-net-device.h b/src/devices/csma/csma-net-device.h index d05bc2342..4e59d0ae3 100644 --- a/src/devices/csma/csma-net-device.h +++ b/src/devices/csma/csma-net-device.h @@ -65,11 +65,12 @@ class CsmaNetDevice : public NetDevice { public: static TypeId GetTypeId (void); + /** * Enumeration of the types of packets supported in the class. * */ - enum CsmaEncapsulationMode { + enum EncapsulationMode { ETHERNET_V1, /**< Version one ethernet packet, length field */ IP_ARP, /**< Ethernet packet encapsulates IP/ARP packet */ RAW, /**< Packet that contains no headers */ @@ -197,17 +198,108 @@ public: */ void SetAddress (Mac48Address addr); -// -// The following methods are inherited from NetDevice base class. -// + /** + * Set The max PHY-level payload length of packets sent over this device. + * + * Okay, that was easy to say, but the details are a bit thorny. We have a MAC-level that is the payload that higher + * level protocols see. We have a PHY-level MTU which is the maximum number of bytes we can send over the link + * (cf. 1500 bytes for Ethernet). The value that determines the relationship between these two values is the link + * encapsulation mode. The link encapsulation defines the number of bytes of overhead that are required for the particular + * MAC protocol used. For example, if the LLC/SNAP encapsulation is used, eight bytes of LLC/SNAP header are consumed and + * therefore the MAC-level MTU must be set and reported as eight bytes less than the PHY-level MTU (which we call the + * payload length to try and avoid confusion). + * + * So, what do we do since there must be three values which must always be consistent in the driver? Which values to we + * allow to be changed and how do we ensure the other two are consistent? We want to actually enable a user to change + * these two payload lengths in flexible ways, but we want the results (even at intermediate stages) to be consistent. + * We certainly don't want to require that users must understand the various requirements of an enapsulation mode in order + * to set these variables. + * + * Consider the following situation: A user wants to set the physical layer MTU to 1400 bytes instead of 1500. This + * user shouldn't have to concern herself that the current encapuslation mode is LLC and this will consume eight bytes. + * She should not have to also set the MAC MTU to 1392 bytes, and she should certainly not have to do this before setting + * the PHY MTU. + * + * A user who is interested in setting the MAC-level MTU to 1400 bytes should not be forced to understand that in certain + * cases the PHY-level MTU must be set to eight bytes more than what he wants in certain cases and zero bytes in others. + * + * Now, consider a user who is only interested in changing the encapsulation mode from LLC/SNAP to ETHERNET_V1. This + * is going to change the relationship between the MAC MTU and the PHY MTU. We've may have to come up with a new value + * for at least one of the MTUs? Which one? + * + * We could play games trying to figure out what the user wants to do, but that is typically a bad plan. So we're going + * to just define a flexible behavior. Here it is: + * + * - If the user is changing the encapsulation mode, the PHY MTU will remain fixed and the MAC MTU will change, if required, + * to make the three values consistent; + * + * - If the user is changing the MAC MTU, she is interested in getting that part of the system set, so the PHY MTU + * will be changed to make the three values consistent; + * + * - If the user is changing the PHY MTU, he is interested in getting that part of the system set, so the MAC MTU + * will be changed to make the three values consistent. + * + * So, if a user calls SetMaxPayloadLength, we assume that the PHY-level MTU is the interesting thing for that user and + * we just adjust the MAC-level MTU to "the correct value" based on the current encapsulation mode. If a user calls + * SetMacMtu, we assume that the MAC-level MTU is the interesting property for that user, and we adjust the PHY-level MTU + * to "the correct value" for the current encapsulation mode. If a user calls SetEncapsulationMode, then we take the + * MAC-level MTU as the free variable and set its value to match the current PHY-level MTU. + * + * \param mayPayloadLength The max PHY-level payload length of packets sent over this device. + */ + void SetMaxPayloadLength (uint16_t maxPayloadLength); + + /** + * Get The max PHY-level payload length of packets sent over this device. + * + * \returns The max PHY-level payload length of packets sent over this device. + */ + uint16_t GetMaxPayloadLength (void) const; + + /** + * Set The MAC-level MTU (client payload) of packets sent over this device. + * + * \param mtu The MAC-level MTU (client payload) of packets sent over this device. + * + * \see SetMaxPayloadLength + */ + void SetMacMtu (uint16_t mtu); + + /** + * Get The MAC-level MTU (client payload) of packets sent over this device. + * + * \returns The MAC-level MTU (client payload) of packets sent over this device. + */ + uint16_t GetMacMtu (void) const; + + + /** + * Set the encapsulation mode of this device. + * + * \param mode The encapsulation mode of this device. + * + * \see SetMaxPayloadLength + */ + void SetEncapsulationMode (CsmaNetDevice::EncapsulationMode mode); + + /** + * Get the encapsulation mode of this device. + * + * \returns The encapsulation mode of this device. + */ + CsmaNetDevice::EncapsulationMode GetEncapsulationMode (void); + + // + // The following methods are inherited from NetDevice base class. + // virtual void SetName (const std::string name); virtual std::string GetName (void) const; virtual void SetIfIndex (const uint32_t index); virtual uint32_t GetIfIndex (void) const; virtual Ptr GetChannel (void) const; - virtual Address GetAddress (void) const; virtual bool SetMtu (const uint16_t mtu); virtual uint16_t GetMtu (void) const; + virtual Address GetAddress (void) const; virtual bool IsLinkUp (void) const; virtual void SetLinkChangeCallback (Callback callback); virtual bool IsBroadcast (void) const; @@ -333,9 +425,6 @@ protected: private: - static const uint16_t DEFAULT_FRAME_LENGTH = 1500; - static const uint16_t DEFAULT_MTU = 1492; - /** * Operator = is declared but not implemented. This disables the assigment * operator for CsmaNetDevice objects. @@ -354,6 +443,18 @@ private: */ void Init (bool sendEnable, bool receiveEnable); + /** + * Calculate the value for the MAC-level MTU that would result from + * setting the PHY-level MTU to the given value. + */ + uint16_t MacMtuFromPayload (uint16_t payloadLength); + + /** + * Calculate the value for the PHY-level MTU that would be required + * to be able to set the MAC-level MTU to the given value. + */ + uint16_t PayloadFromMacMtu (uint16_t mtu); + /** * Start Sending a Packet Down the Wire. * @@ -460,7 +561,7 @@ private: * function and that should be processed by the ProcessHeader * function. */ - CsmaEncapsulationMode m_encapMode; + EncapsulationMode m_encapMode; /** * The data rate that the Net Device uses to simulate packet transmission @@ -568,6 +669,28 @@ private: */ Callback m_linkChangeCallback; + static const uint16_t DEFAULT_PAYLOAD_LENGTH = 1500; + static const uint16_t DEFAULT_MTU = 1492; + + /** + * There are two MTU types that are used in this driver. The MAC-level + * MTU corresponds to the amount of data (payload) an upper layer can + * send across the link. The PHY-level MTU corresponds to the Type/Length + * field in the 802.3 header and corresponds to the maximum amount of data + * the underlying packet can accept. These are not the same thing. For + * example, if you choose "Llc" as your encapsulation mode, the MAC-level + * MTU will be reduced by the eight bytes with respect to the PHY-level + * MTU which are consumed by the LLC/SNAP header. + * + * This method checks the current enacpuslation mode (and any other + * relevent information) and determines if the provided payloadLength + * (PHY-level MTU) and mtu (MAC-level MTU) are consistent. + * + * \param payloadLength The proposed PHY-level MTU + * \param mtu The proposed MAC-level MTU + */ + bool CheckMtuConsistency (uint16_t payloadLength, uint16_t mtu); + /** * The MAC-level maximum transmission unit allowed to be sent or received by * this network device. This corresponds to the maximum payload the device From 13bdfdf13138e48a754b9b2e5deec5bf5c2b1e51 Mon Sep 17 00:00:00 2001 From: Craig Dowell Date: Mon, 4 Aug 2008 17:44:53 -0700 Subject: [PATCH 220/495] actually use CHANGES.html --- CHANGES.html | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/CHANGES.html b/CHANGES.html index 32362296c..dd7eb9ac3 100644 --- a/CHANGES.html +++ b/CHANGES.html @@ -60,6 +60,29 @@ mostly for internal use.

changes to existing API:

+
    +
  • 04-08-2008; changeset +cba7b2b80fe8
  • +
      +
    • +Cleanup of MTU confusion and initialization in CsmaNetDevice +
      +The MTU of the CsmaNetDevice defaulted to 65535.  This did not correspond with
      +the expected MTU found in Ethernet-like devices.  Also there was not clear 
      +documentation regarding which MTU was being set.  There are two MTU here, one
      +at the MAC level and one at the PHY level.  We split out the MTU setting to make
      +this more clear and set the default PHY level MTU to 1500 to be more like
      +Ethernet.  The encapsulation mode defaults to LLC/SNAP which then puts the
      +MAC level MTU at 1492 by default.  We allow users to now set the encapsulation
      +mode, MAC MTU and PHY MTU while keeping the three values consistent.  See the
      +Doxygen of CsmaNetDevice::SetMaxPayloadLength for a detailed description of the
      +issues and solution.
      +
      +
    • +
    + +
+