INET Framework for OMNeT++/OMNEST
inet::physicallayer::BerParseFile Class Reference

Radio model for IEEE 802.11. More...

#include <BerParseFile.h>

Classes

struct  LongBer
 
struct  SnrBer
 

Public Member Functions

void parseFile (const char *filename)
 
bool isFile ()
 
void setPhyOpMode (char p)
 
double getPer (double speed, double tsnr, int tlen)
 
 BerParseFile (char p)
 
 ~BerParseFile ()
 

Protected Types

typedef std::vector< SnrBerSnrBerList
 
typedef std::vector< LongBer * > BerList
 
typedef std::vector< BerListBerTable
 

Protected Member Functions

int getTablePosition (double speed)
 
void clearBerTable ()
 
double dB2fraction (double dB)
 

Protected Attributes

BerTable berTable
 
char phyOpMode
 
bool fileBer
 

Detailed Description

Radio model for IEEE 802.11.

The implementation is largely based on the Mobility Framework's SnrEval80211 and Decider80211 modules. See the NED file for more info.

Member Typedef Documentation

◆ BerList

typedef std::vector<LongBer *> inet::physicallayer::BerParseFile::BerList
protected

◆ BerTable

typedef std::vector<BerList> inet::physicallayer::BerParseFile::BerTable
protected

◆ SnrBerList

typedef std::vector<SnrBer> inet::physicallayer::BerParseFile::SnrBerList
protected

Constructor & Destructor Documentation

◆ BerParseFile()

inet::physicallayer::BerParseFile::BerParseFile ( char  p)
inline
70 { setPhyOpMode(p); fileBer = false; }

◆ ~BerParseFile()

inet::physicallayer::BerParseFile::~BerParseFile ( )
346 {
347  clearBerTable();
348 }

Member Function Documentation

◆ clearBerTable()

void inet::physicallayer::BerParseFile::clearBerTable ( )
protected
22 {
23  while (!berTable.empty()) {
24  BerList *berList = &berTable.back();
25  while (!berList->empty()) {
26  delete berList->back();
27  berList->pop_back();
28  }
29  berTable.pop_back();
30  }
31  fileBer = false;
32 }

Referenced by setPhyOpMode(), and ~BerParseFile().

◆ dB2fraction()

double inet::physicallayer::BerParseFile::dB2fraction ( double  dB)
inlineprotected
61  {
62  return pow(10.0, (dB / 10));
63  }

Referenced by parseFile().

◆ getPer()

double inet::physicallayer::BerParseFile::getPer ( double  speed,
double  tsnr,
int  tlen 
)
78 {
79  BerList *berlist;
80  berlist = &berTable[getTablePosition(speed)];
81  LongBer *pre = nullptr;
82  LongBer *pos = nullptr;
83  unsigned int j;
84  for (j = 0; j < berlist->size(); j++) {
85  pos = *(berlist->begin() + j);
86  if (pos->longpkt >= tlen) {
87  break;
88  }
89  }
90  if (j == 0)
91  pre = nullptr;
92  else {
93  if (j == berlist->size())
94  pre = *(berlist->begin() + j - 2);
95  else
96  pre = *(berlist->begin() + j - 1);
97  }
98  SnrBer snrdata1;
99  SnrBer snrdata2;
100  SnrBer snrdata3;
101  SnrBer snrdata4;
102  snrdata1.snr = -1;
103  snrdata1.ber = -1;
104  snrdata2.snr = -1;
105  snrdata2.ber = -1;
106  snrdata3.snr = -1;
107  snrdata3.ber = -1;
108  snrdata4.snr = -1;
109  snrdata4.ber = -1;
110 
111  if (pos->snrlist.size() < 1)
112  throw cRuntimeError("model error: pos->snrlist is empty");
113  if (tsnr > pos->snrlist[pos->snrlist.size() - 1].snr) {
114  snrdata1 = pos->snrlist[pos->snrlist.size() - 1];
115  snrdata2 = pos->snrlist[pos->snrlist.size() - 1];
116  }
117  else {
118  for (j = 0; j < pos->snrlist.size(); j++) {
119  snrdata1 = pos->snrlist[j];
120  if (tsnr <= snrdata1.snr)
121  break;
122  }
123  if (j == 0) {
124  snrdata2.snr = -1;
125  snrdata2.ber = -1;
126  }
127  else {
128  if (j == pos->snrlist.size()) {
129  if (j < 2)
130  throw cRuntimeError("model error: pos->snrlist is too short, should be 2 or more elements");
131  snrdata2 = pos->snrlist[j - 2];
132  }
133  else
134  snrdata2 = pos->snrlist[j - 1];
135  }
136  }
137 
138  if (pre == nullptr)
139  pre = pos;
140  if (tsnr > pre->snrlist[pre->snrlist.size() - 1].snr) {
141  snrdata3 = pre->snrlist[pre->snrlist.size() - 1];
142  snrdata4 = pre->snrlist[pre->snrlist.size() - 1];
143  }
144  else {
145  for (j = 0; j < pre->snrlist.size(); j++) {
146  snrdata3 = pre->snrlist[j];
147  if (tsnr <= snrdata3.snr)
148  break;
149  }
150  if (j != 0) {
151  if (j == pre->snrlist.size())
152  snrdata4 = pre->snrlist[j - 2];
153  else
154  snrdata4 = pre->snrlist[j - 1];
155  }
156  }
157  if (snrdata2.snr == -1) {
158  snrdata2.snr = snrdata1.snr;
159  snrdata2.ber = snrdata1.ber;
160  }
161  if (snrdata4.snr == -1) {
162  snrdata4.snr = snrdata3.snr;
163  snrdata4.ber = snrdata3.ber;
164  }
165  double per1, per2, per;
166  per1 = snrdata1.ber;
167  per2 = snrdata3.ber;
168 
169  if (tsnr <= snrdata1.snr) {
170  if (snrdata2.snr != snrdata1.snr)
171  per1 = snrdata1.ber + (snrdata2.ber - snrdata1.ber) / (snrdata2.snr - snrdata1.snr) * (tsnr - snrdata1.snr);
172  }
173  if (tsnr <= snrdata3.snr) {
174  if (snrdata3.snr != snrdata4.snr)
175  per2 = snrdata3.ber + (snrdata4.ber - snrdata3.ber) / (snrdata4.snr - snrdata3.snr) * (tsnr - snrdata3.snr);
176  }
177  if (per1 != -1 && per2 != -1) {
178  if (pos->longpkt != pre->longpkt)
179  per = per2 + (per1 - per2) / (pos->longpkt - pre->longpkt) * (tlen - pre->longpkt);
180  else
181  per = per2;
182  }
183  else {
184  if (per1 != -1) {
185  per = per1;
186  }
187  else {
188  if (per2 != -1) {
189  per = per2;
190  }
191  else {
192  EV << "No PER available";
193  per = 0;
194  }
195  }
196  }
197  return per;
198 }

