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