RINASim  October 2016
Documentation of framework for OMNeT++
Delimiting.cc
Go to the documentation of this file.
1 // The MIT License (MIT)
2 //
3 // Copyright (c) 2014-2016 Brno University of Technology, PRISTINE project
4 //
5 // Permission is hereby granted, free of charge, to any person obtaining a copy
6 // of this software and associated documentation files (the "Software"), to deal
7 // in the Software without restriction, including without limitation the rights
8 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 // copies of the Software, and to permit persons to whom the Software is
10 // furnished to do so, subject to the following conditions:
11 //
12 // The above copyright notice and this permission notice shall be included in
13 // all copies or substantial portions of the Software.
14 //
15 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 // THE SOFTWARE.
30 #include "Delimiting.h"
31 
33 
35 {
36  delimitingTimer = nullptr;
37  delimitDelay = 0.0;
38 
39 }
40 
41 void Delimiting::initialize(int step){
42 
43  maxFlowSDUSize = getRINAModule<cModule*>(this, 2, {MOD_EFCP})->par("maxSDUSize");
44  maxFlowPDUSize = getRINAModule<cModule*>(this, 2, {MOD_EFCP})->par("maxPDUSize");
45  delimitDelay = getRINAModule<cModule*>(this, 2, {MOD_EFCP})->par("delimitDelay");
46  sduSeqNum = 1;
47 
49 
50 }
51 
53  northI = this->gateHalf(GATE_DELIMIT_NORTHIO, cGate::INPUT);
54  northO = this->gateHalf(GATE_DELIMIT_NORTHIO, cGate::OUTPUT);
55 
56  southI = this->gateHalf(GATE_DELIMIT_SOUTHIO, cGate::INPUT, 0);
57  southO = this->gateHalf(GATE_DELIMIT_SOUTHIO, cGate::OUTPUT, 0);
58 }
59 
60 
61 void Delimiting::handleMessage(cMessage* msg){
62  if (msg->isSelfMessage())
63  {
64  //self-message
65 
66  DelimitingTimers* timer = static_cast<DelimitingTimers*>(msg);
67  switch (timer->getType())
68  {
69  case (DELIMITING_DELIMIT_TIMER): {
70 
71  UserDataField* userDataField;
72  for(auto it = pduDataQOut.begin(); it != pduDataQOut.end(); it = pduDataQOut.erase(it))
73  {
74  userDataField = new UserDataField();
75  userDataField->encapsulate((*it));
76  userDataField->setCompleteSDU((*it)->getCompleteSDU());
77  userDataField->setFirstFragment((*it)->getFirstFragment());
78  userDataField->setMidFragment((*it)->getMidFragment());
79  userDataField->setLastFragment((*it)->getLastFragment());
80  userDataField->setNoLength(false);
81  userDataField->setSduSeqNumPresent(true);
82  userDataField->setSduSeqNum(sduSeqNum);
83  send(userDataField, southO);
84  }
85  break;
86  }
87  }
88  }
89  else
90  {
91  if (msg->arrivedOn(northI->getId()))
92  {
93  processMsgFromFAI(static_cast<SDUData*>(msg));
94  }
95  else if (msg->arrivedOn(southI->getId()))
96  {
97  handleMsgFromEfcpi(static_cast<UserDataField*>(msg));
98  }
99  else
100  {
101  //A2 panic!
102  }
103 
104  }
105 
106 }
107 
108 
110 {
111  //TODO A2 sduSeqNum handling makes me want to laugh (or cry)
112 
113  /* Fragment, if necessary */
114  std::vector<Data*> dataQ;
115  if(sduData->getByteLength() > maxFlowPDUSize)
116  {
117  /* We need to fragment */
118  int64_t length = sduData->getByteLength();
119  Data* data = new Data;
121  data->encapsulate(sduData);
122  data->setEncapMsgLength(length);
123  length -= maxFlowPDUSize;
124  data->setByteLength(maxFlowPDUSize);
125  dataQ.push_back(data);
126 
127  for(;length - maxFlowPDUSize > 0; length -= maxFlowPDUSize)
128  {
129  /* Only the first fragment contains the actual SDUData, other fragments are there only for purpose of modelling */
130  data = new Data;
132  // data->encapsulate(sduData->dup()); // Uncomment this line if you want copy of SDUData in every fragment
133  data->setByteLength(maxFlowPDUSize);
134  dataQ.push_back(data);
135  }
136 
137  data = new Data;
139  // data->encapsulate(sduData->dup()); // Uncomment this line if you want copy of SDUData in every fragment
140  data->setByteLength(length);
141  dataQ.push_back(data);
142 
143 
144 
145  PDUData* pduData;
146 
147  for(auto it = dataQ.begin(); it != dataQ.end(); it = dataQ.erase(it))
148  {
149  pduData = new PDUData();
150  pduData->encapsulate((*it));
151  pduDataQOut.push_back(pduData);
152 
153  }
154 
155  UserDataField* userDataField;
156  for(auto it = pduDataQOut.begin(); it != pduDataQOut.end(); it = pduDataQOut.erase(it))
157  {
158  userDataField = new UserDataField();
159  userDataField->encapsulate((*it));
160  userDataField->setCompleteSDU((*it)->getCompleteSDU());
161  userDataField->setFirstFragment((*it)->getFirstFragment());
162  userDataField->setMidFragment((*it)->getMidFragment());
163  userDataField->setLastFragment((*it)->getLastFragment());
164  userDataField->setNoLength(false);
165  userDataField->setSduSeqNumPresent(true);
166  userDataField->setSduSeqNum(sduSeqNum);
167  send(userDataField, southO);
168  }
169  sduSeqNum++;
170 
171  }
172  else if(sduData->getByteLength() < maxFlowPDUSize * 0.8)
173  {
174  /* Concatenation */
175 
176 
177  if (pduDataQOut.empty())
178  {
179  Data* data = new Data();
181  data->encapsulate(sduData);
182 
183  PDUData* pduData = new PDUData();
184  pduData->encapsulate(data);
185  pduDataQOut.push_back(pduData);
186 
187 
189 
190  return;
191 
192  }else{
193 
194  PDUData* pduData = pduDataQOut.back();
195  int64_t pduDatalength = pduData->getByteLength();
196  int64_t restLength = maxFlowPDUSize - pduDatalength;
197 
198  if(restLength < sduData->getByteLength())
199  {
200  //We need to fragment
201  int64_t length = sduData->getByteLength();
202  Data* data = new Data();
204  data->encapsulate(sduData);
205  data->setEncapMsgLength(length);
206  data->setByteLength(restLength);
207 
208  length -= restLength;
209 
210  pduData->encapsulate(data);
211 
212  for(;length - maxFlowPDUSize > 0; length -= maxFlowPDUSize)
213  {
214  data = new Data;
216  // data->encapsulate(sduData->dup()); // Uncomment this line if you want copy of SDUData in every fragment
217  data->setByteLength(maxFlowPDUSize);
218  dataQ.push_back(data);
219  }
220 
221  data = new Data;
223  // data->encapsulate(sduData->dup()); // Uncomment this line if you want copy of SDUData in every fragment
224  data->setByteLength(length);
225  dataQ.push_back(data);
226 
227  for(auto it = dataQ.begin(); it != dataQ.end(); it = dataQ.erase(it))
228  {
229  pduData = new PDUData();
230  pduData->encapsulate((*it));
231  pduDataQOut.push_back(pduData);
232 
233  }
234 
235  UserDataField* userDataField;
236  for(auto it = pduDataQOut.begin(); it != pduDataQOut.end() && ((*it)->getByteLength() > maxFlowPDUSize * 0.8 && pduDataQOut.size() > 1); it = pduDataQOut.erase(it))
237  {
238  userDataField = new UserDataField();
239  userDataField->encapsulate((*it));
240  userDataField->setCompleteSDU((*it)->getCompleteSDU());
241  userDataField->setFirstFragment((*it)->getFirstFragment());
242  userDataField->setMidFragment((*it)->getMidFragment());
243  userDataField->setLastFragment((*it)->getLastFragment());
244  userDataField->setNoLength(false);
245  userDataField->setSduSeqNumPresent(true);
246  userDataField->setSduSeqNum(sduSeqNum);
247  send(userDataField, southO);
248  }
249  // sduSeqNum++; //
250 
251  }
252  else
253  {
254  //It fits!
255  Data* data = new Data();
257  data->encapsulate(sduData);
258 
259  // pduData = new PDUData();
260  pduData->encapsulate(data);
261 
263 
264  }
265  }
266  }
267  else
268  {
269  /* SDUData is small enough to fit in one PDU and too big for concatenation */
270 
271 
272  cancelEvent(delimitingTimer);
273 
274  UserDataField* userDataField;
275  for(auto it = pduDataQOut.begin(); it != pduDataQOut.end(); it = pduDataQOut.erase(it))
276  {
277  userDataField = new UserDataField();
278  userDataField->encapsulate((*it));
279  userDataField->setCompleteSDU((*it)->getCompleteSDU());
280  userDataField->setFirstFragment((*it)->getFirstFragment());
281  userDataField->setMidFragment((*it)->getMidFragment());
282  userDataField->setLastFragment((*it)->getLastFragment());
283  userDataField->setNoLength(false);
284  userDataField->setSduSeqNumPresent(true);
285  userDataField->setSduSeqNum(sduSeqNum);
286  send(userDataField, southO);
287 
288  }
289  sduSeqNum++;
290 
291  Data* data = new Data();
293  data->encapsulate(sduData);
294 
295  PDUData* pduData = new PDUData();
296  pduData->encapsulate(data);
297 
298  // pduDataQOut.push_back(pduData);
299 
300  userDataField = new UserDataField();
301  userDataField->encapsulate(pduData);
302  userDataField->setCompleteSDU(true);
303  userDataField->setNoLength(false);
304  userDataField->setSduSeqNumPresent(true);
305  userDataField->setSduSeqNum(sduSeqNum++);
306 
307 // userDataFieldQOut.push_back(userDataField);
308  send(userDataField, southO);
309 
310  }
311 }
312 
314 {
315 
316 
317  userDataFieldQIn.push_back(userDataField);
318 
319  PDUData* pduData;
320  for(auto it = userDataFieldQIn.begin(); it != userDataFieldQIn.end(); it = userDataFieldQIn.erase(it))
321  {
322  pduData = static_cast<PDUData*>((*it)->decapsulate());
323  Data* data;
324  for(; (data = pduData->decapsulate()) != nullptr; ){
325  dataQIn.push_back(data);
326  }
327  delete (*it);
328  delete pduData;
329  }
330 
331  for(auto it = dataQIn.begin(); it != dataQIn.end(); )
332  {
333  if((*it)->getDataType() == DATA_SDU_COMPLETE)
334  {
335  SDUData* sduData = dynamic_cast<SDUData*>((*it)->decapsulate());
336  if (sduData != nullptr)
337  {
338  sduDataQIn.push_back(sduData);
339  }
340  delete (*it);
341  it = dataQIn.erase(it);
342  }
343  else if ((*it)->getDataType() == DATA_FIRST_FRAG)
344  {
345  /* Try to find lastFragment */
346  auto tmpIt = it;
347  tmpIt++;
348  bool found = false;
349  for(; tmpIt != dataQIn.end(); ++tmpIt){
350  if((*tmpIt)->getDataType() == DATA_LAST_FRAG){
351  found = true;
352  break;
353  }
354  }
355 
356  if(found){
357  //restore original length
358  (*it)->setByteLength((*it)->getEncapMsgLength());
359  SDUData* sduData = dynamic_cast<SDUData*>((*it)->decapsulate());
360  if (sduData != nullptr)
361  {
362  sduDataQIn.push_back(sduData);
363  }
364  delete (*it);
365  it = dataQIn.erase(it);
366 
367  for(; it != dataQIn.end() && ((*it)->getDataType() == DATA_MIDDLE_FRAG || (*it)->getDataType() == DATA_LAST_FRAG); it = dataQIn.erase(it))
368  {
369  /* All the middle and the last fragments are empty */
370  delete (*it);
371  }
372  }else{
373  break;
374  }
375 
376  }
377  else
378  {
379  break;
380  }
381  }
382 
383 
384  //TODO A1: This is only if immediate = true, otherwise we should wait for some kind of read()
385  for(auto it = sduDataQIn.begin(); it != sduDataQIn.end(); it = sduDataQIn.erase(it))
386  {
387  send((*it), northO);
388  }
389 }
391 {
392 
393  switch (timer->getType()){
395  {
396  if(!timer->isScheduled()){
397  scheduleAt(simTime() + delimitDelay, timer);
398  }
399  break;
400  }
401 
402 
403  }
404 }
405 
406 
407 
409 {
410  cancelAndDelete(delimitingTimer);
411 
412  for(auto it = dataQIn.begin(); it != dataQIn.end();)
413  {
414  delete (*it);
415  it = dataQIn.erase(it);
416  }
417 
418 
419 }
420 
virtual void setNoLength(bool noLength)
Definition: Data.h:36
cGate * southO
Definition: Delimiting.h:52
virtual void setEncapMsgLength(int64_t encapMsgLength)
Definition: Data_m.cc:231
virtual void setSduSeqNumPresent(bool sduSeqNumPresent)
virtual void handleMessage(cMessage *msg)
Definition: Delimiting.cc:61
Define_Module(Delimiting)
const char * MOD_EFCP
Definition: ExternConsts.cc:40
unsigned int maxFlowSDUSize
Definition: Delimiting.h:69
void handleMsgFromEfcpi(UserDataField *msg)
Definition: Delimiting.cc:313
unsigned int sduSeqNum
Definition: Delimiting.h:68
virtual int getType() const
#define GATE_DELIMIT_SOUTHIO
Definition: Delimiting.h:43
virtual void setLastFragment(bool lastFragment)
#define GATE_DELIMIT_NORTHIO
Definition: Delimiting.h:42
std::vector< SDUData * > sduDataQIn
Definition: Delimiting.h:60
std::vector< Data * > dataQIn
Definition: Delimiting.h:59
cGate * northI
Definition: Delimiting.h:49
unsigned int maxFlowPDUSize
Definition: Delimiting.h:70
void setSduSeqNum(unsigned int sduSeqNum)
virtual void setFirstFragment(bool firstFragment)
std::vector< UserDataField * > userDataFieldQIn
Definition: Delimiting.h:58
double delimitDelay
Definition: Delimiting.h:71
virtual void setDataType(int dataType)
Definition: Data_m.cc:221
void initGates()
Definition: Delimiting.cc:52
void processMsgFromFAI(SDUData *msg)
Definition: Delimiting.cc:109
void schedule(DelimitingTimers *timer)
Definition: Delimiting.cc:390
virtual void initialize(int step)
Definition: Delimiting.cc:41
virtual Data * decapsulate()
Definition: PDUData.cc:90
cGate * northO
Definition: Delimiting.h:50
virtual ~Delimiting()
Definition: Delimiting.cc:408
virtual void setCompleteSDU(bool completeSDU)
DelimitingDelimitTimer * delimitingTimer
Definition: Delimiting.h:55
virtual void encapsulate(Data *data)
Definition: PDUData.cc:59
virtual void setMidFragment(bool midFragment)
cGate * southI
Definition: Delimiting.h:51
std::vector< PDUData * > pduDataQOut
Definition: Delimiting.h:64