OLD | NEW |
(Empty) | |
| 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 * Authors: Kirill Andreev <andreev@iitp.ru> |
| 19 */ |
| 20 |
| 21 #include "peer-link-frame.h" |
| 22 #include "ie-dot11s-peer-management.h" |
| 23 #include "ns3/mesh-wifi-interface-mac.h" |
| 24 #include "ns3/test.h" |
| 25 #include "ns3/packet.h" |
| 26 |
| 27 namespace ns3 { |
| 28 namespace dot11s { |
| 29 NS_OBJECT_ENSURE_REGISTERED (PeerLinkFrameStart); |
| 30 |
| 31 PeerLinkFrameStart::PeerLinkFrameStart () : |
| 32 m_subtype (255), m_capability (0), m_aid (0), m_rates (SupportedRates ()), m_m
eshId (IeMeshId ()), |
| 33 m_config (IeConfiguration ()), m_reasonCode ((uint16_t) REASON11S_RESERVED
) |
| 34 { |
| 35 } |
| 36 void |
| 37 PeerLinkFrameStart::SetPlinkFrameSubtype (uint8_t subtype) |
| 38 { |
| 39 m_subtype = subtype; |
| 40 } |
| 41 void |
| 42 PeerLinkFrameStart::SetPlinkFrameStart (PeerLinkFrameStart::PlinkFrameStartField
s fields) |
| 43 { |
| 44 m_subtype = fields.subtype; |
| 45 m_protocol = fields.protocol; |
| 46 if (m_subtype != (uint8_t) (WifiMeshActionHeader::PEER_LINK_CLOSE)) |
| 47 { |
| 48 m_capability = fields.capability; |
| 49 } |
| 50 if (m_subtype == (uint8_t) (WifiMeshActionHeader::PEER_LINK_CONFIRM)) |
| 51 { |
| 52 m_aid = fields.aid; |
| 53 } |
| 54 if (m_subtype != (uint8_t) (WifiMeshActionHeader::PEER_LINK_CLOSE)) |
| 55 { |
| 56 m_rates = fields.rates; |
| 57 } |
| 58 if (m_subtype != (uint8_t) (WifiMeshActionHeader::PEER_LINK_CONFIRM)) |
| 59 { |
| 60 m_meshId = fields.meshId; |
| 61 } |
| 62 if (m_subtype != (uint8_t) (WifiMeshActionHeader::PEER_LINK_CLOSE)) |
| 63 { |
| 64 m_config = fields.config; |
| 65 } |
| 66 else |
| 67 { |
| 68 m_reasonCode = fields.reasonCode; |
| 69 } |
| 70 } |
| 71 PeerLinkFrameStart::PlinkFrameStartFields |
| 72 PeerLinkFrameStart::GetFields () |
| 73 { |
| 74 PlinkFrameStartFields retval; |
| 75 //TODO: protocol version: |
| 76 retval.subtype = m_subtype; |
| 77 retval.capability = m_capability; |
| 78 retval.aid = m_aid; |
| 79 retval.rates = m_rates; |
| 80 retval.meshId = m_meshId; |
| 81 retval.config = m_config; |
| 82 retval.reasonCode = m_reasonCode; |
| 83 return retval; |
| 84 } |
| 85 TypeId |
| 86 PeerLinkFrameStart::GetTypeId () |
| 87 { |
| 88 static TypeId tid = TypeId ("ns3::dot11s::PeerLinkFrameStart") .SetParent<Head
er> () .AddConstructor< |
| 89 PeerLinkFrameStart> (); |
| 90 return tid; |
| 91 } |
| 92 TypeId |
| 93 PeerLinkFrameStart::GetInstanceTypeId () const |
| 94 { |
| 95 return GetTypeId (); |
| 96 } |
| 97 void |
| 98 PeerLinkFrameStart::Print (std::ostream &os) const |
| 99 { |
| 100 os << "subtype = " << (uint16_t) m_subtype << std::endl << "capability = " <<
m_capability << std::endl << "laid = " |
| 101 << (uint16_t) m_aid << std::endl << "rates = " << m_rates << std::endl <<
"meshId = "; |
| 102 m_meshId.Print (os); |
| 103 os << std::endl << "configuration = "; |
| 104 m_config.Print (os); |
| 105 os << std::endl << "reason code = " << m_reasonCode; |
| 106 } |
| 107 uint32_t |
| 108 PeerLinkFrameStart::GetSerializedSize () const |
| 109 { |
| 110 uint32_t size = 3; //Peering protocol |
| 111 NS_ASSERT (m_subtype < 3); |
| 112 if ((uint8_t) (WifiMeshActionHeader::PEER_LINK_CLOSE) != m_subtype) |
| 113 { |
| 114 size += 2; //capability |
| 115 } |
| 116 if ((uint8_t) (WifiMeshActionHeader::PEER_LINK_CONFIRM) == m_subtype) |
| 117 { |
| 118 size += 2; //AID of remote peer |
| 119 } |
| 120 if ((uint8_t) (WifiMeshActionHeader::PEER_LINK_CLOSE) != m_subtype) |
| 121 { |
| 122 size += m_rates.GetSerializedSize (); |
| 123 } |
| 124 if ((uint8_t) (WifiMeshActionHeader::PEER_LINK_CONFIRM) != m_subtype) |
| 125 { |
| 126 size += m_meshId.GetInformationSize () + 2; |
| 127 } |
| 128 if ((uint8_t) (WifiMeshActionHeader::PEER_LINK_CLOSE) != m_subtype) |
| 129 { |
| 130 size += m_config.GetInformationSize () + 2; |
| 131 } |
| 132 else |
| 133 { |
| 134 size += 2; //reasonCode |
| 135 } |
| 136 return size; |
| 137 } |
| 138 void |
| 139 PeerLinkFrameStart::Serialize (Buffer::Iterator start) const |
| 140 { |
| 141 Buffer::Iterator i = start; |
| 142 NS_ASSERT (m_subtype < 3); |
| 143 i.WriteU8 (IE11S_MESH_PEERING_PROTOCOL_VERSION); |
| 144 i.WriteU8 (m_protocol.GetInformationSize ()); |
| 145 m_protocol.SerializeInformation (i); |
| 146 i.Next (m_protocol.GetInformationSize ()); |
| 147 if ((uint8_t) (WifiMeshActionHeader::PEER_LINK_CLOSE) != m_subtype) |
| 148 { |
| 149 i.WriteHtolsbU16 (m_capability); |
| 150 } |
| 151 if ((uint8_t) (WifiMeshActionHeader::PEER_LINK_CONFIRM) == m_subtype) |
| 152 { |
| 153 i.WriteHtolsbU16 (m_aid); |
| 154 } |
| 155 if ((uint8_t) (WifiMeshActionHeader::PEER_LINK_CLOSE) != m_subtype) |
| 156 { |
| 157 i = m_rates.Serialize (i); |
| 158 } |
| 159 if ((uint8_t) (WifiMeshActionHeader::PEER_LINK_CONFIRM) != m_subtype) |
| 160 { |
| 161 i.WriteU8 (IE11S_MESH_ID); |
| 162 i.WriteU8 (m_meshId.GetInformationSize ()); |
| 163 m_meshId.SerializeInformation (i); |
| 164 i.Next (m_meshId.GetInformationSize ()); |
| 165 } |
| 166 if ((uint8_t) (WifiMeshActionHeader::PEER_LINK_CLOSE) != m_subtype) |
| 167 { |
| 168 i.WriteU8 (IE11S_MESH_CONFIGURATION); |
| 169 i.WriteU8 (m_config.GetInformationSize ()); |
| 170 m_config.SerializeInformation (i); |
| 171 i.Next (m_config.GetInformationSize ()); |
| 172 } |
| 173 else |
| 174 { |
| 175 i.WriteHtolsbU16 (m_reasonCode); |
| 176 } |
| 177 } |
| 178 uint32_t |
| 179 PeerLinkFrameStart::Deserialize (Buffer::Iterator start) |
| 180 { |
| 181 Buffer::Iterator i = start; |
| 182 NS_ASSERT (m_subtype < 3); |
| 183 { |
| 184 uint8_t id = i.ReadU8 (); |
| 185 uint8_t length = i.ReadU8 (); |
| 186 m_protocol.DeserializeInformation (i, length); |
| 187 if ((m_protocol.ElementId () != (WifiElementId) id) || (m_protocol.GetInfo
rmationSize () != length)) |
| 188 { |
| 189 NS_FATAL_ERROR ("Broken frame: Element ID does not match IE itself!"); |
| 190 } |
| 191 i.Next (m_protocol.GetInformationSize ()); |
| 192 } |
| 193 if ((uint8_t) (WifiMeshActionHeader::PEER_LINK_CLOSE) != m_subtype) |
| 194 { |
| 195 m_capability = i.ReadLsbtohU16 (); |
| 196 } |
| 197 if ((uint8_t) (WifiMeshActionHeader::PEER_LINK_CONFIRM) == m_subtype) |
| 198 { |
| 199 m_aid = i.ReadLsbtohU16 (); |
| 200 } |
| 201 if ((uint8_t) (WifiMeshActionHeader::PEER_LINK_CLOSE) != m_subtype) |
| 202 { |
| 203 i = m_rates.Deserialize (i); |
| 204 } |
| 205 if ((uint8_t) (WifiMeshActionHeader::PEER_LINK_CONFIRM) != m_subtype) |
| 206 { |
| 207 uint8_t id = i.ReadU8 (); |
| 208 uint8_t length = i.ReadU8 (); |
| 209 m_meshId.DeserializeInformation (i, length); |
| 210 if ((m_meshId.ElementId () != (WifiElementId) id) || (m_meshId.GetInformat
ionSize () != length)) |
| 211 { |
| 212 NS_FATAL_ERROR ("Broken frame: Element ID does not match IE itself!"); |
| 213 } |
| 214 i.Next (m_meshId.GetInformationSize ()); |
| 215 } |
| 216 if ((uint8_t) (WifiMeshActionHeader::PEER_LINK_CLOSE) != m_subtype) |
| 217 { |
| 218 uint8_t id = i.ReadU8 (); |
| 219 uint8_t length = i.ReadU8 (); |
| 220 m_config. DeserializeInformation (i, length); |
| 221 if ((m_config.ElementId () != (WifiElementId) id) || (m_config.GetInformat
ionSize () != length)) |
| 222 { |
| 223 NS_FATAL_ERROR ("Broken frame: Element ID does not match IE itself!"); |
| 224 } |
| 225 i.Next (m_config.GetInformationSize ()); |
| 226 } |
| 227 else |
| 228 { |
| 229 m_reasonCode = i.ReadLsbtohU16 (); |
| 230 } |
| 231 return i.GetDistanceFrom (start); |
| 232 } |
| 233 bool |
| 234 operator== (const PeerLinkFrameStart & a, const PeerLinkFrameStart & b) |
| 235 { |
| 236 return ((a.m_subtype == b.m_subtype) && (a.m_capability == b.m_capability) &&
(a.m_aid == b.m_aid) |
| 237 && (a.m_meshId.IsEqual (b.m_meshId)) && (a.m_config == b.m_config) |
| 238 && (a.m_reasonCode == b.m_reasonCode)); |
| 239 } |
| 240 #ifdef RUN_SELF_TESTS |
| 241 /// Built-in self test for PeerLinkFrameStart |
| 242 struct PeerLinkFrameStartBist : public Test |
| 243 { |
| 244 PeerLinkFrameStartBist () : |
| 245 Test ("Mesh/802.11s/PeerLinkFrameStart") |
| 246 { |
| 247 } |
| 248 virtual bool |
| 249 RunTests (); |
| 250 }; |
| 251 /// Test instance |
| 252 static PeerLinkFrameStartBist g_PeerLinkFrameStartBist; |
| 253 |
| 254 bool |
| 255 PeerLinkFrameStartBist::RunTests () |
| 256 { |
| 257 bool result (true); |
| 258 { |
| 259 PeerLinkFrameStart a; |
| 260 PeerLinkFrameStart::PlinkFrameStartFields fields; |
| 261 fields.subtype = (uint8_t) (WifiMeshActionHeader::PEER_LINK_OPEN); |
| 262 fields.capability = 0; |
| 263 fields.aid = 101; |
| 264 fields.reasonCode = 12; |
| 265 fields.meshId = IeMeshId ("qwertyuiop"); |
| 266 a.SetPlinkFrameStart (fields); |
| 267 Ptr<Packet> packet = Create<Packet> (); |
| 268 packet->AddHeader (a); |
| 269 PeerLinkFrameStart b; |
| 270 b.SetPlinkFrameSubtype ((uint8_t) (WifiMeshActionHeader::PEER_LINK_OPEN)); |
| 271 packet->RemoveHeader (b); |
| 272 NS_TEST_ASSERT_EQUAL (a, b); |
| 273 } |
| 274 { |
| 275 PeerLinkFrameStart a; |
| 276 PeerLinkFrameStart::PlinkFrameStartFields fields; |
| 277 fields.subtype = (uint8_t) (WifiMeshActionHeader::PEER_LINK_CONFIRM); |
| 278 fields.capability = 0; |
| 279 fields.aid = 1234; |
| 280 fields.reasonCode = 12; |
| 281 fields.meshId = IeMeshId ("qwerty"); |
| 282 a.SetPlinkFrameStart (fields); |
| 283 Ptr<Packet> packet = Create<Packet> (); |
| 284 packet->AddHeader (a); |
| 285 PeerLinkFrameStart b; |
| 286 b.SetPlinkFrameSubtype ((uint8_t) (WifiMeshActionHeader::PEER_LINK_CONFIRM
)); |
| 287 packet->RemoveHeader (b); |
| 288 NS_TEST_ASSERT_EQUAL (a, b); |
| 289 } |
| 290 { |
| 291 PeerLinkFrameStart a; |
| 292 PeerLinkFrameStart::PlinkFrameStartFields fields; |
| 293 fields.subtype = (uint8_t) (WifiMeshActionHeader::PEER_LINK_CLOSE); |
| 294 fields.capability = 0; |
| 295 fields.aid = 10; |
| 296 fields.meshId = IeMeshId ("qqq"); |
| 297 fields.reasonCode = 12; |
| 298 a.SetPlinkFrameStart (fields); |
| 299 Ptr<Packet> packet = Create<Packet> (); |
| 300 packet->AddHeader (a); |
| 301 PeerLinkFrameStart b; |
| 302 b.SetPlinkFrameSubtype ((uint8_t) (WifiMeshActionHeader::PEER_LINK_CLOSE))
; |
| 303 packet->RemoveHeader (b); |
| 304 NS_TEST_ASSERT_EQUAL (a, b); |
| 305 } |
| 306 return result; |
| 307 } |
| 308 #endif |
| 309 } // namespace dot11s |
| 310 } //namespace ns3 |
| 311 |
OLD | NEW |