void AmRlcEntity::ReceptionProcedureEnd () { #ifdef RLC_DEBUG std::cout << "AM RLC ReceptionProcedureEnd " << std::endl; PrintReceivedAMDs (); #endif if (m_receivedAMDs->size () == 0) return; int currentPacket = -1; int expectedNextByte = 0; std::list<int> packetIdToDelete; std::vector <AmdRecord*>::iterator it; for (it = m_receivedAMDs->begin (); it != m_receivedAMDs->end (); it++) { Packet* packet = (*it)->m_packet; if (packet->GetID () != currentPacket && packet->GetRLCHeader ()->GetStartByte () == 0) { //std::cout << "\t\t !! first fragment of the packet" << std::endl; currentPacket = packet->GetID (); expectedNextByte = packet->GetRLCHeader ()->GetEndByte () + 1; } else if (packet->GetID () != currentPacket && packet->GetRLCHeader ()->GetStartByte () != 0) { //std::cout << "\t\t !! fragment of a new packet, but not he first" << std::endl; expectedNextByte = 0; } else if (packet->GetID () == currentPacket && packet->GetRLCHeader ()->GetStartByte () == expectedNextByte) { if (packet->GetRLCHeader ()->IsTheLatestFragment ()) { //std::cout << "\t\t !! consecutive fragment --> the packet can be reassembled" << std::endl; RadioBearerSink *bearer = (RadioBearerSink*) GetRadioBearerInstance (); Packet* p = packet->Copy (); p->SetSize (packet->GetRLCHeader ()->GetEndByte () + 8); bearer->Receive (p); packetIdToDelete.push_front(packet->GetID ()); expectedNextByte = 0; } else { //std::cout << "\t\t !! consecutive fragment --> we expect another fragment" << std::endl; expectedNextByte = packet->GetRLCHeader ()->GetEndByte () + 1; } } } //DELETE REASSEBLED PACKETS! #ifdef RLC_DEBUG std::cout << "\t\t !! DELETE REASSEBLED PACKETS" << std::endl; #endif for (std::list<int>::iterator iter = packetIdToDelete.begin (); iter != packetIdToDelete.end (); iter++) { std::vector <AmdRecord*> *newAmdList = new std::vector <AmdRecord*>; int id = (*iter); for (std::vector <AmdRecord*>::iterator itt = m_receivedAMDs->begin (); itt != m_receivedAMDs->end (); itt++) { AmdRecord *amdRecord = (*itt); double delay = amdRecord->m_packet->GetTimeStamp () + GetRadioBearerInstance ()->GetQoSParameters ()->GetMaxDelay (); if (amdRecord->m_packet->GetID () == id) { delete amdRecord; } else { newAmdList->push_back (amdRecord); } } m_receivedAMDs->clear(); delete m_receivedAMDs; m_receivedAMDs = newAmdList; } //DELETE PACKETS or AMDs WHOSE DEADLINE is EXPIRED ! #ifdef RLC_DEBUG std::cout << "\t\t !! DELETE PACKETS or AMDs WHOSE DEADLINE is EXPIRED !" << std::endl; #endif int currentpacketId = -1; std::vector <AmdRecord*> *newAmdList = new std::vector <AmdRecord*>; for (std::vector <AmdRecord*>::iterator itt = m_receivedAMDs->begin (); itt != m_receivedAMDs->end (); itt++) { AmdRecord *amdRecord = (*itt); double delay = amdRecord->m_packet->GetTimeStamp () + GetRadioBearerInstance ()->GetQoSParameters ()->GetMaxDelay (); if ((delay + 0.01) < Simulator::Init()->Now()) { //trace for statistical purposes Packet *pp = amdRecord->m_packet; if (pp->GetID () != currentpacketId) { currentpacketId = amdRecord->m_packet->GetID (); if (_RLC_TRACING_) { std::cout << "DROP_RX_AM_RLC"; if (pp->GetPacketTags()->GetApplicationType() == PacketTAGs::APPLICATION_TYPE_VOIP) std::cout << " VOIP"; else if (pp->GetPacketTags()->GetApplicationType() == PacketTAGs::APPLICATION_TYPE_TRACE_BASED) std::cout << " VIDEO"; else if (pp->GetPacketTags()->GetApplicationType() == PacketTAGs::APPLICATION_TYPE_CBR) std::cout << " CBR"; else if (pp->GetPacketTags()->GetApplicationType() == PacketTAGs::APPLICATION_TYPE_INFINITE_BUFFER) std::cout << " INF_BUF"; else std::cout << " UNKNOW"; std::cout << " ID "<< pp->GetID() << " B " << GetRlcEntityIndex (); if (pp->GetPacketTags() != NULL && pp->GetPacketTags()->GetApplicationType() == PacketTAGs::APPLICATION_TYPE_TRACE_BASED) { std::cout << " FRAME " << pp->GetPacketTags()->GetFrameNuber() << " START " << pp->GetPacketTags()->GetStartByte() << " END " << pp->GetPacketTags()->GetEndByte(); } std::cout << std::endl; } } delete amdRecord; } else { newAmdList->push_back (amdRecord); } } m_receivedAMDs->clear(); delete m_receivedAMDs; m_receivedAMDs = newAmdList; #ifdef RLC_DEBUG PrintReceivedAMDs (); #endif }
PacketBurst* AmRlcEntity::TransmissionProcedure (int availableBytes) { #ifdef RLC_DEBUG std::cout << "AM RLC tx procedure for node " << GetRadioBearerInstance ()->GetSource ()->GetIDNetworkNode ()<< " bearer "<< GetRlcEntityIndex () << std::endl; #endif PacketBurst* pb = new PacketBurst (); AmStateVariables* amRlcState = GetAmStateVariables (); //STEP 1 CHECK FOR RE-TRANSMISSION #ifdef RLC_DEBUG std::cout << "--> STEP 1: CHECK FOR RE-TRANSMISSION" << std::endl; PrintSentAMDs (); #endif int nbSentAMDs = GetSentAMDs()->size(); if (nbSentAMDs != 0) { int amdId = 0; while (availableBytes > 0 && amdId < nbSentAMDs) { AmdRecord* amdRecord = GetSentAMDs()->at (amdId); if (amdRecord->m_packet->GetSize () + 6 <= availableBytes) //6 = MAC + CRC overhead { amdRecord->m_retx_count++; #ifdef RLC_DEBUG std::cout << "send the whole unacknowledged AMD PDU" << std::endl; #endif Packet* p = amdRecord->m_packet->Copy (); MACHeader *mac = new MACHeader (GetRadioBearerInstance ()->GetSource ()->GetIDNetworkNode (), GetRadioBearerInstance ()->GetDestination ()->GetIDNetworkNode ()); p->AddMACHeader(mac); p->AddHeaderSize (3); if (_RLC_TRACING_) { std::cout << "TX AM_RLC SIZE" << p->GetSize () << " B " << GetRlcEntityIndex () << " PDU_SN " << p->GetRLCHeader ()->GetRlcPduSequenceNumber() << std::endl; } pb->AddPacket (p); availableBytes -= p->GetSize (); amdId++; } else if (availableBytes > 8) // 8 = RLC + MAC + CRC { amdRecord->m_retx_count++; #ifdef RLC_DEBUG std::cout << "there is not enough bandwidth for this AMD PDU. Do another fragmentation" << "--> bytes: " << availableBytes << std::endl; #endif Packet* p1 = amdRecord->m_packet->Copy (); Packet* p2 = amdRecord->m_packet; int sentBytes = availableBytes - 7; p1->GetRLCHeader ()->SetEndByte (p1->GetRLCHeader ()->GetStartByte () + sentBytes - 1); p1->SetSize (2 + sentBytes); //consider both RLC and sent bytes p2->GetRLCHeader ()->SetStartByte (p1->GetRLCHeader ()->GetStartByte () + sentBytes); p2->SetSize (p2->GetSize () - sentBytes); //decrease the packet size by the quota of sent bytes p1->GetRLCHeader ()->SetTheLatestFragment (false); p1->GetRLCHeader ()->SetAFragment (true); p2->GetRLCHeader ()->SetAFragment (true); MACHeader *mac = new MACHeader (GetRadioBearerInstance ()->GetSource ()->GetIDNetworkNode (), GetRadioBearerInstance ()->GetDestination ()->GetIDNetworkNode ()); p1->AddMACHeader(mac); p1->AddHeaderSize (3); //CRC if (_RLC_TRACING_) { std::cout << "TX AM_RLC SIZE" << p1->GetSize () << " B " << GetRlcEntityIndex () << " PDU_SN " << p1->GetRLCHeader ()->GetRlcPduSequenceNumber() << std::endl; } pb->AddPacket (p1->Copy ()); AmdRecord* newAmdRecord = new AmdRecord (p1, p1->GetRLCHeader ()->GetRlcPduSequenceNumber ()); newAmdRecord->m_retx_count = amdRecord->m_retx_count; GetSentAMDs ()->insert(GetSentAMDs ()->begin() + amdId, newAmdRecord); #ifdef RLC_DEBUG PrintSentAMDs (); #endif availableBytes = 0; } else { availableBytes = 0; } } } if (availableBytes <= 0 ) return pb; //STEP 2 NEW TRANSMISSION #ifdef RLC_DEBUG std::cout << "--> STEP 2: CHECK FOR NEW TRANSMISSION" << std::endl; #endif RadioBearer *bearer = (RadioBearer*) GetRadioBearerInstance (); MacQueue *queue = bearer->GetMacQueue (); if (bearer->GetApplication ()->GetApplicationType () == Application::APPLICATION_TYPE_INFINITE_BUFFER) { //CREATE PACKET FOR THE INFINITE BUFFER SOURCE while (true) { Packet *packet = bearer->CreatePacket (availableBytes); packet->GetRLCHeader ()->SetRlcEntityIndex (GetRlcEntityIndex ()); // set sn int currentSN = amRlcState->m_vt_s; packet->GetRLCHeader ()->SetRlcPduSequenceNumber (currentSN); //update am rlc state variables amRlcState->m_vt_s++; //Add MAC header MACHeader *mac = new MACHeader (GetRadioBearerInstance ()->GetSource ()->GetIDNetworkNode (), GetRadioBearerInstance ()->GetDestination ()->GetIDNetworkNode ()); packet->AddMACHeader(mac); packet->AddHeaderSize (3); if (availableBytes > 1503) { packet->SetSize (1503); packet->GetPacketTags ()->SetApplicationSize (1490); availableBytes -= 1503; if (_RLC_TRACING_) { std::cout << "TX AM_RLC SIZE " << packet->GetSize () << " B " << GetRlcEntityIndex () << " PDU_SN " << packet->GetRLCHeader ()->GetRlcPduSequenceNumber() << " Frag " << packet->GetRLCHeader ()->IsAFragment () << " LastFrag " << packet->GetRLCHeader ()->IsTheLatestFragment() << " startB " << packet->GetRLCHeader ()->GetStartByte () << " endB " << packet->GetRLCHeader ()->GetEndByte () << std::endl; } pb->AddPacket (packet); } else if (availableBytes > 13) { packet->SetSize (availableBytes); packet->GetPacketTags ()->SetApplicationSize (availableBytes - 13); availableBytes = 0; if (_RLC_TRACING_) { std::cout << "TX 2 AM_RLC SIZE " << packet->GetSize () << " B " << GetRlcEntityIndex () << " PDU_SN " << packet->GetRLCHeader ()->GetRlcPduSequenceNumber() << " Frag " << packet->GetRLCHeader ()->IsAFragment () << " LastFrag " << packet->GetRLCHeader ()->IsTheLatestFragment() << " startB " << packet->GetRLCHeader ()->GetStartByte () << " endB " << packet->GetRLCHeader ()->GetEndByte () << std::endl; } pb->AddPacket (packet); break; } else { availableBytes = 0; break; } } } else { while (availableBytes > 0 && !queue->IsEmpty ()) { Packet* packet = queue->GetPacketToTramsit (availableBytes); if (packet != NULL) { #ifdef RLC_DEBUG std::cout << "SEND PACKET id " << packet->GetID() << " frag n " << packet->GetRLCHeader ()->GetFragmentNumber ()<< std::endl; #endif //Set the id of the receiver RLC entity packet->GetRLCHeader ()->SetRlcEntityIndex (GetRlcEntityIndex ()); //amRlcState->PrintTxVariables (); // set sn int currentSN = amRlcState->m_vt_s; packet->GetRLCHeader ()->SetRlcPduSequenceNumber (currentSN); //update am rlc state variables amRlcState->m_vt_s++; //amRlcState->PrintTxVariables (); #ifdef RLC_DEBUG std::cout << "_____ pkt " << packet->GetID() << " frag " << packet->GetRLCHeader ()->GetFragmentNumber () << " sn " << packet->GetRLCHeader ()->GetRlcPduSequenceNumber () << " startB " << packet->GetRLCHeader ()->GetStartByte () << " endB " << packet->GetRLCHeader ()->GetEndByte () << std::endl; PrintSentAMDs (); #endif AmdRecord *amdRecord = new AmdRecord (packet->Copy (), currentSN); GetSentAMDs ()->push_back (amdRecord); #ifdef RLC_DEBUG PrintSentAMDs (); #endif //Add MAC header MACHeader *mac = new MACHeader (GetRadioBearerInstance ()->GetSource ()->GetIDNetworkNode (), GetRadioBearerInstance ()->GetDestination ()->GetIDNetworkNode ()); packet->AddMACHeader(mac); packet->AddHeaderSize (3); if (_RLC_TRACING_) { std::cout << "TX AM_RLC SIZE " << packet->GetSize () << " B " << GetRlcEntityIndex () << " PDU_SN " << packet->GetRLCHeader ()->GetRlcPduSequenceNumber() << std::endl; } pb->AddPacket (packet); availableBytes -= packet->GetSize (); } else { availableBytes = 0; } } } return pb; }
void UmRlcEntity::ReceptionProcedure (Packet* p) { #ifdef RLC_DEBUG std::cout << "UM RLC rx procedure for node " << GetRadioBearerInstance ()->GetDestination ()->GetIDNetworkNode ()<< std::endl; std::cout << "RECEIVE PACKET id " << p->GetID() << " frag n " << p->GetRLCHeader ()->GetFragmentNumber ()<< std::endl; #endif if (_RLC_TRACING_) { std::cout << "RX UM_RLC SIZE " << p->GetSize () << " B " << GetRlcEntityIndex () << " PDU_SN " << p->GetRLCHeader ()->GetRlcPduSequenceNumber() << std::endl; } if (m_incomingPacket.size() > 0 && p->GetID () != m_incomingPacket.at (0)->GetID ()) { #ifdef RLC_DEBUG std::cout << "received a new packet, delete enqueued fragments"<< std::endl; #endif Packet *pp = m_incomingPacket.at (0); if (_RLC_TRACING_) { std::cout << "DROP_RX_UM_RLC"; if (pp->GetPacketTags()->GetApplicationType() == PacketTAGs::APPLICATION_TYPE_VOIP) std::cout << " VOIP"; else if (pp->GetPacketTags()->GetApplicationType() == PacketTAGs::APPLICATION_TYPE_TRACE_BASED) std::cout << " VIDEO"; else if (pp->GetPacketTags()->GetApplicationType() == PacketTAGs::APPLICATION_TYPE_CBR) std::cout << " CBR"; else if (pp->GetPacketTags()->GetApplicationType() == PacketTAGs::APPLICATION_TYPE_INFINITE_BUFFER) std::cout << " INF_BUF"; else std::cout << " UNKNOW"; std::cout << " ID "<< pp->GetID() << " B " << GetRlcEntityIndex (); if (pp->GetPacketTags() != NULL && pp->GetPacketTags()->GetApplicationType() == PacketTAGs::APPLICATION_TYPE_TRACE_BASED) { std::cout << " FRAME " << pp->GetPacketTags()->GetFrameNuber() << " START " << pp->GetPacketTags()->GetStartByte() << " END " << pp->GetPacketTags()->GetEndByte(); } std::cout << std::endl; } ClearIncomingPackets (); } //The received packet is not a fragment if (!p->GetRLCHeader ()->IsAFragment ()) { #ifdef RLC_DEBUG std::cout << "\t received a packet " << std::endl; #endif RadioBearerSink *bearer = (RadioBearerSink*) GetRadioBearerInstance (); bearer->Receive (p); } //The received packet is a fragment if (p->GetRLCHeader ()->IsAFragment () && !p->GetRLCHeader ()->IsTheLatestFragment()) { #ifdef RLC_DEBUG std::cout << "\t received a fragment " << std::endl; #endif m_incomingPacket.push_back (p); } //The received packet is the latest fragment if (p->GetRLCHeader ()->IsAFragment () && p->GetRLCHeader ()->IsTheLatestFragment()) { #ifdef RLC_DEBUG std::cout << "\t received the latest fragment " << std::endl; #endif m_incomingPacket.push_back (p); //check if all fragment have been received int numberOfPackets = p->GetRLCHeader ()->GetFragmentNumber () + 1; if (m_incomingPacket.size () == numberOfPackets) { RadioBearerSink *bearer = (RadioBearerSink*) GetRadioBearerInstance (); bearer->Receive (p->Copy ()); ClearIncomingPackets (); } else { #ifdef RLC_DEBUG std::cout << "list of fragment incomplete -> delete all!"<< std::endl; #endif if (_RLC_TRACING_) { std::cout << "DROP_RX_UM_RLC"; if (p->GetPacketTags()->GetApplicationType() == PacketTAGs::APPLICATION_TYPE_VOIP) std::cout << " VOIP"; else if (p->GetPacketTags()->GetApplicationType() == PacketTAGs::APPLICATION_TYPE_TRACE_BASED) std::cout << " VIDEO"; else if (p->GetPacketTags()->GetApplicationType() == PacketTAGs::APPLICATION_TYPE_CBR) std::cout << " CBR"; else if (p->GetPacketTags()->GetApplicationType() == PacketTAGs::APPLICATION_TYPE_INFINITE_BUFFER) std::cout << " INF_BUF"; else std::cout << " UNKNOW"; std::cout << " ID "<< p->GetID() << " B " << GetRlcEntityIndex (); if (p->GetPacketTags() != NULL && p->GetPacketTags()->GetApplicationType() == PacketTAGs::APPLICATION_TYPE_TRACE_BASED) { std::cout << " FRAME " << p->GetPacketTags()->GetFrameNuber() << " START " << p->GetPacketTags()->GetStartByte() << " END " << p->GetPacketTags()->GetEndByte(); } std::cout << std::endl; } ClearIncomingPackets (); } } }
PacketBurst* UmRlcEntity::TransmissionProcedure (int availableBytes) { #ifdef RLC_DEBUG std::cout << "UM RLC tx procedure for node " << GetRadioBearerInstance ()->GetSource ()->GetIDNetworkNode ()<< std::endl; #endif PacketBurst* pb = new PacketBurst (); RadioBearer *bearer = (RadioBearer*) GetRadioBearerInstance (); MacQueue *queue = bearer->GetMacQueue (); if (bearer->GetApplication ()->GetApplicationType () == Application::APPLICATION_TYPE_INFINITE_BUFFER) { //CREATE PACKET FOR THE INFINITE BUFFER SOURCE while (true) { Packet *packet = bearer->CreatePacket (availableBytes); //Set the id of the receiver RLC entity packet->GetRLCHeader ()->SetRlcEntityIndex (GetRlcEntityIndex ()); packet->GetRLCHeader ()->SetRlcPduSequenceNumber (GetRlcPduSequenceNumber ()); int newSequenceNumber = GetRlcPduSequenceNumber () + 1; SetRlcPduSequenceNumber (newSequenceNumber); //Add MAC header MACHeader *mac = new MACHeader (GetRadioBearerInstance ()->GetSource ()->GetIDNetworkNode (), GetRadioBearerInstance ()->GetDestination ()->GetIDNetworkNode ()); packet->AddMACHeader(mac); packet->AddHeaderSize (3); //CRC if (availableBytes > 1503) { packet->SetSize (1503); packet->GetPacketTags ()->SetApplicationSize (1490); //Set the id of the receiver RLC entity packet->GetRLCHeader ()->SetRlcEntityIndex (GetRlcEntityIndex ()); packet->GetRLCHeader ()->SetRlcPduSequenceNumber (GetRlcPduSequenceNumber ()); int newSequenceNumber = GetRlcPduSequenceNumber () + 1; SetRlcPduSequenceNumber (newSequenceNumber); availableBytes -= 1503; pb->AddPacket (packet); if (_RLC_TRACING_) { std::cout << "TX UM_RLC SIZE" << packet->GetSize () << " B " << GetRlcEntityIndex () << " PDU_SN " << packet->GetRLCHeader ()->GetRlcPduSequenceNumber() << std::endl; } } else if (availableBytes > 13) { packet->SetSize (availableBytes); packet->GetPacketTags ()->SetApplicationSize (availableBytes - 13); //Set the id of the receiver RLC entity packet->GetRLCHeader ()->SetRlcEntityIndex (GetRlcEntityIndex ()); packet->GetRLCHeader ()->SetRlcPduSequenceNumber (GetRlcPduSequenceNumber ()); int newSequenceNumber = GetRlcPduSequenceNumber () + 1; SetRlcPduSequenceNumber (newSequenceNumber); availableBytes = 0; pb->AddPacket (packet); if (_RLC_TRACING_) { std::cout << "TX UM_RLC SIZE" << packet->GetSize () << " B " << GetRlcEntityIndex () << " PDU_SN " << packet->GetRLCHeader ()->GetRlcPduSequenceNumber() << std::endl; } break; } else { availableBytes = 0; break; } } } else { while (availableBytes > 0 && !queue->IsEmpty ()) { Packet* packet = queue->GetPacketToTramsit (availableBytes); if (packet != NULL) { //Set the id of the receiver RLC entity packet->GetRLCHeader ()->SetRlcEntityIndex (GetRlcEntityIndex ()); packet->GetRLCHeader ()->SetRlcPduSequenceNumber (GetRlcPduSequenceNumber ()); int newSequenceNumber = GetRlcPduSequenceNumber () + 1; SetRlcPduSequenceNumber (newSequenceNumber); if (_RLC_TRACING_) { std::cout << "TX UM_RLC SIZE" << packet->GetSize () << " B " << GetRlcEntityIndex () << " PDU_SN " << packet->GetRLCHeader ()->GetRlcPduSequenceNumber() << std::endl; } //Add MAC header MACHeader *mac = new MACHeader (GetRadioBearerInstance ()->GetSource ()->GetIDNetworkNode (), GetRadioBearerInstance ()->GetDestination ()->GetIDNetworkNode ()); packet->AddMACHeader(mac); packet->AddHeaderSize (3); //CRC pb->AddPacket (packet); availableBytes -= packet->GetSize (); } else { availableBytes = 0; } } } return pb; }
Packet* RadioBearer::CreatePacket (int bytes) { Packet *p = new Packet (); p->SetID(Simulator::Init()->GetUID ()); p->SetTimeStamp(Simulator::Init()->Now ()); UDPHeader *udp = new UDPHeader (GetClassifierParameters ()->GetSourcePort(), GetClassifierParameters ()->GetDestinationPort ()); p->AddUDPHeader(udp); IPHeader *ip = new IPHeader (GetClassifierParameters ()->GetSourceID (), GetClassifierParameters ()->GetDestinationID()); p->AddIPHeader(ip); PDCPHeader *pdcp = new PDCPHeader (); p->AddPDCPHeader (pdcp); RLCHeader *rlc = new RLCHeader (); p->AddRLCHeader(rlc); PacketTAGs *tags = new PacketTAGs (); tags->SetApplicationType(PacketTAGs::APPLICATION_TYPE_INFINITE_BUFFER); p->SetPacketTags(tags); if (_APP_TRACING_) { /* * Trace format: * * TX APPLICATION_TYPE BEARER_ID SIZE SRC_ID DST_ID TIME */ UserEquipment* ue = (UserEquipment*) GetApplication ()->GetDestination (); std::cout << "TX"; switch (p->GetPacketTags ()->GetApplicationType ()) { case Application::APPLICATION_TYPE_VOIP: { std::cout << " VOIP"; break; } case Application::APPLICATION_TYPE_TRACE_BASED: { std::cout << " VIDEO"; break; } case Application::APPLICATION_TYPE_CBR: { std::cout << " CBR"; break; } case Application::APPLICATION_TYPE_INFINITE_BUFFER: { std::cout << " INF_BUF"; break; } default: { std::cout << " UNDEFINED"; break; } } if (bytes > 1490) bytes = 1490; else bytes = bytes - 13; std::cout << " ID " << p->GetID () << " B " << GetRlcEntity ()->GetRlcEntityIndex () << " SIZE " << bytes << " SRC " << GetSource ()->GetIDNetworkNode () << " DST " << GetDestination ()->GetIDNetworkNode () << " T " << Simulator::Init()->Now() << " " << ue->IsIndoor () << std::endl; } return p; }