1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2008,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  * Authors: Kirill Andreev <andreev@iitp.ru>
19  *          Aleksey Kovalenko <kovalenko@iitp.ru>
20  */
21 
22 #include "ie-dot11s-configuration.h"
23 #include "ns3/packet.h"
24 namespace ns3 {
25 namespace dot11s {
26 
Dot11sMeshCapability()27 Dot11sMeshCapability::Dot11sMeshCapability () :
28   acceptPeerLinks (true), MCCASupported (false), MCCAEnabled (false), forwarding (true), beaconTimingReport (
29     true), TBTTAdjustment (true), powerSaveLevel (false)
30 {
31 }
32 uint8_t
GetSerializedSize() const33 Dot11sMeshCapability::GetSerializedSize () const
34 {
35   return 1;
36 }
37 uint8_t
GetUint8() const38 Dot11sMeshCapability::GetUint8 () const  //IEEE 802.11-2012 8.4.2.100.8 Mesh Capability
39 {
40   uint8_t result = 0;
41   if (acceptPeerLinks)
42     {
43       result |= 1 << 0; //The Accepting Additional Mesh Peerings subfield is set to 1 if the mesh STA is willing to establish additional mesh peerings   with other mesh STAs and set to 0 otherwise
44     }
45   if (MCCASupported) // The MCCA Supported subfield is set to 1 if the mesh STA implements MCCA and set to 0 otherwise
46     {
47       result |= 1 << 1;
48     }
49   if (MCCAEnabled)
50     {
51       result |= 1 << 2;
52     }
53   if (forwarding)
54     {
55       result |= 1 << 3;
56     }
57   if (beaconTimingReport)
58     {
59       result |= 1 << 4;
60     }
61   if (TBTTAdjustment)
62     {
63       result |= 1 << 5;
64     }
65   if (powerSaveLevel)
66     {
67       result |= 1 << 6;
68     }
69   return result;
70 }
71 Buffer::Iterator
Serialize(Buffer::Iterator i) const72 Dot11sMeshCapability::Serialize (Buffer::Iterator i) const
73 {
74   i.WriteU8 (GetUint8 ());
75   return i;
76 }
77 Buffer::Iterator
Deserialize(Buffer::Iterator i)78 Dot11sMeshCapability::Deserialize (Buffer::Iterator i)
79 {
80   uint8_t cap = i.ReadU8 ();
81   acceptPeerLinks = Is (cap, 0);
82   MCCASupported = Is (cap, 1);
83   MCCAEnabled = Is (cap, 2);
84   forwarding = Is (cap, 3);
85   beaconTimingReport = Is (cap, 4);
86   TBTTAdjustment = Is (cap, 5);
87   powerSaveLevel = Is (cap, 6);
88   return i;
89 }
90 bool
Is(uint8_t cap,uint8_t n) const91 Dot11sMeshCapability::Is (uint8_t cap, uint8_t n) const
92 {
93   uint16_t mask = 1 << n;
94   return (cap & mask);
95 }
96 WifiInformationElementId
ElementId() const97 IeConfiguration::ElementId () const
98 {
99   return IE_MESH_CONFIGURATION;
100 }
101 
IeConfiguration()102 IeConfiguration::IeConfiguration () :
103   m_APSPId (PROTOCOL_HWMP), m_APSMId (METRIC_AIRTIME), m_CCMId (CONGESTION_NULL), m_SPId (
104     SYNC_NEIGHBOUR_OFFSET), m_APId (AUTH_NULL), m_neighbors (0)
105 {
106 }
107 uint8_t
GetInformationFieldSize() const108 IeConfiguration::GetInformationFieldSize () const
109 {
110    return 0   // Version
111          + 1  // APSPId
112          + 1 // APSMId
113          + 1 // CCMId
114          + 1 // SPId
115          + 1 // APId
116          + 1 // Mesh formation info (see 7.3.2.86.6 of 802.11s draft 3.0)
117          + m_meshCap.GetSerializedSize ();
118 }
119 void
SerializeInformationField(Buffer::Iterator i) const120 IeConfiguration::SerializeInformationField (Buffer::Iterator i) const
121 {
122   // Active Path Selection Protocol ID:
123   i.WriteU8 (m_APSPId);
124   // Active Path Metric ID:
125   i.WriteU8 (m_APSMId);
126   // Congestion Control Mode ID:
127   i.WriteU8 (m_CCMId);
128   // Sync:
129   i.WriteU8 (m_SPId);
130   // Auth:
131   i.WriteU8 (m_APId);
132   i.WriteU8 (m_neighbors << 1);
133   m_meshCap.Serialize (i);
134 }
135 uint8_t
DeserializeInformationField(Buffer::Iterator i,uint8_t length)136 IeConfiguration::DeserializeInformationField (Buffer::Iterator i, uint8_t length)
137 {
138   Buffer::Iterator start = i;
139   // Active Path Selection Protocol ID:
140   m_APSPId = (dot11sPathSelectionProtocol) i.ReadU8 ();
141   // Active Path Metric ID:
142   m_APSMId = (dot11sPathSelectionMetric) i.ReadU8 ();
143   // Congestion Control Mode ID:
144   m_CCMId = (dot11sCongestionControlMode) i.ReadU8 ();
145   m_SPId = (dot11sSynchronizationProtocolIdentifier) i.ReadU8 ();
146   m_APId = (dot11sAuthenticationProtocol) i.ReadU8 ();
147   m_neighbors = (i.ReadU8 () >> 1) & 0xF;
148   i = m_meshCap.Deserialize (i);
149   return i.GetDistanceFrom (start);
150 }
151 void
Print(std::ostream & os) const152 IeConfiguration::Print (std::ostream& os) const
153 {
154   os << "MeshConfiguration=(neighbors=" << (uint16_t) m_neighbors
155      << ", Active Path Selection Protocol ID=" << (uint32_t) m_APSPId
156      << ", Active Path Selection Metric ID=" << (uint32_t) m_APSMId
157      << ", Congestion Control Mode ID=" << (uint32_t) m_CCMId
158      << ", Synchronize protocol ID=" << (uint32_t) m_SPId
159      << ", Authentication protocol ID=" << (uint32_t) m_APId
160      << ", Capabilities=" << m_meshCap.GetUint8 ();
161   os << ")";
162 }
163 void
SetRouting(dot11sPathSelectionProtocol routingId)164 IeConfiguration::SetRouting (dot11sPathSelectionProtocol routingId)
165 {
166   m_APSPId = routingId;
167 }
168 void
SetMetric(dot11sPathSelectionMetric metricId)169 IeConfiguration::SetMetric (dot11sPathSelectionMetric metricId)
170 {
171   m_APSMId = metricId;
172 }
173 bool
IsHWMP()174 IeConfiguration::IsHWMP ()
175 {
176   return (m_APSPId == PROTOCOL_HWMP);
177 }
178 bool
IsAirtime()179 IeConfiguration::IsAirtime ()
180 {
181   return (m_APSMId == METRIC_AIRTIME);
182 }
183 void
SetNeighborCount(uint8_t neighbors)184 IeConfiguration::SetNeighborCount (uint8_t neighbors)
185 {
186   m_neighbors = (neighbors > 31) ? 31 : neighbors;
187 }
188 uint8_t
GetNeighborCount()189 IeConfiguration::GetNeighborCount ()
190 {
191   return m_neighbors;
192 }
193 Dot11sMeshCapability const&
MeshCapability()194 IeConfiguration::MeshCapability ()
195 {
196   return m_meshCap;
197 }
198 bool
operator ==(const Dot11sMeshCapability & a,const Dot11sMeshCapability & b)199 operator== (const Dot11sMeshCapability & a, const Dot11sMeshCapability & b)
200 {
201   return ((a.acceptPeerLinks == b.acceptPeerLinks) && (a.MCCASupported == b.MCCASupported) && (a.MCCAEnabled
202                                                                                                == b.MCCAEnabled) && (a.forwarding == b.forwarding) && (a.beaconTimingReport == b.beaconTimingReport)
203           && (a.TBTTAdjustment == b.TBTTAdjustment) && (a.powerSaveLevel == b.powerSaveLevel));
204 }
205 bool
operator ==(const IeConfiguration & a,const IeConfiguration & b)206 operator== (const IeConfiguration & a, const IeConfiguration & b)
207 {
208   return ((a.m_APSPId == b.m_APSPId) && (a.m_APSMId == b.m_APSMId) && (a.m_CCMId == b.m_CCMId) && (a.m_SPId
209                                                                                                    == b.m_SPId) && (a.m_APId == b.m_APId) && (a.m_neighbors == b.m_neighbors) && (a.m_meshCap
210                                                                                                                                                                                   == b.m_meshCap));
211 }
212 std::ostream &
operator <<(std::ostream & os,const IeConfiguration & a)213 operator << (std::ostream &os, const IeConfiguration &a)
214 {
215   a.Print (os);
216   return os;
217 }
218 } // namespace dot11s
219 } // namespace ns3
220 
221