#ifndef RND_ROUTING_H #define RND_ROUTING_H #include "RND_Routing.h" #endif RND_Routing::RND_Routing(PacketPool* PP, MAC* mc, PacketBuffer* Bf, int NID, Statistics* St, Settings* S, God* G) : Routing(PP, mc, Bf, NID, St, S, G) { // initialize random seed srand (time(NULL)); return; } RND_Routing::~RND_Routing() { return; } void RND_Routing::NewContact(double CTime, int NID) { Contact(CTime, NID); return; } void RND_Routing::Contact(double CTime, int NID) { // Apply Deletion Method operations first if needed int *Information=DM->GetInfo(); if(Information != NULL) { //Create a vaccine information packet SendVaccine(CTime,NID,Information); } else { // If there are packets destined to node in contact try to send them // Note: How this operation will be executed depends on the deletion method //Clean buffer using Deletion method (Delivered pkts) DM->CleanBuffer(this->Buf); if(DM->ExchangeDirectSummary()) { SendDirectSummary(CTime,NID); } else { SendDirectPackets(CTime,NID); } } return; } void RND_Routing::ContactRemoved(double CTime, int NID) { return; } void RND_Routing::AfterDirectTransfers(double CTime, int NID) { int i=0; int *pkts=NULL; double r=0.0; // get all packets inside my buffer that are not destined to node in contact pkts = Buf->getPacketsNotDestinedTo(NID); for(i = 1; i <= pkts[0]; i++) { //Add packets to scheduler r = (double) rand() / RAND_MAX; //printf("My rand %f\n",r); if (r > 0.6 && Buf->GetPrev(pkts[i]) != NID) { sch->addPacket(pkts[i],NULL); } } free(pkts); //Apply scheduling int *outgoing=sch->getOutgoingPackets(); //Send Packets if(outgoing) { for(int i=1;i<=outgoing[0];i++) { // printf("node %d: Sending packet %d to node %d\n",NodeID ,outgoing[i],NID); SendPacket(CTime,outgoing[i],NID,1); // Remove the packet from the buffer Buf->removePkt(outgoing[i]); } free(outgoing); } return; } void RND_Routing::recv(double rTime, int pktID) { int PacketID; Packet *p; Header *h; // sanity check if((p = pktPool->GetPacket(pktID)) == NULL) { printf("Error: Packet %d doesn't exist in Packet Pool!\nAborting...\n",pktID); exit(1); } // get header and packet ID h = p->getHeader(); if(h->IsDuplicate() == true) { PacketID = h->GetOriginal(); } else { PacketID = pktID; } // sanity check if(rTime < 0 || p->GetStartTime() < 0) { printf("%f: Node %d received new packet with ID %d and type %d from %d\n", rTime, this->NodeID, p->getID(), p->getType(), h->GetprevHop()); exit(1); } // Identify the type of the packet switch(p->getType()) { case DATA_PACKET: { ReceptionData(h, p, pktID, rTime, PacketID); break; } case DIRECT_SUMMARY_PACKET: { ReceptionDirectSummary(h,p,pktID,rTime); break; } case DIRECT_REQUEST_PACKET: { ReceptionDirectRequest(h,p,pktID,rTime); break; } case ANTIPACKET: { ReceptionAntipacket(h,p,pktID,rTime); break; } case ANTIPACKET_RESPONSE: { ReceptionAntipacketResponse(h,p,pktID,rTime); break; } default: { printf("Error: Unknown packet type! RND Routing is not using this type of packet!\nAborting...\n"); exit(1); } } return; } void RND_Routing::ReceptionData(Header* hd, Packet* pkt, int PID, double CurrentTime, int RealID) { #ifdef DIRECT_DEBUG printf("%f: Node %d received new data packet with ID %d from %d\n", CurrentTime, this->NodeID, RealID, hd->GetprevHop()); #endif // Check if I am the packet creator (packet comes from the application layer) if((hd->GetSource() == this->NodeID) && (hd->GetNextHop() == -1)) { // Update buffer Buf->addPkt(RealID, hd->GetDestination(),hd->GetSource(),CurrentTime, hd->GetHops(), hd->GetprevHop(), pkt->GetStartTime()); Stat->pktGen(RealID, hd->GetSource(), hd->GetDestination(), CurrentTime); return; } // Check if I am the next hop if(hd->GetNextHop() != this->NodeID) { // Garbage collection if(pkt->AccessPkt() == false) { pktPool->ErasePacket(PID); } return; } // Check if I am the destination of the packet if(hd->GetDestination() == this->NodeID) { // Update statistics Stat->pktRec(hd->GetHops(), CurrentTime - pkt->GetStartTime(), pkt, pkt->GetStartTime(), false); // Garbage collection if(pkt->AccessPkt() == false) { pktPool->ErasePacket(PID); } return; } // I am the next hop but not the destination if(Buf->PacketExists(RealID)) { printf("[Error]: Node %d received a packet with ID %d from node %d that already exists in its buffer\n", this->NodeID, RealID, hd->GetprevHop()); exit(EXIT_FAILURE); } else { // Update buffer Buf->addPkt(RealID, hd->GetDestination(), CurrentTime,hd->GetSource(),hd->GetHops(), hd->GetprevHop(), pkt->GetStartTime()); // Update statistics Stat->incTimesAsRelayNode(pkt->GetStartTime()); } // Garbage collection if(pkt->AccessPkt() == false) { pktPool->ErasePacket(PID); } return; } void RND_Routing::SendPacket(double STime, int pktID, int nHop, int RepValue) { int CurrentN=0; Packet *p=NULL; Packet *newPkt=NULL; if((p = pktPool->GetPacket(pktID)) == NULL) { printf("Error: Packet %d doesn't exist in Packet Pool!\nAborting...\n", pktID); exit(1); } // Duplicate the packet newPkt = p->Duplicate(Buf->GetHops(pktID)); newPkt->getHeader()->SetNextHop(nHop); newPkt->getHeader()->SetprevHop(this->NodeID); newPkt->getHeader()->SetRep(RepValue); pktPool->AddPacket(newPkt); // Inform the current neighbors about the new packet CurrentN = Mlayer->BroadcastPkt(STime, this->NodeID, newPkt->getSize(), newPkt->getID()); // Garbage collection if(CurrentN > 0) { // Set access attribute to safely delete the packet later newPkt->SetRecipients(CurrentN); // Update statistics if(newPkt->getHeader()->GetDestination() == nHop) { Stat->incHandovers(Buf->GetPktCreationTime(pktID)); } Stat->incForwards(pktID, Buf->GetPktCreationTime(pktID)); } else { // Cancel broadcast and delete packet (there are no neighbors) pktPool->ErasePacket(newPkt->getID()); } return; }