Referenced by inet::physicallayer::Ieee80211BerTableErrorModel::computePacketErrorRate().

◆ getTablePosition()

int inet::physicallayer::BerParseFile::getTablePosition ( double  speed)
protected
45 {
46  speed /= 1000000;
47  if (phyOpMode == 'b') {
48  if (speed < 2)
49  return 0;
50  else if (speed < 5)
51  return 1;
52  else if (speed < 11)
53  return 2;
54  else
55  return 3;
56  }
57  else {
58  if (speed < 9)
59  return 0;
60  else if (speed < 12)
61  return 1;
62  else if (speed < 18)
63  return 2;
64  else if (speed < 24)
65  return 3;
66  else if (speed < 36)
67  return 4;
68  else if (speed < 48)
69  return 5;
70  else if (speed < 54)
71  return 6;
72  else
73  return 7;
74  }
75 }

Referenced by getPer().

◆ isFile()

bool inet::physicallayer::BerParseFile::isFile ( )
inline
67 { return fileBer; }

◆ parseFile()

void inet::physicallayer::BerParseFile::parseFile ( const char *  filename)
201 {
202  std::ifstream in(filename, std::ios::in);
203  if (in.fail())
204  throw cRuntimeError("Cannot open file '%s'", filename);
205  std::string line;
206  std::string subline;
207 
208  while (std::getline(in, line)) {
209  // '#' line
210  std::string::size_type found = line.find('#');
211  if (found == 0)
212  continue;
213  if (found != std::string::npos)
214  subline = line;
215  else
216  subline = line.substr(0, found);
217  found = subline.find("$self");
218  if (found == std::string::npos)
219  continue;
220  // Node Id
221  found = subline.find("add");
222  if (found == std::string::npos)
223  continue;
224  // Initial position
225 
226  std::string::size_type pos1 = subline.find("Mode");
227  std::string::size_type pos2 = subline.find("Mb");
228  BerList *berlist;
229  std::string substr = subline.substr(pos1 + 4, pos2 - (pos1 + 4));
230 // int speed = std::atof (subline.substr(pos1+4,pos2).c_str());
231 
232  int position = -1;
233  if (phyOpMode == 'b') {
234  if (!strcmp(substr.c_str(), "1"))
235  position = 0;
236  else if (!strcmp(substr.c_str(), "2"))
237  position = 1;
238  else if (!strcmp(substr.c_str(), "5_5"))
239  position = 2;
240  else if (!strcmp(substr.c_str(), "11"))
241  position = 3;
242  else
243  continue;
244  }
245  else {
246  if (!strcmp(substr.c_str(), "6"))
247  position = 0;
248  else if (!strcmp(substr.c_str(), "9"))
249  position = 1;
250  else if (!strcmp(substr.c_str(), "12"))
251  position = 2;
252  else if (!strcmp(substr.c_str(), "18"))
253  position = 3;
254  else if (!strcmp(substr.c_str(), "24"))
255  position = 4;
256  else if (!strcmp(substr.c_str(), "36"))
257  position = 5;
258  else if (!strcmp(substr.c_str(), "48"))
259  position = 6;
260  else if (!strcmp(substr.c_str(), "54"))
261  position = 7;
262  else
263  continue;
264  }
265 
266  if (position < 0)
267  throw cRuntimeError("ber parse file error");
268 
269  berlist = &berTable[position];
270 
271  std::string parameters = subline.substr(pos2 + 3, std::string::npos);
272  std::stringstream linestream(parameters);
273  int pkSize;
274  double snr;
275  double ber;
276  linestream >> pkSize;
277  linestream >> snr;
278  linestream >> ber;
279  snr = dB2fraction(snr);
280  if (pkSize < 128)
281  pkSize = 128;
282  else if (128 <= pkSize && pkSize < 256)
283  pkSize = 128;
284  else if (256 <= pkSize && pkSize < 512)
285  pkSize = 256;
286  else if (512 <= pkSize && pkSize < 1024)
287  pkSize = 512;
288  else if (1024 <= pkSize && pkSize < 1500)
289  pkSize = 1024;
290  else
291  pkSize = 1500;
292  if (berlist->size() == 0) {
293  LongBer *l = new LongBer;
294  l->longpkt = pkSize;
295  berlist->push_back(l);
296  }
297  LongBer *l;
298  bool inList = false;
299  for (unsigned int j = 0; j < berlist->size(); j++) {
300  l = *(berlist->begin() + j);
301  if (l->longpkt == pkSize) {
302  inList = true;
303  break;
304  }
305  }
306  if (!inList) {
307  l = new LongBer;
308  l->longpkt = pkSize;
309 
310  unsigned int position = 0;
311  for (position = 0; position < berlist->size(); position++) {
312  LongBer *aux = *(berlist->begin() + position);
313 
314  if (l->longpkt < aux->longpkt)
315  break;
316  }
317  if (position == berlist->size())
318  berlist->push_back(l);
319  else
320  berlist->insert(berlist->begin() + position, l);
321  }
322  SnrBer snrdata;
323  snrdata.snr = snr;
324  snrdata.ber = ber;
325  l->snrlist.push_back(snrdata);
326  std::stable_sort(l->snrlist.begin(), l->snrlist.end(), std::less<SnrBer>());
327  }
328  in.close();
329 
330  // exist data?
331  if (phyOpMode == 'b') {
332  for (int i = 0; i < 4; i++)
333  if (berTable[i].size() == 0)
334  throw cRuntimeError("Error in ber class B file, speed not present");
335 
336  }
337  else {
338  for (int i = 0; i < 8; i++)
339  if (berTable[i].size() == 0)
340  throw cRuntimeError("Error in ber class A/G file, speed not present");
341 
342  }
343 }

