A Discrete-Event Network Simulator
Home
Tutorials ▼
English
Portuguese
Docs ▼
Wiki
Manual
Models
Develop ▼
API
Bugs
API
Main Page
Related Pages
Modules
Namespaces
Classes
Files
File List
File Members
All
Classes
Namespaces
Files
Functions
Variables
Typedefs
Enumerations
Enumerator
Properties
Friends
Macros
Groups
Pages
peer-management-protocol-mac.cc
Go to the documentation of this file.
1
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2
/*
3
* Copyright (c) 2009 IITP RAS
4
*
5
* This program is free software; you can redistribute it and/or modify
6
* it under the terms of the GNU General Public License version 2 as
7
* published by the Free Software Foundation;
8
*
9
* This program is distributed in the hope that it will be useful,
10
* but WITHOUT ANY WARRANTY; without even the implied warranty of
11
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
* GNU General Public License for more details.
13
*
14
* You should have received a copy of the GNU General Public License
15
* along with this program; if not, write to the Free Software
16
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17
*
18
* Author: Kirill Andreev <andreev@iitp.ru>
19
*/
20
21
#include "
ie-dot11s-configuration.h
"
22
#include "
ie-dot11s-peer-management.h
"
23
#include "
dot11s-mac-header.h
"
24
#include "
peer-management-protocol-mac.h
"
25
#include "
peer-management-protocol.h
"
26
#include "
peer-link-frame.h
"
27
#include "ns3/mesh-wifi-interface-mac.h"
28
#include "ns3/simulator.h"
29
#include "ns3/wifi-mac-header.h"
30
#include "ns3/mesh-information-element-vector.h"
31
#include "ns3/log.h"
32
namespace
ns3 {
33
namespace
dot11s {
34
PeerManagementProtocolMac::PeerManagementProtocolMac
(uint32_t interface,
35
Ptr<PeerManagementProtocol>
protocol)
36
{
37
m_ifIndex
= interface;
38
m_protocol
= protocol;
39
}
40
41
PeerManagementProtocolMac::~PeerManagementProtocolMac
()
42
{
43
}
44
45
void
46
PeerManagementProtocolMac::SetParent
(
Ptr<MeshWifiInterfaceMac>
parent)
47
{
48
m_parent
= parent;
49
m_parent
->
TraceConnectWithoutContext
(
"TxErrHeader"
,
MakeCallback
(&
PeerManagementProtocolMac::TxError
,
this
));
50
m_parent
->
TraceConnectWithoutContext
(
"TxOkHeader"
,
MakeCallback
(&
PeerManagementProtocolMac::TxOk
,
this
));
51
}
52
void
53
PeerManagementProtocolMac::TxError
(
WifiMacHeader
const
&hdr)
54
{
55
m_protocol
->
TransmissionFailure
(
m_ifIndex
, hdr.
GetAddr1
());
56
}
57
void
58
PeerManagementProtocolMac::TxOk
(
WifiMacHeader
const
&hdr)
59
{
60
m_protocol
->
TransmissionSuccess
(
m_ifIndex
, hdr.
GetAddr1
());
61
}
62
bool
63
PeerManagementProtocolMac::Receive
(
Ptr<Packet>
const_packet,
const
WifiMacHeader
& header)
64
{
65
// First of all we copy a packet, because we need to remove some
66
//headers
67
Ptr<Packet>
packet = const_packet->
Copy
();
68
if
(header.
IsBeacon
())
69
{
70
MgtBeaconHeader
beacon_hdr;
71
packet->
RemoveHeader
(beacon_hdr);
72
MeshInformationElementVector
elements;
73
packet->
RemoveHeader
(elements);
74
Ptr<IeBeaconTiming>
beaconTiming = DynamicCast<IeBeaconTiming> (elements.
FindFirst
(
IE11S_BEACON_TIMING
));
75
Ptr<IeMeshId>
meshId = DynamicCast<IeMeshId> (elements.
FindFirst
(
IE11S_MESH_ID
));
76
77
if
((meshId != 0) && (
m_protocol
->
GetMeshId
()->
IsEqual
(*meshId)))
78
{
79
m_protocol
->
ReceiveBeacon
(
m_ifIndex
, header.
GetAddr2
(),
MicroSeconds
(
80
beacon_hdr.
GetBeaconIntervalUs
()), beaconTiming);
81
}
82
// Beacon shall not be dropped. May be needed to another plugins
83
return
true
;
84
}
85
if
(header.
IsAction
())
86
{
87
WifiActionHeader
actionHdr;
88
packet->
RemoveHeader
(actionHdr);
89
WifiActionHeader::ActionValue
actionValue = actionHdr.
GetAction
();
90
// If can not handle - just return;
91
if
(actionHdr.
GetCategory
() !=
WifiActionHeader::MESH_PEERING_MGT
)
92
{
93
return
m_protocol
->
IsActiveLink
(
m_ifIndex
, header.
GetAddr2
());
94
}
95
m_stats
.
rxMgt
++;
96
m_stats
.
rxMgtBytes
+= packet->
GetSize
();
97
Mac48Address
peerAddress = header.
GetAddr2
();
98
Mac48Address
peerMpAddress = header.
GetAddr3
();
99
PeerLinkFrameStart::PlinkFrameStartFields
fields;
100
{
101
PeerLinkFrameStart
peerFrame;
102
peerFrame.
SetPlinkFrameSubtype
((uint8_t) actionValue.
peerLink
);
103
packet->
RemoveHeader
(peerFrame);
104
fields = peerFrame.
GetFields
();
105
NS_ASSERT
(fields.
subtype
== actionValue.
peerLink
);
106
}
107
if
((actionValue.
peerLink
!=
WifiActionHeader::PEER_LINK_CLOSE
) && !(
m_parent
->
CheckSupportedRates
(
108
fields.
rates
)))
109
{
110
m_protocol
->
ConfigurationMismatch
(
m_ifIndex
, peerAddress);
111
// Broken peer link frame - drop it
112
m_stats
.
brokenMgt
++;
113
return
false
;
114
}
115
if
((actionValue.
peerLink
!=
WifiActionHeader::PEER_LINK_CONFIRM
) && !fields.
meshId
.
IsEqual
(
116
*(
m_protocol
->
GetMeshId
())))
117
{
118
m_protocol
->
ConfigurationMismatch
(
m_ifIndex
, peerAddress);
119
// Broken peer link frame - drop it
120
m_stats
.
brokenMgt
++;
121
return
false
;
122
}
123
Ptr<IePeerManagement>
peerElement;
124
//Peer Management element is the last element in this frame - so, we can use MeshInformationElementVector
125
MeshInformationElementVector
elements;
126
packet->
RemoveHeader
(elements);
127
peerElement = DynamicCast<IePeerManagement>(elements.
FindFirst
(
IE11S_PEERING_MANAGEMENT
));
128
NS_ASSERT
(peerElement != 0);
129
//Check taht frame subtype corresponds peer link subtype
130
if
(peerElement->SubtypeIsOpen ())
131
{
132
m_stats
.
rxOpen
++;
133
NS_ASSERT
(actionValue.
peerLink
==
WifiActionHeader::PEER_LINK_OPEN
);
134
}
135
if
(peerElement->SubtypeIsConfirm ())
136
{
137
m_stats
.
rxConfirm
++;
138
NS_ASSERT
(actionValue.
peerLink
==
WifiActionHeader::PEER_LINK_CONFIRM
);
139
}
140
if
(peerElement->SubtypeIsClose ())
141
{
142
m_stats
.
rxClose
++;
143
NS_ASSERT
(actionValue.
peerLink
==
WifiActionHeader::PEER_LINK_CLOSE
);
144
}
145
//Deliver Peer link management frame to protocol:
146
m_protocol
->
ReceivePeerLinkFrame
(
m_ifIndex
, peerAddress, peerMpAddress, fields.
aid
, *peerElement,
147
fields.
config
);
148
// if we can handle a frame - drop it
149
return
false
;
150
}
151
return
m_protocol
->
IsActiveLink
(
m_ifIndex
, header.
GetAddr2
());
152
}
153
bool
154
PeerManagementProtocolMac::UpdateOutcomingFrame
(
Ptr<Packet>
packet,
WifiMacHeader
& header,
155
Mac48Address
from,
Mac48Address
to)
156
{
157
if
(header.
IsAction
())
158
{
159
WifiActionHeader
actionHdr;
160
packet->
PeekHeader
(actionHdr);
161
if
(actionHdr.
GetCategory
() ==
WifiActionHeader::MESH_PEERING_MGT
)
162
{
163
return
true
;
164
}
165
}
166
if
(header.
GetAddr1
().
IsGroup
())
167
{
168
return
true
;
169
}
170
else
171
{
172
if
(
m_protocol
->
IsActiveLink
(
m_ifIndex
, header.
GetAddr1
()))
173
{
174
return
true
;
175
}
176
else
177
{
178
m_stats
.
dropped
++;
179
return
false
;
180
}
181
}
182
}
183
void
184
PeerManagementProtocolMac::UpdateBeacon
(
MeshWifiBeacon
& beacon)
const
185
{
186
if
(
m_protocol
->
GetBeaconCollisionAvoidance
())
187
{
188
Ptr<IeBeaconTiming>
beaconTiming =
m_protocol
->
GetBeaconTimingElement
(
m_ifIndex
);
189
beacon.
AddInformationElement
(beaconTiming);
190
}
191
beacon.
AddInformationElement
(
m_protocol
->
GetMeshId
());
192
m_protocol
->
NotifyBeaconSent
(
m_ifIndex
, beacon.
GetBeaconInterval
());
193
}
194
195
void
196
PeerManagementProtocolMac::SendPeerLinkManagementFrame
(
Mac48Address
peerAddress,
Mac48Address
peerMpAddress,
197
uint16_t aid,
IePeerManagement
peerElement,
IeConfiguration
meshConfig)
198
{
199
//Create a packet:
200
meshConfig.
SetNeighborCount
(
m_protocol
->
GetNumberOfLinks
());
201
Ptr<Packet>
packet = Create<Packet> ();
202
MeshInformationElementVector
elements;
203
elements.
AddInformationElement
(
Ptr<IePeerManagement>
(&peerElement));
204
packet->
AddHeader
(elements);
205
PeerLinkFrameStart::PlinkFrameStartFields
fields;
206
fields.
rates
=
m_parent
->
GetSupportedRates
();
207
fields.
capability
= 0;
208
fields.
meshId
= *(
m_protocol
->
GetMeshId
());
209
fields.
config
= meshConfig;
210
PeerLinkFrameStart
plinkFrame;
211
//Create an 802.11 frame header:
212
//Send management frame to MAC:
213
WifiActionHeader
actionHdr;
214
if
(peerElement.
SubtypeIsOpen
())
215
{
216
m_stats
.
txOpen
++;
217
WifiActionHeader::ActionValue
action;
218
action.
peerLink
=
WifiActionHeader::PEER_LINK_OPEN
;
219
fields.
subtype
=
WifiActionHeader::PEER_LINK_OPEN
;
220
actionHdr.
SetAction
(
WifiActionHeader::MESH_PEERING_MGT
, action);
221
}
222
if
(peerElement.
SubtypeIsConfirm
())
223
{
224
m_stats
.
txConfirm
++;
225
WifiActionHeader::ActionValue
action;
226
action.
peerLink
=
WifiActionHeader::PEER_LINK_CONFIRM
;
227
fields.
aid
= aid;
228
fields.
subtype
=
WifiActionHeader::PEER_LINK_CONFIRM
;
229
actionHdr.
SetAction
(
WifiActionHeader::MESH_PEERING_MGT
, action);
230
}
231
if
(peerElement.
SubtypeIsClose
())
232
{
233
m_stats
.
txClose
++;
234
WifiActionHeader::ActionValue
action;
235
action.
peerLink
=
WifiActionHeader::PEER_LINK_CLOSE
;
236
fields.
subtype
=
WifiActionHeader::PEER_LINK_CLOSE
;
237
fields.
reasonCode
= peerElement.
GetReasonCode
();
238
actionHdr.
SetAction
(
WifiActionHeader::MESH_PEERING_MGT
, action);
239
}
240
plinkFrame.
SetPlinkFrameStart
(fields);
241
packet->
AddHeader
(plinkFrame);
242
packet->
AddHeader
(actionHdr);
243
m_stats
.
txMgt
++;
244
m_stats
.
txMgtBytes
+= packet->
GetSize
();
245
// Wifi Mac header:
246
WifiMacHeader
hdr;
247
hdr.
SetAction
();
248
hdr.
SetAddr1
(peerAddress);
249
hdr.
SetAddr2
(
m_parent
->
GetAddress
());
250
//Addr is not used here, we use it as our MP address
251
hdr.
SetAddr3
(
m_protocol
->
GetAddress
());
252
hdr.
SetDsNotFrom
();
253
hdr.
SetDsNotTo
();
254
m_parent
->
SendManagementFrame
(packet, hdr);
255
}
256
257
Mac48Address
258
PeerManagementProtocolMac::GetAddress
()
const
259
{
260
if
(
m_parent
!= 0)
261
{
262
return
m_parent
->
GetAddress
();
263
}
264
else
265
{
266
return
Mac48Address
();
267
}
268
}
269
void
270
PeerManagementProtocolMac::SetBeaconShift
(
Time
shift)
271
{
272
if
(shift !=
Seconds
(0))
273
{
274
m_stats
.
beaconShift
++;
275
}
276
m_parent
->
ShiftTbtt
(shift);
277
}
278
PeerManagementProtocolMac::Statistics::Statistics
() :
279
txOpen (0), txConfirm (0), txClose (0), rxOpen (0), rxConfirm (0), rxClose (0), dropped (0), brokenMgt (0),
280
txMgt (0), txMgtBytes (0), rxMgt (0), rxMgtBytes (0), beaconShift (0)
281
{
282
}
283
void
284
PeerManagementProtocolMac::Statistics::Print
(std::ostream & os)
const
285
{
286
os <<
"<Statistics "
287
"txOpen=\""
<< txOpen <<
"\""
<< std::endl <<
288
"txConfirm=\""
<< txConfirm <<
"\""
<< std::endl <<
289
"txClose=\""
<< txClose <<
"\""
<< std::endl <<
290
"rxOpen=\""
<< rxOpen <<
"\""
<< std::endl <<
291
"rxConfirm=\""
<< rxConfirm <<
"\""
<< std::endl <<
292
"rxClose=\""
<< rxClose <<
"\""
<< std::endl <<
293
"dropped=\""
<< dropped <<
"\""
<< std::endl <<
294
"brokenMgt=\""
<< brokenMgt <<
"\""
<< std::endl <<
295
"txMgt=\""
<< txMgt <<
"\""
<< std::endl <<
296
"txMgtBytes=\""
<< txMgtBytes <<
"\""
<< std::endl <<
297
"rxMgt=\""
<< rxMgt <<
"\""
<< std::endl <<
298
"rxMgtBytes=\""
<< rxMgtBytes <<
"\""
<< std::endl <<
299
"beaconShift=\""
<< beaconShift <<
"\"/>"
<< std::endl;
300
}
301
void
302
PeerManagementProtocolMac::Report
(std::ostream & os)
const
303
{
304
os <<
"<PeerManagementProtocolMac "
305
"address=\""
<<
m_parent
->
GetAddress
() <<
"\">"
<< std::endl;
306
m_stats
.
Print
(os);
307
os <<
"</PeerManagementProtocolMac>"
<< std::endl;
308
}
309
void
310
PeerManagementProtocolMac::ResetStats
()
311
{
312
m_stats
=
Statistics
();
313
}
314
uint32_t
315
PeerManagementProtocolMac::GetLinkMetric
(
Mac48Address
peerAddress)
316
{
317
return
m_parent
->
GetLinkMetric
(peerAddress);
318
}
319
int64_t
320
PeerManagementProtocolMac::AssignStreams
(int64_t stream)
321
{
322
return
m_protocol
->
AssignStreams
(stream);
323
}
324
325
}
// namespace dot11s
326
}
// namespace ns3
327
src
mesh
model
dot11s
peer-management-protocol-mac.cc
Generated on Tue Oct 9 2012 16:45:42 for ns-3 by
1.8.1.2