#include "tsn-aggregated-net-device.h" #include "ns3/tsn-net-device.h" #include "ns3/ethernet-header2.h" namespace ns3 { NS_LOG_COMPONENT_DEFINE("TsnAggregatedNetDevice"); NS_OBJECT_ENSURE_REGISTERED(TsnAggregatedNetDevice); TypeId TsnAggregatedNetDevice::GetTypeId() { static TypeId tid = TypeId("ns3::TsnAggregatedNetDevice") .SetParent() .SetGroupName("Tsn") .AddConstructor(); return tid; } TsnAggregatedNetDevice::TsnAggregatedNetDevice() { NS_LOG_FUNCTION(this); } TsnAggregatedNetDevice::~TsnAggregatedNetDevice() { NS_LOG_FUNCTION(this); } void TsnAggregatedNetDevice::AddNetDevice(Ptr net) { NS_LOG_FUNCTION(this); net->SetPromiscReceiveCallback(MakeCallback(&TsnAggregatedNetDevice::MacRxPromiscCallback, this)); m_netDevices.insert(m_netDevices.end(),net); } void TsnAggregatedNetDevice::DoDispose() { NS_LOG_FUNCTION(this); m_netDevices.clear(); NetDevice::DoDispose(); } bool TsnAggregatedNetDevice::SendFrom(Ptr packet, const Address& source, const Address& dest, uint16_t ethertype) { NS_LOG_FUNCTION(this); //Pkt copy Ptr pkt = packet->Copy(); // Stream identification in-facing output std::vector> streamIdentityTable = GetNode()->GetStreamIdentityTable(); for (uint16_t i = 0; i < streamIdentityTable.size(); i++){ if (streamIdentityTable[i]->Match(this, true, false, pkt)){ uint32_t streamHandle = streamIdentityTable[i]->GetStreamHandle(); //FRER // NS_LOG_INFO( "Stream handle of Pkt #"<GetUid() << " on output : " << streamHandle); bool isSeqNumber = false; uint16_t seqNumber = 0; //Sequence decode => extract RTAG if this function is enable for this stream handle //TODO //Individual Recovery if this function is enable for this stream handle //TODO //Sequence Recovery if this function is enable for this stream handle //TODO //Stream Transfert Function //Nothing to implement in the simulator //Sequence Generation if this function is enable for this stream handle std::vector> seqGenTable = GetNode()->GetSequenceGenerationTable(); for (uint32_t i = 0; i < seqGenTable.size(); i++) { if(seqGenTable[i]->IsApplicable(streamHandle)) { isSeqNumber = true; seqNumber = seqGenTable[i]->GetSequenceNumber(); break; } } //Stream splitting if this function is enable for this stream handle //TODO //Sequence encode => encode RTAG if this function is enable for this stream handle if (isSeqNumber) { std::vector> seqEncTable = GetNode()->GetSequenceEncodeDecodeTable(); for (uint32_t i = 0; i < seqEncTable.size(); i++) { if(seqEncTable[i]->IsApplicable(streamHandle, this, true)) { seqEncTable[i]->Encode(pkt, seqNumber); break; } } } break; } } //Stream identification out-facing input (active) for (uint16_t i = 0; i < streamIdentityTable.size(); i++){ if (streamIdentityTable[i]->Match(this, false, true, pkt)){ streamIdentityTable[i]->DoActiveUpdate(pkt); break; } } //Send packet to the TsnNetDevice bool res = true; bool outRes = true; for(int i = 0; i<(int)m_netDevices.size(); i++) { res = m_netDevices[i]->SendFrom(pkt, source, dest, ethertype); if (!res){ outRes = false; } } m_snifferTrace(pkt); m_promiscSnifferTrace(pkt); //Return false if one sendFrom have return false return(outRes); } bool TsnAggregatedNetDevice::MacRxPromiscCallback(Ptr dev, Ptr p, uint16_t protocol, const Address& sender, const Address& receiver, PacketType pType) { NS_LOG_FUNCTION(this); // Hit the trace hooks. All of these hooks are in the same place in this // device because it is so simple, but this is not usually the case in // more complicated devices. m_snifferTrace(p); m_promiscSnifferTrace(p); m_phyRxEndTrace(p); if (pType != PACKET_OTHERHOST) { //Pkt copy Ptr packet = p->Copy(); // Stream identification std::vector> streamIdentityTable = GetNode()->GetStreamIdentityTable(); for (uint16_t i = 0; i < streamIdentityTable.size(); i++){ if (streamIdentityTable[i]->Match(this, false, true, packet)){ uint32_t streamHandle = streamIdentityTable[i]->GetStreamHandle(); //FRER bool isSeqNumber = false; uint16_t seqNumber = 0; //Sequence decode => extract RTAG if this function is enable for this stream handle std::vector> seqEncTable = GetNode()->GetSequenceEncodeDecodeTable(); for (uint32_t i = 0; i < seqEncTable.size(); i++) { if(seqEncTable[i]->IsApplicable(streamHandle, this, true)) { isSeqNumber = true; seqNumber = seqEncTable[i]->Decode(packet); break; } } //Individual Recovery if this function is enable for this stream handle //TODO //Sequence Recovery if this function is enable for this stream handle std::vector> seqRcvyTable = GetNode()->GetSequenceRecoveryTable(); for (uint32_t i = 0; i < seqRcvyTable.size(); i++) { bool IsApplicable(uint32_t streamHandle, Ptr port, bool direction, bool hasSeqNumber, bool individualRecovery); if(seqRcvyTable[i]->IsApplicable(streamHandle, this, true, isSeqNumber, false)) { if(!seqRcvyTable[i]->Recovery(seqNumber)) { //Duplicate FRER packet detected ! ==> Drop m_frerDropTrace(packet); return false; } break; } } //Stream Transfert Function //Nothing to implement in the simulator //Sequence Generation if this function is enable for this stream handle //TODO //Stream splitting if this function is enable for this stream handle //TODO //Sequence encode => encode RTAG if this function is enable for this stream handle //TODO break; } } //A copy for callback Ptr originalPacket = packet->Copy(); //Hit the callback and trace EthernetHeader2 header; packet->RemoveHeader(header); uint16_t protocol; protocol = header.GetEthertype(); if (!m_promiscCallback.IsNull()) { m_macPromiscRxTrace(originalPacket->Copy()); m_promiscCallback(this, originalPacket, protocol, header.GetSrc(), header.GetDest(), pType); } //NS_LOG_INFO((Simulator::Now()).As(Time::S) << " \t" << Names::FindName(m_node) << "/" << Names::FindName(this) <<" : Pkt #" << originalPacket->GetUid() <<" received by the netDevice ! " << originalPacket->ToString()); m_macRxTrace(originalPacket); m_rxCallback(this, packet, protocol, header.GetSrc()); m_latencyTrace(originalPacket); } return true; } }