📄 ashr.h
字号:
** - Remove from t3 and ack queues** - Add to collision sent queue** - Update packet header to indicate that a collision packet has been sent** - Create and send COLL pkt*/template <class PLD>void SSRv02<PLD>::sendCollisionPacket( packet_t *pkt){ mwlPrint( ("sCP: 0x%08X %3d->%3d; ea %3d @ %f\n", (int) pkt, (int) pkt->hdr.src_addr, (int) pkt->hdr.dst_addr, (int) MyEtherAddr, SimTime())); if( endT2Timer.Active( pkt->hdr.t2Index) == true) endT2Timer.Cancel( pkt->hdr.t2Index);//mwl if( endT3Timer.Active( pkt->hdr.t3Index) == true)//mwl endT3Timer.Cancel( pkt->hdr.t3Index); m_T3_queue.remove( pkt); mwlPrint( ("sCP: Adding %s to m_collPktsSent_queue ea %3d\n", pkt->dump().c_str(), (int) MyEtherAddr)); m_collPktsSent_queue.push_back( pkt); pkt->hdr.collPktSent = true; // create and sent COLL packet_t *collPkt = (packet_t *) createCollPkt( pkt); SendPacket( collPkt, false); // don't change sequence number/*** start timer to remove packet from m_collPktsSent_queue** Make sure the time is greater than endT3Timer.*/ double start = (2 * transitionTime + (1 + numT2Slots + numT3Slots) * slotWidth + AckWindow) * 2 + SimTime(); pkt->hdr.collIndex = endCollTimer.Set( pkt, start); return;}template <class PLD>void SSRv02<PLD>::receiveCollisionPacket( packet_t *collPkt){ packet_queue_t::iterator iter; mwlPrint( ("rCP: ea %3d; %3d->%3d; %s @ %f\n", (int) MyEtherAddr, (int) collPkt->hdr.src_addr, (int) collPkt->hdr.dst_addr, collPkt->dump().c_str(), SimTime()));/*** Search m_send_queue, the list of packets that are waiting to be sent. If the** packet is found, remove it from the queue. If the packet was on the queue,** this means that the packet was scheduled to be forwarded in a later slot and** the collision indicates that there are other nodes who have already tried to** forward it.*/ CancelPacket( collPkt->hdr.src_addr, collPkt->hdr.seq_number);#ifdef MWL_20060430 for( iter = m_send_queue.begin(); iter != m_send_queue.end(); iter++) { mwlPrint( ("rCP: ea %3d; Found %s on m_send_queue\n", (int) MyEtherAddr, (*iter)->dump().c_str())); if( (*iter)->hdr.src_addr == collPkt->hdr.src_addr && (*iter)->hdr.dst_addr == collPkt->hdr.dst_addr && (*iter)->hdr.seq_number == collPkt->hdr.seq_number) break; // match found } if( iter != m_send_queue.end()) { (*iter)->free(); m_send_queue.erase( iter); return; // the packet can't be on the other queue }/*** Should the collision packet cancel the currently active packet?*/ if( m_active_packet->hdr.src_addr == collPkt->hdr.src_addr && m_active_packet->hdr.dst_addr == collPkt->hdr.dst_addr && m_active_packet->hdr.seq_number == collPkt->hdr.seq_number) { CancelPacket( mwl); }#endif //MWL_20060430/*** Search m_T3_queue (the list of packets sent but not yet ACKed) for a packet** with the matching source, destination and sequence number.*/ for( iter = m_T3_queue.begin(); iter != m_T3_queue.end(); iter++) { mwlPrint( ("rCP: ea %3d; Found %s on m_T3_queue\n", (int) MyEtherAddr, (*iter)->dump().c_str())); if( (*iter)->hdr.src_addr == collPkt->hdr.src_addr && (*iter)->hdr.dst_addr == collPkt->hdr.dst_addr && (*iter)->hdr.seq_number == collPkt->hdr.seq_number) break; // match found }/*** If found, cancel timers and remove the original packet from queues.** If this node had forwarded the packet during the slot with the collision,** then attempt again to forward the original packet.*/ if( iter != m_T3_queue.end()) { packet_t *orig = *iter, *newPkt; if( endT1Timer.Active( orig->hdr.t1Index) == true) endT1Timer.Cancel( orig->hdr.t1Index); if( endT2Timer.Active( orig->hdr.t2Index) == true) endT2Timer.Cancel( orig->hdr.t2Index);//mwl if( endT3Timer.Active( orig->hdr.t3Index) == true)//mwl endT3Timer.Cancel( orig->hdr.t3Index); if( orig->hdr.slotNumber == collPkt->hdr.slotNumber) { newPkt = orig->copy(); newPkt->hdr.expected_hop++; mwlPrint( ("rCP: Forwarding packet 0x%08X (%3d->%3d) from T3 queue\n", (int) newPkt, (int) newPkt->hdr.src_addr, (int) newPkt->hdr.dst_addr)); ForwardPacket( newPkt); } mwlPrint( ("rCP: ea %3d; freeing 0x%08X\n", (int) MyEtherAddr, (int) orig)); m_T3_queue.remove( orig); orig->free(); } else mwlPrint( ("rCP: ea %3d; not found on m_T3_queue\n", (int) MyEtherAddr)); collPkt->free(); // done with COLL return;}template <class PLD>void SSRv02<PLD>::receiveHelloPacket( packet_t *pkt){/*** Need to do something with the hello packet.** How does a node decide that it needs to send a hello packet?** The spec says that when a node that caused a routing hole comes back on** line, it should send a hello packet. How to determine this.** When receiving this packet, the node will adjust its hop count to (hello** pkt + 1) only if the current hop count >= (hello pkt + 2). If the HC is** changed, this node sends a new hello packet with the adjusted HC.*/ mwlPrint( ("SSRV02::rHP: received HELLO packet @ %f (MWL)\n", SimTime())); pkt->free(); // done with HELLO packet return;}template <class PLD>void SSRv02<PLD>::receiveBackupPacket( packet_t *pkt){ mwlPrint( ("SSRV02::rBP: BACKUP pkt received @ %f (MWL)\n", SimTime())); pkt->free(); // done with BACKUP packet return;}/*** This node has just received an ACK packet.** - If the ACK is for a packet that is scheduled to be transmitted, then** cancel the transmission. (Another node has already forwarded the packet.)** - If the ACK was sent by the destination node, then cancel retransmission of** the packet. This is the equivalent of a node forwarding the packet. The** previous address field in the packet header works for identification.*/template <class PLD>void SSRv02<PLD>::receiveAckPacket( packet_t *pkt){ mwlPrint( ("rA: ea %3d; 0x%08X [%3d, sn%08X] @ %f\n", (int) MyEtherAddr, (int) pkt, (int) pkt->hdr.src_addr, pkt->hdr.seq_number, SimTime())); // cancel pending send CancelPacket( pkt->hdr.src_addr, pkt->hdr.seq_number); // cancel retransmissions if( pkt->hdr.pre_addr == MyEtherAddr) performAck( pkt);// CancelRetransmission( pkt->hdr.src_addr, pkt->hdr.seq_number); return;}template <class PLD>void SSRv02<PLD>::receiveReqRepDataPacket( packet_t *pkt){ cache_t::iterator iter; ether_addr_t src = pkt->hdr.src_addr; updateHopCountInCache( src, pkt->hdr.actual_hop, false, "rRRDP", pkt); iter = m_seq_cache.find( src); /*** The method check (defined at the top of this file) determines if this** sequence number is greater than the sequence number in the cache. If the** packet's sequence number is greater, then this packet is new. This** comparison is not valid for resent packets or DATA or REPLY packets with** the T3 flag set to true.*/ if( iter->second.check( pkt->hdr.seq_number) == false || pkt->hdr.resend != 0 || pkt->hdr.t3Flag == true) { RecvUniPackets++; if( pkt->hdr.dst_addr == MyEtherAddr) recvPktAtDest( pkt, iter); else if( pkt->hdr.actual_hop < pkt->hdr.max_hop) { // create new packet to forward packet_t *np = pkt->copy(); np->hdr.cur_addr = MyEtherAddr; np->hdr.pre_addr = pkt->hdr.cur_addr; np->hdr.resend = 0; np->hdr.numSlots = numT2Slots; np->hdr.collDetected = false; np->hdr.collPktSent = false; // don't reset t3Flag since it's used by ForwardPacket //Printf((DumpPackets,"rr%d creates COPY %s\n",(int)MyEtherAddr,np->dump().c_str())); np->hdr.actual_hop++;#ifdef VISUAL_ROUTE np->hdr.path.AddNode( MyEtherAddr);#endif if( np->hdr.type == REQUEST) { np->hdr.t3Flag = false; //np->hdr.delay=ForwardDelay*(1-RXThresh/power); np->hdr.delay = Random( ForwardDelay); TotalDelay += np->hdr.delay; TotalSamples++; //Printf((DumpPackets,"rr%d forwards REQUEST %s \n",(int)MyEtherAddr, (int)pkt->dump().c_str())); mwlPrint( ("rRRDP: ea %3d forwards REQUEST %s @ %f\n", (int) MyEtherAddr, pkt->dump().c_str(), SimTime())); SendPacket( np, false); }/*** If the destination is found in the cache and the hop count in the cache is** less than the maximum allowed by the received packet, then forward the** packet.*/ else ForwardPacket( np); } } else { // received packet is not new//MWL FLOODING if( pkt->hdr.type != REQUEST) { mwlPrint( ("rRRDP: ea %3d canceling packet @ %f\n", (int) MyEtherAddr, SimTime())); CancelPacket( pkt->hdr.src_addr, pkt->hdr.seq_number); if( determineAckStatus( pkt) == true) performAck( pkt); } } pkt->free(); // done with received packet return;}/******************************************************************* * We are now receiving a packet from the mac layer. *******************************************************************/template <class PLD>void SSRv02<PLD>::from_mac_data( packet_t *pkt, double power){//mwl cache_t::iterator iter;//mwl ether_addr_t src = pkt->hdr.src_addr; RecvPackets++; Printf((DumpPackets,"%d SSRv02: %d %d %s \n", (int) MyEtherAddr, (int) pkt->hdr.cur_addr, (int) MyEtherAddr, pkt->dump().c_str()));#ifdef MWL_PRINT fflush( stdout); switch( pkt->hdr.type) { case REQUEST: case REPLY: case DATA: case ACK: case COLL: case HELLO: case BACKUP: mwlPrint( ("fmd: ea %3d<-%3d %s @ %f\n", (int) MyEtherAddr, (int) pkt->hdr.cur_addr, pkt->dump().c_str(), SimTime())); break; default: mwlPrint( ("fmd: ea %3d; 0x%08X Bad packet type: 0x%08X\n", (int) MyEtherAddr, (int) pkt, pkt->hdr.type)); break; }#endif //MWL_PRINT switch( pkt->hdr.type) { case ACK: receiveAckPacket( pkt); break; case COLL: receiveCollisionPacket( pkt); break; case HELLO: receiveHelloPacket( pkt); break; case BACKUP: receiveBackupPacket( pkt); break; case REQUEST: case REPLY: case DATA: receiveReqRepDataPacket( pkt); break; } return;}template <class PLD>void SSRv02<PLD>::recvPktAtDest( packet_t *pkt, cache_t::iterator iter){ if( pkt->hdr.resend != 0) { mwlPrint( ("rPAD: ea %3d; dropping resent packet 0x%08X %s @ %f\n", (int) MyEtherAddr, (int) pkt, pkt->dump().c_str(), SimTime())); return; } switch( pkt->hdr.type) { // these cases can't happen, but they make the compiler happy case ACK: case HELLO: case COLL: case BACKUP: mwlPrint( ("SSRV02::rPAD: %s received @ %f\n", pkt->dump().c_str(), SimTime())); break; case REQUEST: { packet_t *rp; // send reply without any delay rp = (packet_t *) createReplyPkt( pkt->hdr.src_addr, iter->second.hopCount()); Printf((DumpPackets, "%d SSRv02: %d->%d %s\n", (int) MyEtherAddr, (int) MyEtherAddr, (int) pkt->hdr.src_addr, rp->dump().c_str())); mwlPrint( ("rPAD: ea %d creates REPLY %s @ %f\n", (int) MyEtherAddr, rp->dump().c_str(), SimTime())); // Send reply and check if any packets need to be sent to the src // of the request SendPacket( rp); CheckBuffer( pkt->hdr.src_addr, iter->second.hopCount()); } break; case REPLY: Printf((DumpPackets,"%d SSRv02: %d<-%d %s\n", (int)MyEtherAddr, (int)MyEtherAddr, (int)pkt->hdr.src_addr, pkt->dump().c_str())); mwlPrint( ("rPAD: ea %3d; received REPLY from %4d @ %f\n", (int) MyEtherAddr, (int) pkt->hdr.src_addr, SimTime())); // destination sends Ack after AckWindow SendAck( pkt->hdr.src_addr, MyEtherAddr, pkt->hdr.cur_addr, pkt->hdr.seq_number, AckWindow); CheckBuffer( pkt->hdr.src_addr, iter->second.hopCount());#ifdef VISUAL_ROUTE pkt->hdr.path.AddNode(MyEtherAddr); printf( "VR: %f: 0x%08X %3d->%3d sn%08X %s\n", SimTime(), (int) pkt, (int) pkt->hdr.src_addr, (int) pkt->hdr.dst_addr, pkt->hdr.seq_number, pkt->hdr.path.ToString());#endif //VISUAL_ROUTE break; case DATA: // the packet arrives at its destination // destination sends Ack after AckWindow SendAck( pkt->hdr.src_addr, MyEtherAddr, pkt->hdr.cur_addr, pkt->hdr.seq_number, AckWindow); pkt->inc_pld_ref(); mwlPrint( ("rPAD: ea %3d; data to transport @ %f\n", (int) MyEtherAddr, SimTime())); to_transport( pkt->pld); { int hc = pkt->hdr.actual_hop; TotalHop += hc; if( hc > HCArraySize-1) hc = HCArraySize-1; HopCounts[hc]++; } RecvDataPackets++;#ifdef VISUAL_ROUTE pkt->hdr.path.AddNode(MyEtherAddr);//mwl printf( "%f: %3d->%3d %s\n", SimTime(), (int) pkt->hdr.src_addr,//mwl (int) pkt->hdr.dst_addr, pkt->hdr.path.ToString()); printf( "VR: %f: 0x%08X %3d->%3d sn%08X %s\n", SimTime(), (int) pkt, (int) pkt->hdr.src_addr, (int) pkt->hdr.dst_addr, pkt->hdr.seq_number, pkt->hdr.path.ToString());#endif //VISUAL_ROUTE break; } return;}template <class PLD>int SSRv02<PLD>::mwlGetHC( int addr){ cache_t::iterator iter; ether_addr_t ea = addr; iter = m_seq_cache.find( ea); return (int) iter->second.hopCount();}template <class PLD>void SSRv02<PLD>::ForwardPacket( packet_t *pkt){ cache_t::iterator iter; double backOffTime; bool forwardPkt; char mwlFlag = pkt->hdr.t3Flag == true ? 'T' : 'F'; int slot, numSlots, h_table, h_pkt; iter = m_seq_cache.find( pkt->hdr.dst_addr); if( iter == m_seq_cache.end()) { mwlPrint( ("FP: ea %3d; from %3d; 0x%08X; sn%08X; %c not in cache\n", (int) MyEtherAddr, (int) pkt->hdr.pre_addr, (int) pkt, pkt->hdr.seq_number, mwlFlag)); pkt->free(); // dest not found, drop packet return; } h_table = iter->second.hopCount(); h_pkt = pkt->hdr.expected_hop - 1; // value in pkt not decremented when sent numSlots = pkt->hdr.numSlots; pkt->hdr.expected_hop = (*iter).second.hopCount();//mwl These lines prevent any packet from every timing out//mwl if( pkt->hdr.max_hop < pkt->hdr.expected_hop + AdditionalHop)//mwl pkt->hdr.max_hop = pkt->hdr.expected_hop + AdditionalHop; if( pkt->hdr.t3Flag == false) { // if h_table == h_pkt-1, then normal case and forward during T2 // T2 is slots 1..numSlots if( h_table == h_pkt) { // When the protocol is modified so that the number of slots is dynamic, // use numSlots from original packet (Future implementation) slot = (int) Random( numSlots); forwardPkt = true; T2PktsSent[ slot]++; slot++; } // if h_table < h_pkt-1, then shorter route, send during T1 // T1 is slot 0 else if( h_table < h_pkt) { slot = 0; forwardPkt = true; T1PktsSent++; } else // major topology change or isolated node; drop packet { DropPkts++; forwardPkt = false; } } else // t3Flag == true { pkt->hdr.t3Flag = false; // pkt no longer T3 enabling // if h_table <= h_pkt-1, then attempt to forward during first slot // This node should have responded T1 or T2 when the original DATA packet // was sent. if( h_table <= h_pkt) { slot = 0; forwardPkt = false; T3AbnormalPktsSent++; mwlPrint( ("FP: ea %3d; from %3d; 0x%08X; sn%08X; T abnormal packet; %2d %2d\n", (int) MyEtherAddr, (int) pkt->hdr.pre_addr, (int) pkt, pkt->hdr.seq_number, h_table, h_pkt)); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -