DESERT 3.5.1
Loading...
Searching...
No Matches
uwicrp-module-sink.cpp
Go to the documentation of this file.
1//
2// Copyright (c) 2017 Regents of the SIGNET lab, University of Padova.
3// All rights reserved.
4//
5// Redistribution and use in source and binary forms, with or without
6// modification, are permitted provided that the following conditions
7// are met:
8// 1. Redistributions of source code must retain the above copyright
9// notice, this list of conditions and the following disclaimer.
10// 2. Redistributions in binary form must reproduce the above copyright
11// notice, this list of conditions and the following disclaimer in the
12// documentation and/or other materials provided with the distribution.
13// 3. Neither the name of the University of Padova (SIGNET lab) nor the
14// names of its contributors may be used to endorse or promote products
15// derived from this software without specific prior written permission.
16//
17// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
19// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
20// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
21// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
22// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
23// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
24// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
25// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
26// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
27// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28//
29
39#include "uwicrp-module-sink.h"
40
41extern packet_t PT_UWICRP_ACK;
42extern packet_t PT_UWICRP_STATUS;
43extern packet_t PT_UWICRP_DATA;
44
48static class UwIcrpSinkModuleClass : public TclClass
49{
50public:
52 : TclClass("Module/UW/ICRPSink")
53 {
54 }
55
56 TclObject *
57 create(int, const char *const *)
58 {
59 return (new UwIcrpSink());
60 }
62
65
67 : ipAddr_(0)
68 , printDebug_(0)
69{
70 bind("printDebug_", &printDebug_);
71 cout.precision(2);
72 cout.setf(ios::floatfield, ios::fixed);
73}
74
78
79int
81{
82 return Module::recvSyncClMsg(m);
83}
84
85int
87{
88 if (m->type() == UWIP_CLMSG_SEND_ADDR) {
90 ipAddr_ = m_->getAddr();
91 }
92 return Module::recvAsyncClMsg(m);
93}
94
95void
97{
98 if (ipAddr_ == 0) {
99 UWIPClMsgReqAddr *m = new UWIPClMsgReqAddr(getId());
100 sendSyncClMsgDown(m);
101 }
102}
103
104int
105UwIcrpSink::command(int argc, const char *const *argv)
106{
107 Tcl &tcl = Tcl::instance();
108
109 if (argc == 2) {
110 if (strcasecmp(argv[1], "initialize") == 0) {
111 this->initialize();
112 return TCL_OK;
113 } else if (strcasecmp(argv[1], "getackheadersize") == 0) {
114 tcl.resultf("%d", this->getAckPktHeaderSize());
115 return TCL_OK;
116 } else if (strcasecmp(argv[1], "getdataheadersize") == 0) {
117 tcl.resultf("%d", this->getDataPktHeaderSize());
118 return TCL_OK;
119 } else if (strcasecmp(argv[1], "getstatusheadersize") == 0) {
120 tcl.resultf("%d", this->getStatusPktHeaderSize());
121 return TCL_OK;
122 } else if (strcasecmp(argv[1], "getackpktcount") == 0) {
123 tcl.resultf("%lu", numberofackpkt_);
124 return TCL_OK;
125 } else if (strcasecmp(argv[1], "getstatuspktcount") == 0) {
126 tcl.resultf("%lu", numberofstatuspkt_);
127 return TCL_OK;
128 }
129 } else if (argc == 3) {
130 if (strcasecmp(argv[1], "addr") == 0) {
131 ipAddr_ = static_cast<uint8_t>(atoi(argv[2]));
132 return TCL_OK;
133 if (ipAddr_ == 0) {
134 fprintf(stderr, "0 is not a valid IP address");
135 return TCL_ERROR;
136 }
137 return TCL_OK;
138 }
139 }
140 return Module::command(argc, argv);
141}
142
143void
145{
146 hdr_cmn *ch = HDR_CMN(p);
147
148 if (!ch->error()) {
149 if (ch->direction() == hdr_cmn::UP) {
150 if (ch->ptype_ == PT_UWICRP_STATUS) {
151 if (printDebug_ > 10)
152 cout << "@" << Scheduler::instance().clock()
153 << " -> S: " << this->printIP(ipAddr_)
154 << " - CP: " << ch->uid()
155 << " - UP - Status Packet - Garbage." << endl;
156 Packet::free(p);
157 return;
158 }
159 if (ch->ptype_ == PT_UWICRP_ACK) {
160 if (printDebug_ > 10)
161 cout << "@" << Scheduler::instance().clock()
162 << " -> S: " << this->printIP(ipAddr_)
163 << " - CP: " << ch->uid()
164 << " - UP - Ack Packet - Garbage." << endl;
165 Packet::free(p);
166 return;
167 } else { // Data packet
168 if (ch->next_hop() !=
169 UWIP_BROADCAST) { // The source has already a path to
170 // reach this node. length == 1
171 // because the IP in position 0 is the
172 // IP of the source
173 if (printDebug_ > 10)
174 cout << "@" << Scheduler::instance().clock()
175 << " -> S: " << this->printIP(ipAddr_)
176 << " - CP: " << ch->uid()
177 << " - UP - Data Packet Received. Send it up."
178 << endl;
179 this->sendBackAck(p);
180 sendUp(p);
181 return;
182 } else { // The source doesn't have a path to reach this node:
183 // create a status packet. In this case an ack is not
184 // required.
185 if (printDebug_ > 10)
186 cout << "@" << Scheduler::instance().clock()
187 << " -> S: " << this->printIP(ipAddr_)
188 << " - CP: " << ch->uid()
189 << " - UP - Data Packet Received: Send it Up and "
190 "Send back the Path."
191 << endl;
192 Packet *p_new = Packet::alloc();
193 this->initStatusPkt(p, p_new);
195 sendDown(p_new);
196 sendUp(p);
197 return;
198 }
199 }
200 } else if (ch->direction() == hdr_cmn::DOWN) {
201 if (printDebug_ > 10)
202 cout << "@" << Scheduler::instance().clock()
203 << " -> S: " << this->printIP(ipAddr_)
204 << " - P: " << ch->uid()
205 << " - DOWN - Packet from upper layer - Garbage." << endl;
206 Packet::free(p);
207 return;
208 } else {
209 if (printDebug_ > 10)
210 cout << "@" << Scheduler::instance().clock()
211 << " -> S: " << this->printIP(ipAddr_)
212 << " - P: " << ch->uid()
213 << " - ??? - NO_DIRECTION - Garbage." << endl;
214 Packet::free(p);
215 return;
216 }
217 }
218}
219
220void
221UwIcrpSink::initStatusPkt(Packet *p_old, Packet *p_new)
222{
223 // Common header.
224 hdr_cmn *ch_old = HDR_CMN(p_old);
225 hdr_cmn *ch_new = HDR_CMN(p_new);
226 // ch->uid() = 0; // Set by the Application above.
227 ch_new->ptype() = PT_UWICRP_STATUS;
228 // ch->size() = 0; // Look Down;
229 ch_new->direction() = hdr_cmn::DOWN;
230 // ch->next_hop() = 0; // Set by SuwIPRoutingNode::forwardDataPacket.
231 ch_new->next_hop() = ch_old->prev_hop_;
232 ch_new->prev_hop_ = ipAddr_;
233
234 // IP Header.
235 hdr_uwip *iph_old = HDR_UWIP(p_old);
236 hdr_uwip *iph_new = HDR_UWIP(p_new);
237 iph_new->daddr() = iph_old->saddr(); // The destination is the source of the
238 // data packet
239 // iph->dport() = 0; // Set by the Application above.
240 // iph->saddr() = 0; // Set by IPModule
241 // iph->sport() = 0; // Set by the Application above.
242 // iph->ttl() = 0; // Set by IPModule
243
244 // Data header.
245 hdr_uwicrp_data *icrpdatah_old = HDR_UWICRP_DATA(p_old);
246 hdr_uwicrp_status *icrpstatush_new = HDR_UWICRP_STATUS(p_new);
247 for (int i = 0; i < icrpdatah_old->list_of_hops_length(); i++) {
248 icrpstatush_new->list_of_hops()[i] = icrpdatah_old->list_of_hops()[i];
249 }
250 icrpstatush_new->list_of_hops_length() =
251 icrpdatah_old->list_of_hops_length();
252 icrpstatush_new->pointer_to_list_of_hops() =
253 icrpdatah_old->pointer_to_list_of_hops();
254 icrpstatush_new->creation_time() = Scheduler::instance().clock();
255
256 ch_new->size() += sizeof(hdr_uwicrp_status);
257 ch_new->timestamp() = Scheduler::instance().clock();
258}
259
260string
261UwIcrpSink::printIP(const uint8_t _ip)
262{
263 std::stringstream out;
264 out << "0.0.0." << ((_ip & 0x000000ff));
265 return out.str();
266}
267
268void
270{
271 Packet *p_ack = Packet::alloc();
272
273 hdr_cmn *ch = HDR_CMN(p);
274 hdr_cmn *ch_ack = HDR_CMN(p_ack);
275 hdr_uwip *iph_ack = HDR_UWIP(p_ack);
276
277 ch_ack->ptype() = PT_UWICRP_ACK;
278 ch_ack->direction() = hdr_cmn::DOWN;
279 ch_ack->next_hop() = ch->prev_hop_;
280 ch_ack->prev_hop_ = ipAddr_;
281
282 iph_ack->daddr() = ch->prev_hop_;
283
284 ch_ack->size() += sizeof(hdr_uwicrp_ack);
285 ch_ack->timestamp() = Scheduler::instance().clock();
287 sendDown(p_ack);
288} /* UwIcrpSink::sendBackAck */
Class that manages cross layer messages that require the IP of the node.
Definition uwip-clmsg.h:57
Class used to answer to UWIPClMsgReqAddr cross layer messages.
Definition uwip-clmsg.h:68
nsaddr_t getAddr()
Adds the module for UwIcrpSinkModuleClass in ns2.
TclObject * create(int, const char *const *)
UwIcrpSink class is used to represent the routing layer of a node.
virtual void initStatusPkt(Packet *, Packet *)
Initializes a Status Packet previously allocated.
static long numberofackpkt_
Comulative number of Ack packets processed by UwIcrpSink objects.
virtual void initialize()
Initializes a UwIcrpSink node.
int printDebug_
Flag to enable or disable dirrefent levels of debug.
virtual void recv(Packet *)
Performs the reception of packets from upper and lower layers.
virtual int recvSyncClMsg(ClMessage *)
Cross-Layer messages synchronous interpreter.
uint8_t ipAddr_
IP of the current node.
static long numberofstatuspkt_
Comulative number of Status packets processed by UwIcrpSink objects.
UwIcrpSink()
Constructor of UwIcrpSink class.
virtual string printIP(const uint8_t)
Return a string with an IP in the classic form "x.x.x.x" converting an ns2 nsaddr_t address.
static const int getAckPktHeaderSize()
Returns the size in byte of a hdr_uwicrp_ack packet header.
static const int getStatusPktHeaderSize()
Returns the size in byte of a hdr_uwicrp_status packet header.
virtual void sendBackAck(const Packet *p)
Creates an ack packet and sends it to the previous hop using the information contained in the header ...
virtual int recvAsyncClMsg(ClMessage *)
Initializes a UwIcrpSink node.
static const int getDataPktHeaderSize()
Returns the size in byte of a hdr_uwicrp_data packet header.
virtual int command(int, const char *const *)
TCL command interpreter.
~UwIcrpSink()
Destructor of UwIcrpSink class.
hdr_uwicrp_ack describes acks packets used by UWICRP.
hdr_uwicrp_data describes data packets used by UWICRP
int & pointer_to_list_of_hops()
Reference to the pointer_to_list_of_hops_ variable.
int & list_of_hops_length()
Reference to the list_of_hops_length_ variable.
nsaddr_t * list_of_hops()
Pointer to the list_of_hops_ variable.
hdr_uwicrp_status describes status packets used by UWICRP
int & list_of_hops_length()
Reference to the list_of_hops_length_ variable.
double & creation_time()
Reference to the creation_time_ variable.
nsaddr_t * list_of_hops()
Pointer to the list_of_hops_ variable.
int & pointer_to_list_of_hops()
Reference to the pointer_to_list_of_hops_ variable.
hdr_uwip describes UWIP packets.
Definition uwip-module.h:70
uint8_t & daddr()
Reference to the daddr_ variable.
uint8_t & saddr()
Reference to the saddr_ variable.
Definition uwip-module.h:95
#define HDR_UWICRP_DATA(p)
#define HDR_UWICRP_STATUS(p)
UwIcrpSinkModuleClass class_module_uwicrp_sink
Provides a module for sinks that needs a simple and dynamic routing protocol.
static const uint8_t UWIP_BROADCAST
Variable used to represent a broadcast UWIP.
Definition uwip-module.h:62
#define HDR_UWIP(P)
Definition uwip-module.h:58