OLD | NEW |
(Empty) | |
| 1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ |
| 2 /* |
| 3 * Copyright (c) 2010 CTTC |
| 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: Nicola Baldo <nbaldo@cttc.es> |
| 19 */ |
| 20 |
| 21 #include "ns3/log.h" |
| 22 #include "ns3/queue.h" |
| 23 #include "ns3/simulator.h" |
| 24 #include "ns3/enum.h" |
| 25 #include "ns3/boolean.h" |
| 26 #include "ns3/uinteger.h" |
| 27 #include "ns3/pointer.h" |
| 28 #include "ns3/channel.h" |
| 29 #include "ns3/trace-source-accessor.h" |
| 30 #include "aloha-noack-mac-header.h" |
| 31 #include "aloha-noack-net-device.h" |
| 32 #include "ns3/llc-snap-header.h" |
| 33 |
| 34 NS_LOG_COMPONENT_DEFINE ("AlohaNoackNetDevice"); |
| 35 |
| 36 |
| 37 namespace ns3 { |
| 38 |
| 39 |
| 40 std::ostream& operator<< (std::ostream& os, AlohaNoackNetDevice::State state) |
| 41 { |
| 42 switch (state) |
| 43 { |
| 44 case AlohaNoackNetDevice::IDLE: |
| 45 os << "IDLE" ; |
| 46 break; |
| 47 case AlohaNoackNetDevice::TX: |
| 48 os << "TX" ; |
| 49 break; |
| 50 case AlohaNoackNetDevice::RX: |
| 51 os << "RX" ; |
| 52 break; |
| 53 } |
| 54 return os; |
| 55 } |
| 56 |
| 57 |
| 58 NS_OBJECT_ENSURE_REGISTERED (AlohaNoackNetDevice); |
| 59 |
| 60 TypeId |
| 61 AlohaNoackNetDevice::GetTypeId (void) |
| 62 { |
| 63 static TypeId tid = TypeId ("ns3::AlohaNoackNetDevice") |
| 64 .SetParent<NetDevice> () |
| 65 .AddConstructor<AlohaNoackNetDevice> () |
| 66 .AddAttribute ("Address", |
| 67 "The MAC address of this device.", |
| 68 Mac48AddressValue (Mac48Address ("12:34:56:78:90:12")), |
| 69 MakeMac48AddressAccessor (&AlohaNoackNetDevice::m_address), |
| 70 MakeMac48AddressChecker ()) |
| 71 .AddAttribute ("Queue", |
| 72 "packets being transmitted get queued here", |
| 73 PointerValue (), |
| 74 MakePointerAccessor (&AlohaNoackNetDevice::m_queue), |
| 75 MakePointerChecker<Queue> ()) |
| 76 .AddAttribute ("Phy", "The PHY layer attached to this device.", |
| 77 PointerValue (), |
| 78 MakePointerAccessor (&AlohaNoackNetDevice::GetPhy, |
| 79 &AlohaNoackNetDevice::SetPhy), |
| 80 MakePointerChecker<Object> ()) |
| 81 .AddTraceSource ("MacTx", |
| 82 "Trace source indicating a packet has arrived for transmiss
ion by this device", |
| 83 MakeTraceSourceAccessor (&AlohaNoackNetDevice::m_macTxTrace
)) |
| 84 .AddTraceSource ("MacTxDrop", |
| 85 "Trace source indicating a packet has been dropped by the d
evice before transmission", |
| 86 MakeTraceSourceAccessor (&AlohaNoackNetDevice::m_macTxDropT
race)) |
| 87 .AddTraceSource ("MacPromiscRx", |
| 88 "A packet has been received by this device, has been passed
up from the physical layer " |
| 89 "and is being forwarded up the local protocol stack. This
is a promiscuous trace,", |
| 90 MakeTraceSourceAccessor (&AlohaNoackNetDevice::m_macPromisc
RxTrace)) |
| 91 .AddTraceSource ("MacRx", |
| 92 "A packet has been received by this device, has been passed
up from the physical layer " |
| 93 "and is being forwarded up the local protocol stack. This
is a non-promiscuous trace,", |
| 94 MakeTraceSourceAccessor (&AlohaNoackNetDevice::m_macRxTrace
)) |
| 95 ; |
| 96 return tid; |
| 97 } |
| 98 |
| 99 AlohaNoackNetDevice::AlohaNoackNetDevice () |
| 100 : m_state (IDLE) |
| 101 { |
| 102 NS_LOG_FUNCTION (this); |
| 103 } |
| 104 |
| 105 AlohaNoackNetDevice::~AlohaNoackNetDevice () |
| 106 { |
| 107 NS_LOG_FUNCTION (this); |
| 108 m_queue = 0; |
| 109 } |
| 110 |
| 111 void |
| 112 AlohaNoackNetDevice::DoDispose () |
| 113 { |
| 114 NS_LOG_FUNCTION (this); |
| 115 m_node = 0; |
| 116 NetDevice::DoDispose (); |
| 117 } |
| 118 |
| 119 |
| 120 void |
| 121 AlohaNoackNetDevice::SetIfIndex (const uint32_t index) |
| 122 { |
| 123 NS_LOG_FUNCTION (index); |
| 124 m_ifIndex = index; |
| 125 } |
| 126 |
| 127 uint32_t |
| 128 AlohaNoackNetDevice::GetIfIndex (void) const |
| 129 { |
| 130 NS_LOG_FUNCTION (this); |
| 131 return m_ifIndex; |
| 132 } |
| 133 |
| 134 bool |
| 135 AlohaNoackNetDevice::SetMtu (uint16_t mtu) |
| 136 { |
| 137 NS_LOG_FUNCTION (mtu); |
| 138 m_mtu = mtu; |
| 139 return true; |
| 140 } |
| 141 |
| 142 uint16_t |
| 143 AlohaNoackNetDevice::GetMtu (void) const |
| 144 { |
| 145 NS_LOG_FUNCTION (this); |
| 146 |
| 147 // the following looks weird but works... copied from wifi-net-device.cc |
| 148 if (m_mtu == 0) |
| 149 { |
| 150 NS_LOG_LOGIC ("Mtu=" << m_mtu); |
| 151 m_mtu = 0xffff; |
| 152 NS_LOG_LOGIC ("Mtu=" << m_mtu); |
| 153 } |
| 154 |
| 155 return m_mtu; |
| 156 } |
| 157 |
| 158 |
| 159 void |
| 160 AlohaNoackNetDevice::SetQueue (Ptr<Queue> q) |
| 161 { |
| 162 NS_LOG_FUNCTION (q); |
| 163 m_queue = q; |
| 164 } |
| 165 |
| 166 |
| 167 void |
| 168 AlohaNoackNetDevice::SetAddress (Address address) |
| 169 { |
| 170 NS_LOG_FUNCTION (this); |
| 171 m_address = Mac48Address::ConvertFrom (address); |
| 172 } |
| 173 |
| 174 Address |
| 175 AlohaNoackNetDevice::GetAddress (void) const |
| 176 { |
| 177 NS_LOG_FUNCTION (this); |
| 178 return m_address; |
| 179 } |
| 180 |
| 181 bool |
| 182 AlohaNoackNetDevice::IsBroadcast (void) const |
| 183 { |
| 184 NS_LOG_FUNCTION (this); |
| 185 return true; |
| 186 } |
| 187 |
| 188 Address |
| 189 AlohaNoackNetDevice::GetBroadcast (void) const |
| 190 { |
| 191 NS_LOG_FUNCTION (this); |
| 192 return Mac48Address ("ff:ff:ff:ff:ff:ff"); |
| 193 } |
| 194 |
| 195 bool |
| 196 AlohaNoackNetDevice::IsMulticast (void) const |
| 197 { |
| 198 NS_LOG_FUNCTION (this); |
| 199 return true; |
| 200 } |
| 201 |
| 202 Address |
| 203 AlohaNoackNetDevice::GetMulticast (Ipv4Address addr) const |
| 204 { |
| 205 NS_LOG_FUNCTION (addr); |
| 206 Mac48Address ad = Mac48Address::GetMulticast (addr); |
| 207 return ad; |
| 208 } |
| 209 |
| 210 |
| 211 Address AlohaNoackNetDevice::GetMulticast (Ipv6Address addr) const |
| 212 { |
| 213 NS_LOG_FUNCTION (addr); |
| 214 Mac48Address ad = Mac48Address::GetMulticast (addr); |
| 215 return ad; |
| 216 } |
| 217 |
| 218 |
| 219 bool |
| 220 AlohaNoackNetDevice::IsPointToPoint (void) const |
| 221 { |
| 222 NS_LOG_FUNCTION (this); |
| 223 return false; |
| 224 } |
| 225 |
| 226 bool |
| 227 AlohaNoackNetDevice::IsBridge (void) const |
| 228 { |
| 229 NS_LOG_FUNCTION (this); |
| 230 return false; |
| 231 } |
| 232 |
| 233 |
| 234 Ptr<Node> |
| 235 AlohaNoackNetDevice::GetNode (void) const |
| 236 { |
| 237 NS_LOG_FUNCTION (this); |
| 238 return m_node; |
| 239 } |
| 240 |
| 241 void |
| 242 AlohaNoackNetDevice::SetNode (Ptr<Node> node) |
| 243 { |
| 244 NS_LOG_FUNCTION (node); |
| 245 |
| 246 m_node = node; |
| 247 } |
| 248 |
| 249 void |
| 250 AlohaNoackNetDevice::SetPhy (Ptr<Object> phy) |
| 251 { |
| 252 NS_LOG_FUNCTION (this << phy); |
| 253 m_phy = phy; |
| 254 } |
| 255 |
| 256 |
| 257 Ptr<Object> |
| 258 AlohaNoackNetDevice::GetPhy () const |
| 259 { |
| 260 NS_LOG_FUNCTION (this); |
| 261 return m_phy; |
| 262 } |
| 263 |
| 264 |
| 265 |
| 266 Ptr<Channel> |
| 267 AlohaNoackNetDevice::GetChannel (void) const |
| 268 { |
| 269 NS_LOG_FUNCTION (this); |
| 270 return m_channel; |
| 271 } |
| 272 |
| 273 |
| 274 bool |
| 275 AlohaNoackNetDevice::NeedsArp (void) const |
| 276 { |
| 277 NS_LOG_FUNCTION (this); |
| 278 return true; |
| 279 } |
| 280 |
| 281 bool |
| 282 AlohaNoackNetDevice::IsLinkUp (void) const |
| 283 { |
| 284 NS_LOG_FUNCTION (this); |
| 285 return m_linkUp; |
| 286 } |
| 287 |
| 288 void |
| 289 AlohaNoackNetDevice::AddLinkChangeCallback (Callback<void> callback) |
| 290 { |
| 291 NS_LOG_FUNCTION (&callback); |
| 292 m_linkChangeCallbacks.ConnectWithoutContext (callback); |
| 293 } |
| 294 |
| 295 void |
| 296 AlohaNoackNetDevice::SetReceiveCallback (NetDevice::ReceiveCallback cb) |
| 297 { |
| 298 NS_LOG_FUNCTION (&cb); |
| 299 m_rxCallback = cb; |
| 300 } |
| 301 |
| 302 void |
| 303 AlohaNoackNetDevice::SetPromiscReceiveCallback (NetDevice::PromiscReceiveCallbac
k cb) |
| 304 { |
| 305 NS_LOG_FUNCTION (&cb); |
| 306 m_promiscRxCallback = cb; |
| 307 } |
| 308 |
| 309 bool |
| 310 AlohaNoackNetDevice::SupportsSendFrom () const |
| 311 { |
| 312 NS_LOG_FUNCTION (this); |
| 313 return true; |
| 314 } |
| 315 |
| 316 |
| 317 bool |
| 318 AlohaNoackNetDevice::Send (Ptr<Packet> packet,const Address& dest, uint16_t prot
ocolNumber) |
| 319 { |
| 320 NS_LOG_FUNCTION (packet << dest << protocolNumber); |
| 321 return SendFrom (packet, m_address, dest, protocolNumber); |
| 322 } |
| 323 |
| 324 bool |
| 325 AlohaNoackNetDevice::SendFrom (Ptr<Packet> packet, const Address& src, const Add
ress& dest, uint16_t protocolNumber) |
| 326 { |
| 327 NS_LOG_FUNCTION (packet << src << dest << protocolNumber); |
| 328 |
| 329 LlcSnapHeader llc; |
| 330 llc.SetType (protocolNumber); |
| 331 packet->AddHeader (llc); |
| 332 |
| 333 AlohaNoackMacHeader header; |
| 334 header.SetSource (Mac48Address::ConvertFrom (src)); |
| 335 header.SetDestination (Mac48Address::ConvertFrom (dest)); |
| 336 packet->AddHeader (header); |
| 337 |
| 338 m_macTxTrace (packet); |
| 339 |
| 340 |
| 341 |
| 342 // |
| 343 // If the device is idle, transmission starts immediately. Otherwise, |
| 344 // the transmission will be started by NotifyTransmissionEnd |
| 345 // |
| 346 NS_LOG_LOGIC (this << " state=" << m_state); |
| 347 if (m_state == IDLE) |
| 348 { |
| 349 if (m_queue->IsEmpty ()) |
| 350 { |
| 351 NS_LOG_LOGIC ("new packet is head of queue, starting TX immediately"); |
| 352 m_currentPkt = packet; |
| 353 StartTransmission (); |
| 354 } |
| 355 else |
| 356 { |
| 357 NS_LOG_LOGIC ("enqueueing new packet"); |
| 358 if (m_queue->Enqueue (packet) == false) |
| 359 { |
| 360 m_macTxDropTrace (packet); |
| 361 return false; |
| 362 } |
| 363 NS_LOG_LOGIC ("transmitting head-of-queue packet"); |
| 364 m_currentPkt = m_queue->Dequeue (); |
| 365 NS_ASSERT (m_currentPkt != 0); |
| 366 StartTransmission (); |
| 367 } |
| 368 } |
| 369 else |
| 370 { |
| 371 NS_LOG_LOGIC ("deferring TX, enqueueing new packet"); |
| 372 NS_ASSERT (m_queue); |
| 373 if (m_queue->Enqueue (packet) == false) |
| 374 { |
| 375 m_macTxDropTrace (packet); |
| 376 return false; |
| 377 } |
| 378 } |
| 379 return true; |
| 380 } |
| 381 |
| 382 void |
| 383 AlohaNoackNetDevice::SetPhyMacTxStartCallback (PhyMacTxStartCallback c) |
| 384 { |
| 385 NS_LOG_FUNCTION (this); |
| 386 m_phyMacTxStartCallback = c; |
| 387 } |
| 388 |
| 389 void |
| 390 AlohaNoackNetDevice::StartTransmission () |
| 391 { |
| 392 NS_LOG_FUNCTION (this); |
| 393 |
| 394 NS_ASSERT (m_currentPkt != 0); |
| 395 NS_ASSERT (m_state == IDLE); |
| 396 |
| 397 if (m_phyMacTxStartCallback (m_currentPkt)) |
| 398 { |
| 399 NS_LOG_WARN ("PHY refused to start TX"); |
| 400 } |
| 401 else |
| 402 { |
| 403 m_state = TX; |
| 404 } |
| 405 } |
| 406 |
| 407 |
| 408 |
| 409 void |
| 410 AlohaNoackNetDevice::NotifyTransmissionEnd (Ptr<const Packet>) |
| 411 { |
| 412 NS_LOG_FUNCTION (this); |
| 413 NS_ASSERT_MSG (m_state == TX, "TX end notified while state != TX"); |
| 414 m_state = IDLE; |
| 415 NS_ASSERT (m_queue); |
| 416 if (m_queue->IsEmpty () == false) |
| 417 { |
| 418 m_currentPkt = m_queue->Dequeue (); |
| 419 NS_ASSERT (m_currentPkt); |
| 420 Simulator::ScheduleNow (&AlohaNoackNetDevice::StartTransmission, this); |
| 421 } |
| 422 } |
| 423 |
| 424 |
| 425 void |
| 426 AlohaNoackNetDevice::NotifyReceptionStart () |
| 427 { |
| 428 NS_LOG_FUNCTION (this); |
| 429 } |
| 430 |
| 431 |
| 432 |
| 433 void |
| 434 AlohaNoackNetDevice::NotifyReceptionEndError () |
| 435 { |
| 436 NS_LOG_FUNCTION (this); |
| 437 } |
| 438 |
| 439 |
| 440 |
| 441 |
| 442 |
| 443 void |
| 444 AlohaNoackNetDevice::NotifyReceptionEndOk (Ptr<Packet> packet) |
| 445 { |
| 446 NS_LOG_FUNCTION (this << packet); |
| 447 AlohaNoackMacHeader header; |
| 448 packet->RemoveHeader (header); |
| 449 NS_LOG_LOGIC ("packet " << header.GetSource () << " --> " << header.GetDestina
tion () << " (here: " << m_address << ")"); |
| 450 |
| 451 LlcSnapHeader llc; |
| 452 packet->RemoveHeader (llc); |
| 453 |
| 454 PacketType packetType; |
| 455 if (header.GetDestination ().IsBroadcast ()) |
| 456 { |
| 457 packetType = PACKET_BROADCAST; |
| 458 } |
| 459 else if (header.GetDestination ().IsGroup ()) |
| 460 { |
| 461 packetType = PACKET_MULTICAST; |
| 462 } |
| 463 else if (header.GetDestination () == m_address) |
| 464 { |
| 465 packetType = PACKET_HOST; |
| 466 } |
| 467 else |
| 468 { |
| 469 packetType = PACKET_OTHERHOST; |
| 470 } |
| 471 |
| 472 NS_LOG_LOGIC ("packet type = " << packetType); |
| 473 |
| 474 if (!m_promiscRxCallback.IsNull ()) |
| 475 { |
| 476 m_promiscRxCallback (this, packet->Copy (), llc.GetType (), header.GetSour
ce (), header.GetDestination (), packetType); |
| 477 } |
| 478 |
| 479 if (packetType != PACKET_OTHERHOST) |
| 480 { |
| 481 m_rxCallback (this, packet, llc.GetType (), header.GetSource () ); |
| 482 } |
| 483 } |
| 484 |
| 485 |
| 486 |
| 487 } // namespace ns3 |
OLD | NEW |