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