Referenced by inet::physicallayer::Ieee80211BerTableErrorModel::initialize().

◆ setPhyOpMode()

void inet::physicallayer::BerParseFile::setPhyOpMode ( char  p)
35 {
36  clearBerTable();
37  phyOpMode = p;
38  if (phyOpMode == 'b')
39  berTable.resize(4);
40  else
41  berTable.resize(8);
42 }

Member Data Documentation

◆ berTable

BerTable inet::physicallayer::BerParseFile::berTable
protected

◆ fileBer

bool inet::physicallayer::BerParseFile::fileBer
protected

Referenced by clearBerTable().

◆ phyOpMode

char inet::physicallayer::BerParseFile::phyOpMode
protected

The documentation for this class was generated from the following files:
inet::physicallayer::BerParseFile::fileBer
bool fileBer
Definition: BerParseFile.h:56
inet::physicallayer::BerParseFile::dB2fraction
double dB2fraction(double dB)
Definition: BerParseFile.h:60
inet::physicallayer::BerParseFile::getTablePosition
int getTablePosition(double speed)
Definition: BerParseFile.cc:44
inet::physicallayer::BerParseFile::clearBerTable
void clearBerTable()
Definition: BerParseFile.cc:21
inet::physicallayer::BerParseFile::phyOpMode
char phyOpMode
Definition: BerParseFile.h:55
inet::physicallayer::BerParseFile::setPhyOpMode
void setPhyOpMode(char p)
Definition: BerParseFile.cc:34
inet::physicallayer::BerParseFile::berTable
BerTable berTable
Definition: BerParseFile.h:54
inet::physicallayer::BerParseFile::BerList
std::vector< LongBer * > BerList
Definition: BerParseFile.h:51