OLD | NEW |
(Empty) | |
| 1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ |
| 2 /* |
| 3 * Copyright (c) 2011 The Boeing Company |
| 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: |
| 19 * Tom Henderson <thomas.r.henderson@boeing.com> |
| 20 * Tommaso Pecorella <tommaso.pecorella@unifi.it> |
| 21 * Margherita Filippetti <morag87@gmail.com> |
| 22 */ |
| 23 #include "lr-wpan-tsch-net-device.h" |
| 24 #include "lr-wpan-phy.h" |
| 25 //#include "lr-wpan-csmaca.h" |
| 26 #include "lr-wpan-error-model.h" |
| 27 #include <ns3/abort.h> |
| 28 #include <ns3/node.h> |
| 29 #include <ns3/log.h> |
| 30 #include <ns3/spectrum-channel.h> |
| 31 #include <ns3/pointer.h> |
| 32 #include <ns3/boolean.h> |
| 33 #include <ns3/mobility-model.h> |
| 34 #include <ns3/packet.h> |
| 35 |
| 36 |
| 37 NS_LOG_COMPONENT_DEFINE ("LrWpanTschNetDevice"); |
| 38 |
| 39 namespace ns3 { |
| 40 |
| 41 NS_OBJECT_ENSURE_REGISTERED (LrWpanTschNetDevice); |
| 42 |
| 43 TypeId |
| 44 LrWpanTschNetDevice::GetTypeId (void) |
| 45 { |
| 46 static TypeId tid = TypeId ("ns3::LrWpanTschNetDevice") |
| 47 .SetParent<NetDevice> () |
| 48 .AddConstructor<LrWpanTschNetDevice> () |
| 49 .AddAttribute ("Channel", "The channel attached to this device", |
| 50 PointerValue (), |
| 51 MakePointerAccessor (&LrWpanTschNetDevice::DoGetChannel), |
| 52 MakePointerChecker<SpectrumChannel> ()) |
| 53 .AddAttribute ("Phy", "The PHY layer attached to this device.", |
| 54 PointerValue (), |
| 55 MakePointerAccessor (&LrWpanTschNetDevice::GetPhy, |
| 56 &LrWpanTschNetDevice::SetPhy), |
| 57 MakePointerChecker<LrWpanPhy> ()) |
| 58 .AddAttribute ("Mac", "The MAC layer attached to this device.", |
| 59 PointerValue (), |
| 60 MakePointerAccessor (&LrWpanTschNetDevice::GetMac, |
| 61 &LrWpanTschNetDevice::SetMac), |
| 62 MakePointerChecker<LrWpanTschMac> ()) |
| 63 .AddAttribute ("UseAcks", "Request acknowledgments for data frames.", |
| 64 BooleanValue (true), |
| 65 MakeBooleanAccessor (&LrWpanTschNetDevice::m_useAcks), |
| 66 MakeBooleanChecker ()) |
| 67 ; |
| 68 return tid; |
| 69 } |
| 70 |
| 71 LrWpanTschNetDevice::LrWpanTschNetDevice () |
| 72 : m_configComplete (false) |
| 73 { |
| 74 NS_LOG_FUNCTION (this); |
| 75 m_mac = CreateObject<LrWpanTschMac> (); |
| 76 m_phy = CreateObject<LrWpanPhy> (); |
| 77 //m_csmaca = CreateObject<LrWpanCsmaCa> (); |
| 78 CompleteConfig (); |
| 79 } |
| 80 |
| 81 LrWpanTschNetDevice::~LrWpanTschNetDevice () |
| 82 { |
| 83 NS_LOG_FUNCTION (this); |
| 84 } |
| 85 |
| 86 |
| 87 void |
| 88 LrWpanTschNetDevice::DoDispose (void) |
| 89 { |
| 90 NS_LOG_FUNCTION (this); |
| 91 m_mac->Dispose (); |
| 92 m_phy->Dispose (); |
| 93 //m_csmaca->Dispose (); |
| 94 m_phy = 0; |
| 95 m_mac = 0; |
| 96 //m_csmaca = 0; |
| 97 m_node = 0; |
| 98 // chain up. |
| 99 NetDevice::DoDispose (); |
| 100 |
| 101 } |
| 102 |
| 103 void |
| 104 LrWpanTschNetDevice::DoInitialize (void) |
| 105 { |
| 106 NS_LOG_FUNCTION (this); |
| 107 m_phy->Initialize (); |
| 108 m_mac->Initialize (); |
| 109 NetDevice::DoInitialize (); |
| 110 } |
| 111 |
| 112 |
| 113 void |
| 114 LrWpanTschNetDevice::CompleteConfig (void) |
| 115 { |
| 116 NS_LOG_FUNCTION (this); |
| 117 if (m_mac == 0 |
| 118 || m_phy == 0 |
| 119 || m_node == 0 |
| 120 || m_configComplete) |
| 121 { |
| 122 return; |
| 123 } |
| 124 |
| 125 m_mac->SetPhy (m_phy); |
| 126 //m_mac->SetCsmaCa (m_csmaca); |
| 127 m_mac->SetMcpsDataIndicationCallback (MakeCallback (&LrWpanTschNetDevice::Mcps
DataIndication, this)); |
| 128 //m_csmaca->SetMac (m_mac); |
| 129 |
| 130 m_phy->SetMobility (m_node->GetObject<MobilityModel> ()); |
| 131 Ptr<LrWpanErrorModel> model = CreateObject<LrWpanErrorModel> (); |
| 132 m_phy->SetErrorModel (model); |
| 133 m_phy->SetDevice (this); |
| 134 |
| 135 m_phy->SetPdDataIndicationCallback (MakeCallback (&LrWpanTschMac::PdDataIndica
tion, m_mac)); |
| 136 m_phy->SetPdDataConfirmCallback (MakeCallback (&LrWpanTschMac::PdDataConfirm,
m_mac)); |
| 137 m_phy->SetPlmeEdConfirmCallback (MakeCallback (&LrWpanTschMac::PlmeEdConfirm,
m_mac)); |
| 138 m_phy->SetPlmeGetAttributeConfirmCallback (MakeCallback (&LrWpanTschMac::PlmeG
etAttributeConfirm, m_mac)); |
| 139 m_phy->SetPlmeSetTRXStateConfirmCallback (MakeCallback (&LrWpanTschMac::PlmeSe
tTRXStateConfirm, m_mac)); |
| 140 m_phy->SetPlmeSetAttributeConfirmCallback (MakeCallback (&LrWpanTschMac::PlmeS
etAttributeConfirm, m_mac)); |
| 141 |
| 142 m_mac->SetMlmeSetSlotframeConfirmCallback(MakeCallback (&LrWpanTschNetDevice::
SlotframeConfirm,this)); |
| 143 m_mac->SetMlmeSetLinkConfirmCallback(MakeCallback (&LrWpanTschNetDevice::LinkC
onfirm,this)); |
| 144 m_mac->SetMlmeTschModeConfirmCallback(MakeCallback (&LrWpanTschNetDevice::Mode
Confirm,this)); |
| 145 |
| 146 //m_csmaca->SetLrWpanTschMacStateCallback (MakeCallback (&LrWpanTschMac::SetLr
WpanMacState, m_mac)); |
| 147 //m_phy->SetPlmeCcaConfirmCallback (MakeCallback (&LrWpanCsmaCa::PlmeCcaConfir
m, m_csmaca)); |
| 148 m_phy->SetPlmeCcaConfirmCallback (MakeCallback (&LrWpanTschMac::PlmeCcaConfirm
, m_mac)); |
| 149 m_configComplete = true; |
| 150 } |
| 151 |
| 152 void |
| 153 LrWpanTschNetDevice::SetMac (Ptr<LrWpanTschMac> mac) |
| 154 { |
| 155 NS_LOG_FUNCTION (this); |
| 156 m_mac = mac; |
| 157 CompleteConfig (); |
| 158 } |
| 159 |
| 160 void |
| 161 LrWpanTschNetDevice::SetPhy (Ptr<LrWpanPhy> phy) |
| 162 { |
| 163 NS_LOG_FUNCTION (this); |
| 164 m_phy = phy; |
| 165 CompleteConfig (); |
| 166 } |
| 167 /* |
| 168 void |
| 169 LrWpanTschNetDevice::SetCsmaCa (Ptr<LrWpanCsmaCa> csmaca) |
| 170 { |
| 171 NS_LOG_FUNCTION (this); |
| 172 m_csmaca = csmaca; |
| 173 CompleteConfig (); |
| 174 } |
| 175 */ |
| 176 void |
| 177 LrWpanTschNetDevice::SetChannel (Ptr<SpectrumChannel> channel) |
| 178 { |
| 179 NS_LOG_FUNCTION (this << channel); |
| 180 m_phy->SetChannel (channel); |
| 181 channel->AddRx (m_phy); |
| 182 CompleteConfig (); |
| 183 } |
| 184 |
| 185 Ptr<LrWpanTschMac> |
| 186 LrWpanTschNetDevice::GetMac (void) const |
| 187 { |
| 188 // NS_LOG_FUNCTION (this); |
| 189 return m_mac; |
| 190 } |
| 191 |
| 192 Ptr<LrWpanPhy> |
| 193 LrWpanTschNetDevice::GetPhy (void) const |
| 194 { |
| 195 NS_LOG_FUNCTION (this); |
| 196 return m_phy; |
| 197 } |
| 198 /* |
| 199 Ptr<LrWpanCsmaCa> |
| 200 LrWpanTschNetDevice::GetCsmaCa (void) const |
| 201 { |
| 202 NS_LOG_FUNCTION (this); |
| 203 return m_csmaca; |
| 204 } |
| 205 */ |
| 206 void |
| 207 LrWpanTschNetDevice::SetIfIndex (const uint32_t index) |
| 208 { |
| 209 NS_LOG_FUNCTION (this << index); |
| 210 m_ifIndex = index; |
| 211 } |
| 212 |
| 213 uint32_t |
| 214 LrWpanTschNetDevice::GetIfIndex (void) const |
| 215 { |
| 216 NS_LOG_FUNCTION (this); |
| 217 return m_ifIndex; |
| 218 } |
| 219 |
| 220 Ptr<Channel> |
| 221 LrWpanTschNetDevice::GetChannel (void) const |
| 222 { |
| 223 NS_LOG_FUNCTION (this); |
| 224 return m_phy->GetChannel (); |
| 225 } |
| 226 |
| 227 void |
| 228 LrWpanTschNetDevice::LinkUp (void) |
| 229 { |
| 230 NS_LOG_FUNCTION (this); |
| 231 m_linkUp = true; |
| 232 m_linkChanges (); |
| 233 } |
| 234 |
| 235 void |
| 236 LrWpanTschNetDevice::LinkDown (void) |
| 237 { |
| 238 NS_LOG_FUNCTION (this); |
| 239 m_linkUp = false; |
| 240 m_linkChanges (); |
| 241 } |
| 242 |
| 243 Ptr<SpectrumChannel> |
| 244 LrWpanTschNetDevice::DoGetChannel (void) const |
| 245 { |
| 246 NS_LOG_FUNCTION (this); |
| 247 return m_phy->GetChannel (); |
| 248 } |
| 249 |
| 250 void |
| 251 LrWpanTschNetDevice::SetAddress (Address address) |
| 252 { |
| 253 NS_LOG_FUNCTION (this); |
| 254 m_mac->SetShortAddress (Mac16Address::ConvertFrom (address)); |
| 255 } |
| 256 |
| 257 Address |
| 258 LrWpanTschNetDevice::GetAddress (void) const |
| 259 { |
| 260 NS_LOG_FUNCTION (this); |
| 261 return m_mac->GetShortAddress (); |
| 262 } |
| 263 |
| 264 bool |
| 265 LrWpanTschNetDevice::SetMtu (const uint16_t mtu) |
| 266 { |
| 267 NS_ABORT_MSG ("Unsupported"); |
| 268 return false; |
| 269 } |
| 270 |
| 271 uint16_t |
| 272 LrWpanTschNetDevice::GetMtu (void) const |
| 273 { |
| 274 NS_LOG_FUNCTION (this); |
| 275 // Maximum payload size is: max psdu - frame control - seqno - addressing - se
curity - fcs |
| 276 // = 128 - 2 - 1 - (2+2+0+0) - 0
- 2 |
| 277 // = 118 |
| 278 // assuming no security and addressing with only 16 bit addresses without pan
id compression. |
| 279 return 118; |
| 280 } |
| 281 |
| 282 bool |
| 283 LrWpanTschNetDevice::IsLinkUp (void) const |
| 284 { |
| 285 NS_LOG_FUNCTION (this); |
| 286 return m_phy != 0 && m_linkUp; |
| 287 } |
| 288 |
| 289 void |
| 290 LrWpanTschNetDevice::AddLinkChangeCallback (Callback<void> callback) |
| 291 { |
| 292 NS_LOG_FUNCTION (this); |
| 293 m_linkChanges.ConnectWithoutContext (callback); |
| 294 } |
| 295 |
| 296 bool |
| 297 LrWpanTschNetDevice::IsBroadcast (void) const |
| 298 { |
| 299 NS_LOG_FUNCTION (this); |
| 300 return true; |
| 301 } |
| 302 |
| 303 Address |
| 304 LrWpanTschNetDevice::GetBroadcast (void) const |
| 305 { |
| 306 NS_LOG_FUNCTION (this); |
| 307 return Mac16Address ("ff:ff"); |
| 308 } |
| 309 |
| 310 bool |
| 311 LrWpanTschNetDevice::IsMulticast (void) const |
| 312 { |
| 313 NS_LOG_FUNCTION (this); |
| 314 return true; |
| 315 } |
| 316 |
| 317 Address |
| 318 LrWpanTschNetDevice::GetMulticast (Ipv4Address multicastGroup) const |
| 319 { |
| 320 NS_ABORT_MSG ("Unsupported"); |
| 321 return Address (); |
| 322 } |
| 323 |
| 324 Address |
| 325 LrWpanTschNetDevice::GetMulticast (Ipv6Address addr) const |
| 326 { |
| 327 NS_LOG_FUNCTION (this); |
| 328 /* Implementation based on RFC 4944 Section 9. |
| 329 * An IPv6 packet with a multicast destination address (DST), |
| 330 * consisting of the sixteen octets DST[1] through DST[16], is |
| 331 * transmitted to the following 802.15.4 16-bit multicast address: |
| 332 * 0 1 |
| 333 * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 |
| 334 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
| 335 * |1 0 0|DST[15]* | DST[16] | |
| 336 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
| 337 * Here, DST[15]* refers to the last 5 bits in octet DST[15], that is, |
| 338 * bits 3-7 within DST[15]. The initial 3-bit pattern of "100" follows |
| 339 * the 16-bit address format for multicast addresses (Section 12). */ |
| 340 |
| 341 // \todo re-add this once Lr-Wpan will be able to accept these multicast addre
sses |
| 342 // uint8_t buf[16]; |
| 343 // uint8_t buf2[2]; |
| 344 // |
| 345 // addr.GetBytes(buf); |
| 346 // |
| 347 // buf2[0] = 0x80 | (buf[14] & 0x1F); |
| 348 // buf2[1] = buf[15]; |
| 349 // |
| 350 // Mac16Address newaddr = Mac16Address(); |
| 351 // newaddr.CopyFrom(buf2); |
| 352 // return newaddr; |
| 353 |
| 354 return Mac16Address ("ff:ff"); |
| 355 } |
| 356 |
| 357 bool |
| 358 LrWpanTschNetDevice::IsBridge (void) const |
| 359 { |
| 360 NS_LOG_FUNCTION (this); |
| 361 return false; |
| 362 } |
| 363 |
| 364 bool |
| 365 LrWpanTschNetDevice::IsPointToPoint (void) const |
| 366 { |
| 367 NS_LOG_FUNCTION (this); |
| 368 return false; |
| 369 } |
| 370 |
| 371 bool |
| 372 LrWpanTschNetDevice::Send (Ptr<Packet> packet, const Address& dest, uint16_t pro
tocolNumber) |
| 373 { |
| 374 // This method basically assumes an 802.3-compliant device, but a raw |
| 375 // 802.15.4 device does not have an ethertype, and requires specific |
| 376 // McpsDataRequest parameters. |
| 377 // For further study: how to support these methods somehow, such as |
| 378 // inventing a fake ethertype and packet tag for McpsDataRequest |
| 379 NS_LOG_FUNCTION (this << packet << dest << protocolNumber); |
| 380 |
| 381 if (packet->GetSize () > GetMtu ()) |
| 382 { |
| 383 NS_LOG_ERROR ("Fragmentation is needed for this packet, drop the packet ")
; |
| 384 return false; |
| 385 } |
| 386 |
| 387 TschMcpsDataRequestParams m_mcpsDataRequestParams; |
| 388 LrWpanFrameControlOptions frmcontrol; |
| 389 m_mcpsDataRequestParams.m_frameControlOptions = frmcontrol; |
| 390 m_mcpsDataRequestParams.m_dstAddr = Mac16Address::ConvertFrom (dest); |
| 391 m_mcpsDataRequestParams.m_dstAddrMode = SHORT_ADDR; |
| 392 m_mcpsDataRequestParams.m_srcAddrMode = NO_PANID_ADDR; |
| 393 |
| 394 if (Mac16Address::ConvertFrom (dest) == Mac16Address("ff:ff")) |
| 395 { |
| 396 m_mcpsDataRequestParams.m_ACK_TX = false; |
| 397 } |
| 398 else |
| 399 { |
| 400 m_mcpsDataRequestParams.m_ACK_TX = m_useAcks; |
| 401 } |
| 402 |
| 403 m_mcpsDataRequestParams.m_msduHandle = 0; |
| 404 m_mcpsDataRequestParams.m_dstPanId = m_mac->GetPanId (); |
| 405 m_mac->McpsDataRequest (m_mcpsDataRequestParams, packet); |
| 406 return true; |
| 407 } |
| 408 |
| 409 bool |
| 410 LrWpanTschNetDevice::Send (Ptr<Packet> packet, const Address& dest, bool use_ack
, uint16_t protocolNumber) |
| 411 { |
| 412 // This method basically assumes an 802.3-compliant device, but a raw |
| 413 // 802.15.4 device does not have an ethertype, and requires specific |
| 414 // McpsDataRequest parameters. |
| 415 // For further study: how to support these methods somehow, such as |
| 416 // inventing a fake ethertype and packet tag for McpsDataRequest |
| 417 NS_LOG_FUNCTION (this << packet << dest << protocolNumber); |
| 418 |
| 419 if (packet->GetSize () > GetMtu ()) |
| 420 { |
| 421 NS_LOG_ERROR ("Fragmentation is needed for this packet, drop the packet ")
; |
| 422 return false; |
| 423 } |
| 424 |
| 425 TschMcpsDataRequestParams m_mcpsDataRequestParams; |
| 426 LrWpanFrameControlOptions frmcontrol; |
| 427 m_mcpsDataRequestParams.m_frameControlOptions = frmcontrol; |
| 428 m_mcpsDataRequestParams.m_dstAddr = Mac16Address::ConvertFrom (dest); |
| 429 m_mcpsDataRequestParams.m_dstAddrMode = SHORT_ADDR; |
| 430 m_mcpsDataRequestParams.m_srcAddrMode = NO_PANID_ADDR; |
| 431 m_mcpsDataRequestParams.m_ACK_TX = use_ack; |
| 432 m_mcpsDataRequestParams.m_msduHandle = 0; |
| 433 m_mcpsDataRequestParams.m_dstPanId = m_mac->GetPanId (); |
| 434 m_mac->McpsDataRequest (m_mcpsDataRequestParams, packet); |
| 435 return true; |
| 436 } |
| 437 bool |
| 438 LrWpanTschNetDevice::SendFrom (Ptr<Packet> packet, const Address& source, const
Address& dest, uint16_t protocolNumber) |
| 439 { |
| 440 NS_ABORT_MSG ("Unsupported"); |
| 441 // TODO: To support SendFrom, the MACs McpsDataRequest has to use the provided
source address, instead of to local one. |
| 442 return false; |
| 443 } |
| 444 |
| 445 Ptr<Node> |
| 446 LrWpanTschNetDevice::GetNode (void) const |
| 447 { |
| 448 NS_LOG_FUNCTION (this); |
| 449 return m_node; |
| 450 } |
| 451 |
| 452 void |
| 453 LrWpanTschNetDevice::SetNode (Ptr<Node> node) |
| 454 { |
| 455 NS_LOG_FUNCTION (this); |
| 456 m_node = node; |
| 457 CompleteConfig (); |
| 458 } |
| 459 |
| 460 bool |
| 461 LrWpanTschNetDevice::NeedsArp (void) const |
| 462 { |
| 463 NS_LOG_FUNCTION (this); |
| 464 return true; |
| 465 } |
| 466 |
| 467 void |
| 468 LrWpanTschNetDevice::SetReceiveCallback (ReceiveCallback cb) |
| 469 { |
| 470 NS_LOG_FUNCTION (this); |
| 471 m_receiveCallback = cb; |
| 472 } |
| 473 |
| 474 void |
| 475 LrWpanTschNetDevice::SetPromiscReceiveCallback (PromiscReceiveCallback cb) |
| 476 { |
| 477 // This method basically assumes an 802.3-compliant device, but a raw |
| 478 // 802.15.4 device does not have an ethertype, and requires specific |
| 479 // McpsDataIndication parameters. |
| 480 // For further study: how to support these methods somehow, such as |
| 481 // inventing a fake ethertype and packet tag for McpsDataRequest |
| 482 NS_LOG_WARN ("Unsupported; use LrWpan MAC APIs instead"); |
| 483 } |
| 484 |
| 485 void |
| 486 LrWpanTschNetDevice::McpsDataIndication (McpsDataIndicationParams params, Ptr<Pa
cket> pkt) |
| 487 { |
| 488 NS_LOG_FUNCTION (this); |
| 489 // TODO: Use the PromiscReceiveCallback if the MAC is in promiscuous mode. |
| 490 m_receiveCallback (this, pkt, 0, params.m_srcAddr); |
| 491 } |
| 492 |
| 493 bool |
| 494 LrWpanTschNetDevice::SupportsSendFrom (void) const |
| 495 { |
| 496 NS_LOG_FUNCTION_NOARGS (); |
| 497 return false; |
| 498 } |
| 499 |
| 500 int64_t |
| 501 LrWpanTschNetDevice::AssignStreams (int64_t stream) |
| 502 { |
| 503 NS_LOG_FUNCTION (stream); |
| 504 int64_t streamIndex = stream; |
| 505 //streamIndex += m_csmaca->AssignStreams (stream); |
| 506 streamIndex += m_phy->AssignStreams (stream); |
| 507 NS_LOG_DEBUG ("Number of assigned RV streams: " << (streamIndex - stream)); |
| 508 return (streamIndex - stream); |
| 509 } |
| 510 |
| 511 /***** TSCH ************/ |
| 512 void |
| 513 LrWpanTschNetDevice::SlotframeConfirm (MlmeSetSlotframeConfirmParams params) |
| 514 { |
| 515 NS_LOG_FUNCTION (this); |
| 516 } |
| 517 |
| 518 void |
| 519 LrWpanTschNetDevice::LinkConfirm (MlmeSetLinkConfirmParams params) |
| 520 { |
| 521 NS_LOG_FUNCTION (this); |
| 522 } |
| 523 |
| 524 void |
| 525 LrWpanTschNetDevice::ModeConfirm (MlmeTschModeConfirmParams params) |
| 526 { |
| 527 NS_LOG_FUNCTION (this); |
| 528 } |
| 529 } // namespace ns3 |
OLD | NEW |