|
|
| 189 |
NS_LOG_FUNCTION (this); |
189 |
NS_LOG_FUNCTION (this); |
| 190 |
m_txMachineState = READY; |
190 |
m_txMachineState = READY; |
| 191 |
m_tInterframeGap = Seconds (0); |
191 |
m_tInterframeGap = Seconds (0); |
| 192 |
m_channel = 0; |
192 |
m_channel = 0; |
|
|
193 |
m_queue = 0; |
| 194 |
m_queueInterface = 0; |
| 193 |
|
195 |
|
| 194 |
// |
196 |
// |
| 195 |
// We would like to let the attribute system take care of initializing the |
197 |
// We would like to let the attribute system take care of initializing the |
|
|
| 396 |
p->AddTrailer (trailer); |
398 |
p->AddTrailer (trailer); |
| 397 |
} |
399 |
} |
| 398 |
|
400 |
|
|
|
401 |
void |
| 402 |
CsmaNetDevice::NotifyNewAggregate (void) |
| 403 |
{ |
| 404 |
NS_LOG_FUNCTION (this); |
| 405 |
|
| 406 |
if (m_queueInterface == 0) |
| 407 |
{ |
| 408 |
Ptr<NetDeviceQueueInterface> ndqi = this->GetObject<NetDeviceQueueInterface> (); |
| 409 |
if (ndqi != 0) |
| 410 |
{ |
| 411 |
m_queueInterface = ndqi; |
| 412 |
} |
| 413 |
} |
| 414 |
NetDevice::NotifyNewAggregate (); |
| 415 |
} |
| 416 |
|
| 399 |
#if 0 |
417 |
#if 0 |
| 400 |
bool |
418 |
bool |
| 401 |
CsmaNetDevice::ProcessHeader (Ptr<Packet> p, uint16_t & param) |
419 |
CsmaNetDevice::ProcessHeader (Ptr<Packet> p, uint16_t & param) |
|
|
| 554 |
m_txMachineState = READY; |
572 |
m_txMachineState = READY; |
| 555 |
|
573 |
|
| 556 |
// |
574 |
// |
|
|
575 |
// Check for valid queue interface configuration. |
| 576 |
// |
| 577 |
Ptr<NetDeviceQueue> txq; |
| 578 |
if (m_queueInterface) |
| 579 |
{ |
| 580 |
txq = m_queueInterface->GetTxQueue (0); |
| 581 |
} |
| 582 |
|
| 583 |
// |
| 557 |
// If there is another packet on the input queue, we need to start trying to |
584 |
// If there is another packet on the input queue, we need to start trying to |
| 558 |
// get that out. If the queue is empty we just wait until someone puts one |
585 |
// get that out. If the queue is empty we just wait until someone puts one |
| 559 |
// in. |
586 |
// in. |
| 560 |
// |
587 |
// |
| 561 |
if (m_queue->IsEmpty ()) |
588 |
if (m_queue->IsEmpty ()) |
| 562 |
{ |
589 |
{ |
|
|
590 |
NS_LOG_LOGIC ("No pending packets in device queue for transmission."); |
| 591 |
if (txq) |
| 592 |
{ |
| 593 |
NS_LOG_DEBUG ("The device queue is being woken up."); |
| 594 |
txq->Wake (); |
| 595 |
} |
| 563 |
return; |
596 |
return; |
| 564 |
} |
597 |
} |
| 565 |
else |
598 |
else |
| 566 |
{ |
599 |
{ |
| 567 |
Ptr<QueueItem> item = m_queue->Dequeue (); |
600 |
Ptr<QueueItem> item = m_queue->Dequeue (); |
| 568 |
NS_ASSERT_MSG (item != 0, "CsmaNetDevice::TransmitAbort(): IsEmpty false but no Packet on queue?"); |
601 |
NS_ASSERT_MSG (item != 0, "CsmaNetDevice::TransmitAbort(): IsEmpty false but no Packet on queue?"); |
|
|
602 |
|
| 603 |
// Got another packet off of the queue, so start the transmit process |
| 604 |
// again. If the queue was stopped, start it again if there is room for |
| 605 |
// another packet. Note that we cannot wake the upper layers because |
| 606 |
// otherwise a packet is sent to the device while the machine state is |
| 607 |
// busy, thus causing the assert in TransmitStart to fail. |
| 608 |
if (txq && txq->IsStopped ()) |
| 609 |
{ |
| 610 |
if ((m_queue->GetMode () == Queue::QUEUE_MODE_PACKETS && |
| 611 |
m_queue->GetNPackets () < m_queue->GetMaxPackets ()) || |
| 612 |
(m_queue->GetMode () == Queue::QUEUE_MODE_BYTES && |
| 613 |
m_queue->GetNBytes () + m_mtu <= m_queue->GetMaxBytes ())) |
| 614 |
{ |
| 615 |
NS_LOG_DEBUG ("The device queue is being started."); |
| 616 |
txq->Start (); |
| 617 |
} |
| 618 |
} |
| 619 |
|
| 569 |
m_currentPkt = item->GetPacket (); |
620 |
m_currentPkt = item->GetPacket (); |
| 570 |
m_snifferTrace (m_currentPkt); |
621 |
m_snifferTrace (m_currentPkt); |
| 571 |
m_promiscSnifferTrace (m_currentPkt); |
622 |
m_promiscSnifferTrace (m_currentPkt); |
| 572 |
TransmitStart (); |
623 |
TransmitStart (); |
|
|
624 |
|
| 625 |
if (txq) |
| 626 |
{ |
| 627 |
// Inform BQL about a the packet being transmitted |
| 628 |
txq->NotifyQueuedBytes (m_currentPkt->GetSize ()); |
| 629 |
} |
| 630 |
|
| 573 |
} |
631 |
} |
| 574 |
} |
632 |
} |
| 575 |
|
633 |
|
|
|
| 625 |
NS_ASSERT_MSG (m_currentPkt == 0, "CsmaNetDevice::TransmitReadyEvent(): m_currentPkt nonzero"); |
683 |
NS_ASSERT_MSG (m_currentPkt == 0, "CsmaNetDevice::TransmitReadyEvent(): m_currentPkt nonzero"); |
| 626 |
|
684 |
|
| 627 |
// |
685 |
// |
|
|
686 |
// Check for valid queue interface configuration. |
| 687 |
// |
| 688 |
Ptr<NetDeviceQueue> txq; |
| 689 |
if (m_queueInterface) |
| 690 |
{ |
| 691 |
txq = m_queueInterface->GetTxQueue (0); |
| 692 |
} |
| 693 |
|
| 694 |
// |
| 628 |
// Get the next packet from the queue for transmitting |
695 |
// Get the next packet from the queue for transmitting |
| 629 |
// |
696 |
// |
| 630 |
if (m_queue->IsEmpty ()) |
697 |
if (m_queue->IsEmpty ()) |
| 631 |
{ |
698 |
{ |
|
|
699 |
NS_LOG_LOGIC ("No pending packets in device queue for transmission."); |
| 700 |
if (txq) |
| 701 |
{ |
| 702 |
NS_LOG_DEBUG ("The device queue is being woken up."); |
| 703 |
txq->Wake (); |
| 704 |
} |
| 632 |
return; |
705 |
return; |
| 633 |
} |
706 |
} |
| 634 |
else |
707 |
else |
| 635 |
{ |
708 |
{ |
| 636 |
Ptr<QueueItem> item = m_queue->Dequeue (); |
709 |
Ptr<QueueItem> item = m_queue->Dequeue (); |
| 637 |
NS_ASSERT_MSG (item != 0, "CsmaNetDevice::TransmitReadyEvent(): IsEmpty false but no Packet on queue?"); |
710 |
NS_ASSERT_MSG (item != 0, "CsmaNetDevice::TransmitReadyEvent(): IsEmpty false but no Packet on queue?"); |
|
|
711 |
|
| 712 |
// Got another packet off of the queue, so start the transmit process |
| 713 |
// again. If the queue was stopped, start it again if there is room for |
| 714 |
// another packet. Note that we cannot wake the upper layers because |
| 715 |
// otherwise a packet is sent to the device while the machine state is |
| 716 |
// busy, thus causing the assert in TransmitStart to fail. |
| 717 |
if (txq && txq->IsStopped ()) |
| 718 |
{ |
| 719 |
if ((m_queue->GetMode () == Queue::QUEUE_MODE_PACKETS && |
| 720 |
m_queue->GetNPackets () < m_queue->GetMaxPackets ()) || |
| 721 |
(m_queue->GetMode () == Queue::QUEUE_MODE_BYTES && |
| 722 |
m_queue->GetNBytes () + m_mtu <= m_queue->GetMaxBytes ())) |
| 723 |
{ |
| 724 |
NS_LOG_DEBUG ("The device queue is being started."); |
| 725 |
txq->Start (); |
| 726 |
} |
| 727 |
} |
| 728 |
|
| 638 |
m_currentPkt = item->GetPacket (); |
729 |
m_currentPkt = item->GetPacket (); |
| 639 |
m_snifferTrace (m_currentPkt); |
730 |
m_snifferTrace (m_currentPkt); |
| 640 |
m_promiscSnifferTrace (m_currentPkt); |
731 |
m_promiscSnifferTrace (m_currentPkt); |
| 641 |
TransmitStart (); |
732 |
TransmitStart (); |
|
|
733 |
|
| 734 |
if (txq) |
| 735 |
{ |
| 736 |
// Inform BQL about a the packet being transmitted |
| 737 |
txq->NotifyQueuedBytes (m_currentPkt->GetSize ()); |
| 738 |
} |
| 642 |
} |
739 |
} |
| 643 |
} |
740 |
} |
| 644 |
|
741 |
|
|
|
| 952 |
NS_ASSERT (IsLinkUp ()); |
1049 |
NS_ASSERT (IsLinkUp ()); |
| 953 |
|
1050 |
|
| 954 |
// |
1051 |
// |
|
|
1052 |
// Check for valid queue interface configuration. |
| 1053 |
// |
| 1054 |
Ptr<NetDeviceQueue> txq; |
| 1055 |
if (m_queueInterface) |
| 1056 |
{ |
| 1057 |
txq = m_queueInterface->GetTxQueue (0); |
| 1058 |
} |
| 1059 |
NS_ASSERT_MSG (!txq || !txq->IsStopped (), |
| 1060 |
"Send should not be called when the device is stopped"); |
| 1061 |
|
| 1062 |
// |
| 955 |
// Only transmit if send side of net device is enabled |
1063 |
// Only transmit if send side of net device is enabled |
| 956 |
// |
1064 |
// |
| 957 |
if (IsSendEnabled () == false) |
1065 |
if (IsSendEnabled () == false) |
|
|
| 972 |
// |
1080 |
// |
| 973 |
if (m_queue->Enqueue (Create<QueueItem> (packet)) == false) |
1081 |
if (m_queue->Enqueue (Create<QueueItem> (packet)) == false) |
| 974 |
{ |
1082 |
{ |
|
|
1083 |
// Enqueue may fail (overflow). This should not happen if the traffic |
| 1084 |
// control module has been installed. Anyway, stop the tx queue, so that |
| 1085 |
// the upper layers do not send packets until there is room in the queue |
| 1086 |
// again. |
| 975 |
m_macTxDropTrace (packet); |
1087 |
m_macTxDropTrace (packet); |
|
|
1088 |
if (txq) |
| 1089 |
{ |
| 1090 |
NS_LOG_ERROR ("Device queue full when the queue is not stopped!"); |
| 1091 |
txq->Stop (); |
| 1092 |
} |
| 976 |
return false; |
1093 |
return false; |
| 977 |
} |
1094 |
} |
| 978 |
|
1095 |
|
|
|
1096 |
if (txq) |
| 1097 |
{ |
| 1098 |
// Inform BQL about a the new enqueued packet |
| 1099 |
txq->NotifyQueuedBytes (packet->GetSize ()); |
| 1100 |
} |
| 1101 |
|
| 979 |
// |
1102 |
// |
| 980 |
// If the device is idle, we need to start a transmission. Otherwise, |
1103 |
// If the device is idle, we need to start a transmission. Otherwise, |
| 981 |
// the transmission will be started when the current packet finished |
1104 |
// the transmission will be started when the current packet finished |
|
|
| 988 |
Ptr<QueueItem> item = m_queue->Dequeue (); |
1111 |
Ptr<QueueItem> item = m_queue->Dequeue (); |
| 989 |
NS_ASSERT_MSG (item != 0, "CsmaNetDevice::SendFrom(): IsEmpty false but no Packet on queue?"); |
1112 |
NS_ASSERT_MSG (item != 0, "CsmaNetDevice::SendFrom(): IsEmpty false but no Packet on queue?"); |
| 990 |
m_currentPkt = item->GetPacket (); |
1113 |
m_currentPkt = item->GetPacket (); |
|
|
1114 |
|
| 1115 |
// We have enqueued a packet and dequeued a (possibly different) |
| 1116 |
// packet. We need to check if there is still room for another packet |
| 1117 |
// only if the queue is in byte mode (the enqueued packet might be |
| 1118 |
// larger than the dequeued packet, thus leaving no room for another |
| 1119 |
// packet). |
| 1120 |
if (txq) |
| 1121 |
{ |
| 1122 |
if (m_queue->GetMode () == Queue::QUEUE_MODE_BYTES && |
| 1123 |
m_queue->GetNBytes () + m_mtu > m_queue->GetMaxBytes ()) |
| 1124 |
{ |
| 1125 |
NS_LOG_DEBUG ("The device queue is being stopped."); |
| 1126 |
txq->Stop (); |
| 1127 |
} |
| 1128 |
} |
| 1129 |
|
| 991 |
m_promiscSnifferTrace (m_currentPkt); |
1130 |
m_promiscSnifferTrace (m_currentPkt); |
| 992 |
m_snifferTrace (m_currentPkt); |
1131 |
m_snifferTrace (m_currentPkt); |
| 993 |
TransmitStart (); |
1132 |
TransmitStart (); |
|
|
1133 |
|
| 1134 |
if (txq) |
| 1135 |
{ |
| 1136 |
// Inform BQL about a the packet being transmitted |
| 1137 |
txq->NotifyQueuedBytes (packet->GetSize ()); |
| 1138 |
} |
| 1139 |
} |
| 1140 |
} |
| 1141 |
else |
| 1142 |
{ |
| 1143 |
// We have enqueued a packet but we have not dequeued any packet. Thus, |
| 1144 |
// we need to check whether the queue is able to store another packet. If |
| 1145 |
// not, we stop the queue. |
| 1146 |
if (txq) |
| 1147 |
{ |
| 1148 |
if ((m_queue->GetMode () == Queue::QUEUE_MODE_PACKETS && |
| 1149 |
m_queue->GetNPackets () >= m_queue->GetMaxPackets ()) || |
| 1150 |
(m_queue->GetMode () == Queue::QUEUE_MODE_BYTES && |
| 1151 |
m_queue->GetNBytes () + m_mtu > m_queue->GetMaxBytes ())) |
| 1152 |
{ |
| 1153 |
NS_LOG_DEBUG ("The device queue is being stopped."); |
| 1154 |
txq->Stop (); |
| 1155 |
} |
| 994 |
} |
1156 |
} |
| 995 |
} |
1157 |
} |
| 996 |
return true; |
1158 |
return true; |