blob: febd62112cf0ed14c65aba7b268cfc0716874aba [file] [log] [blame]
Ilya Moiseenko02fb7062011-08-11 17:18:00 -07001//
2// stupid-interest-sink.cpp
3// Abstraction
4//
5// Created by Ilya Moiseenko on 10.08.11.
6// Copyright 2011 UCLA. All rights reserved.
7//
8
9#include "stupid-interest-sink.h"
Alexander Afanasyev2536e202011-08-12 14:13:10 -070010
Ilya Moiseenko02fb7062011-08-11 17:18:00 -070011#include "ns3/address.h"
12#include "ns3/address-utils.h"
13#include "ns3/log.h"
14#include "ns3/inet-socket-address.h"
15#include "ns3/node.h"
16#include "ns3/socket.h"
17#include "ns3/udp-socket.h"
18#include "ns3/simulator.h"
19#include "ns3/socket-factory.h"
20#include "ns3/packet.h"
21#include "ns3/trace-source-accessor.h"
22#include "ns3/udp-socket-factory.h"
23
24using namespace std;
25
26namespace ns3 {
27
28 NS_LOG_COMPONENT_DEFINE ("StupidInterestSink");
29 NS_OBJECT_ENSURE_REGISTERED (StupidInterestSink);
30
31 TypeId
32 StupidInterestSink::GetTypeId (void)
33 {
34 static TypeId tid = TypeId ("ns3::StupidInterestSink")
35 .SetParent<Application> ()
36 .AddConstructor<StupidInterestSink> ()
37 .AddAttribute ("Local", "The Address on which to Bind the rx socket.",
38 AddressValue (),
39 MakeAddressAccessor (&StupidInterestSink::m_local),
40 MakeAddressChecker ())
41 .AddAttribute ("Protocol", "The type id of the protocol to use for the rx socket.",
42 TypeIdValue (UdpSocketFactory::GetTypeId ()),
43 MakeTypeIdAccessor (&StupidInterestSink::m_tid),
44 MakeTypeIdChecker ())
45 .AddTraceSource ("Rx", "A packet has been received",
46 MakeTraceSourceAccessor (&StupidInterestSink::m_rxTrace))
47 ;
48 return tid;
49 }
50
51 StupidInterestSink::StupidInterestSink ()
52 {
53 NS_LOG_FUNCTION (this);
54 m_socket = 0;
55 m_totalRx = 0;
56 }
57
58 StupidInterestSink::~StupidInterestSink()
59 {
60 NS_LOG_FUNCTION (this);
61 }
62
63 uint32_t StupidInterestSink::GetTotalRx () const
64 {
65 return m_totalRx;
66 }
67
68 Ptr<Socket>
69 StupidInterestSink::GetListeningSocket (void) const
70 {
71 NS_LOG_FUNCTION (this);
72 return m_socket;
73 }
74
75 std::list<Ptr<Socket> >
76 StupidInterestSink::GetAcceptedSockets (void) const
77 {
78 NS_LOG_FUNCTION (this);
79 return m_socketList;
80 }
81
82 void StupidInterestSink::DoDispose (void)
83 {
84 NS_LOG_FUNCTION (this);
85 m_socket = 0;
86 m_socketList.clear ();
87
88 // chain up
89 Application::DoDispose ();
90 }
91
92
93 // Application Methods
94 void StupidInterestSink::StartApplication () // Called at time specified by Start
95 {
96 NS_LOG_FUNCTION (this);
97 // Create the socket if not already
98 if (!m_socket)
99 {
100 m_socket = Socket::CreateSocket (GetNode (), m_tid);
101 m_socket->Bind (m_local);
102 m_socket->Listen ();
103 m_socket->ShutdownSend ();
104 if (addressUtils::IsMulticast (m_local))
105 {
106 Ptr<UdpSocket> udpSocket = DynamicCast<UdpSocket> (m_socket);
107 if (udpSocket)
108 {
109 // equivalent to setsockopt (MCAST_JOIN_GROUP)
110 udpSocket->MulticastJoinGroup (0, m_local);
111 }
112 else
113 {
114 NS_FATAL_ERROR ("Error: joining multicast on a non-UDP socket");
115 }
116 }
117 }
118
119 m_socket->SetRecvCallback (MakeCallback (&StupidInterestSink::HandleRead, this));
120 m_socket->SetAcceptCallback (
121 MakeNullCallback<bool, Ptr<Socket>, const Address &> (),
122 MakeCallback (&StupidInterestSink::HandleAccept, this));
123 m_socket->SetCloseCallbacks (
124 MakeCallback (&StupidInterestSink::HandlePeerClose, this),
125 MakeCallback (&StupidInterestSink::HandlePeerError, this));
126 }
127
128 void StupidInterestSink::StopApplication () // Called at time specified by Stop
129 {
130 NS_LOG_FUNCTION (this);
131 while(!m_socketList.empty ()) //these are accepted sockets, close them
132 {
133 Ptr<Socket> acceptedSocket = m_socketList.front ();
134 m_socketList.pop_front ();
135 acceptedSocket->Close ();
136 }
137 if (m_socket)
138 {
139 m_socket->Close ();
140 m_socket->SetRecvCallback (MakeNullCallback<void, Ptr<Socket> > ());
141 }
142 }
143
144 void StupidInterestSink::HandleRead (Ptr<Socket> socket)
145 {
146 NS_LOG_FUNCTION (this << socket);
147 Ptr<Packet> packet;
148 Address from;
149 while (packet = socket->RecvFrom (from))
150 {
151 if (packet->GetSize () == 0)
152 { //EOF
153 break;
154 }
155 if (InetSocketAddress::IsMatchingType (from))
156 {
157 m_totalRx += packet->GetSize ();
158 InetSocketAddress address = InetSocketAddress::ConvertFrom (from);
159 NS_LOG_INFO ("Received " << packet->GetSize () << " bytes from " <<
160 address.GetIpv4 () << " [" << address << "]"
161 << " total Rx " << m_totalRx);
162 //cast address to void , to suppress 'address' set but not used
163 //compiler warning in optimized builds
164 (void) address;
165 }
166 m_rxTrace (packet, from);
167 }
168 }
169
170 void StupidInterestSink::HandlePeerClose (Ptr<Socket> socket)
171 {
172 NS_LOG_INFO ("PktSink, peerClose");
173 }
174
175 void StupidInterestSink::HandlePeerError (Ptr<Socket> socket)
176 {
177 NS_LOG_INFO ("PktSink, peerError");
178 }
179
180
181 void StupidInterestSink::HandleAccept (Ptr<Socket> s, const Address& from)
182 {
183 NS_LOG_FUNCTION (this << s << from);
184 s->SetRecvCallback (MakeCallback (&StupidInterestSink::HandleRead, this));
185 m_socketList.push_back (s);
186 }
187
188} // Namespace ns3