📄 shr.h
字号:
** If (this packet updated Z's entry in the cost table)** forward packet w/o election** else** the packet is dropped.*/ else { iter = m_seq_cache.find( np->hdr.dst_addr); if( iter == m_seq_cache.end()) np->free(); else { if( costTableUpdated == true) forwardAsFlood( np); else np->free(); } } } else {/*** TTL exceeded, dropping packet;** Create a copy of the packet solely for the purpose of recording the full** path. This is because pkt is used by other nodes.*/ packet_t *np = pkt->copy(); np->hdr.path.AddNode( MyEtherAddr); visualizer->writePath( (int) np->hdr.src_addr, (int) np->hdr.dst_addr, np->hdr.seq_number, np->hdr.path, false); np->free(); } } } else // packet should be on ack queue { if( pkt->hdr.type == ACK) receiveAck( pkt); else receiveDataRep( pkt); } pkt->free(); return;}template <class PLD>void SHR<PLD>::forwardAsFlood( packet_t *pkt){ // AckWindow doesn't apply when flooding a packet. pkt->hdr.delay = Random( ForwardDelay); TotalDelay += pkt->hdr.delay; TotalSamples++; SendPacket( pkt); return;}/*** The m_ack_list contains a list of packets that have already been sent and** are waiting for acknowledgement.**** The processing for reception of an ACK is:** - if the ACK was initiated by a packet sent by another node (pre_addr != self)** - cancel PKT** - remove PKT from ack queue** - else (this node generated packet that initiated ACK)** - if the ACK is from the destination (cur_addr == dest_addr)** - get packet from ack queue** - Send an ACK. This is the same processing as when node detects that** a packet has been forwarded.** - remove PKT from ack queue** - else (ACK is from an intermediate node)** - ignore the ACK*/template <class PLD>void SHR<PLD>::receiveAck( packet_t *ackPkt){ shrPrint( ("rA: ea %3d; 0x%08X; sn%08X; src %3d; cur %3d; pre %3d @ %f\n", (int) MyEtherAddr, (int) ackPkt, ackPkt->hdr.seq_number, (int) ackPkt->hdr.src_addr, (int) ackPkt->hdr.cur_addr, (int) ackPkt->hdr.pre_addr, SimTime()));#ifndef SHR_ACK CancelPacket( ackPkt->hdr.src_addr, ackPkt->hdr.seq_number);#else // SHR_ACK packet_t *pktFromList; // If the ack is in response to a packet generated by another node if( ackPkt->hdr.pre_addr != MyEtherAddr) { shrPrint( ("rA: ea %3d; sn%08X; Canceling packet\n", (int) MyEtherAddr, ackPkt->hdr.seq_number)); CancelPacket( ackPkt->hdr.src_addr, ackPkt->hdr.seq_number); pktFromList = (packet_t *) getFromAckList( ackPkt); if( pktFromList != NULL) removeFromAckList( pktFromList, true); } else // Ack is in response to packet generated by this node. { pktFromList = (packet_t *) getFromAckList( ackPkt); if( pktFromList != NULL) { // Respond to ack, but only if it's from the destination if( ackPkt->hdr.ackType == AT_Destination) { shrPrint( ("rA: ea %3d; sn%08X; Sending ack\n", (int) MyEtherAddr, ackPkt->hdr.seq_number)); doRouteRepair( pktFromList, ackPkt); SendAck( ackPkt->hdr.src_addr, MyEtherAddr, ackPkt->hdr.cur_addr, ackPkt->hdr.seq_number, 0.0, false); removeFromAckList( pktFromList, true); } } }#endif // SHR_ACK return;}template <class PLD>void SHR<PLD>::receiveDataRep( packet_t *rcvdPkt){ packet_queue_t::iterator iter; packet_t *pktFromList; shrPrint( ("rDR: ea %3d; 0x%08X; sn%08X; src %3d; cur %3d; pre %3d @ %f\n", (int) MyEtherAddr, (int) rcvdPkt, rcvdPkt->hdr.seq_number, (int) rcvdPkt->hdr.src_addr, (int) rcvdPkt->hdr.cur_addr, (int) rcvdPkt->hdr.pre_addr, SimTime())); CancelPacket( rcvdPkt->hdr.src_addr, rcvdPkt->hdr.seq_number); // m_ack_list is for storing packets that need to be ACKed // In theory, an ACK with a previous address of this node should be on the // ack list, but it's possible for things to get out of sync. pktFromList = (packet_t *) getFromAckList( rcvdPkt); // If packet wasn't found, there's nothing to do. if( pktFromList == NULL) return; if( rcvdPkt->hdr.pre_addr == MyEtherAddr) { doRouteRepair( pktFromList, rcvdPkt); SendAck( rcvdPkt->hdr.src_addr, MyEtherAddr, rcvdPkt->hdr.cur_addr, rcvdPkt->hdr.seq_number, 0.0, false); removeFromAckList( pktFromList, true); } else // forwarding of packet from another node { shrPrint( ("rDR: ea %3d; 0x%08X; sn%08X; resend <- %d; iter %3d<-%3d; " "pkt %3d<-%3d\n", (int) MyEtherAddr, (unsigned int) pktFromList, pktFromList->hdr.seq_number, MaxResend, (int) pktFromList->hdr.cur_addr, (int)pktFromList->hdr.pre_addr, (int) rcvdPkt->hdr.cur_addr, (int) rcvdPkt->hdr.pre_addr)); pktFromList->hdr.resend = MaxResend; } return;}template <class PLD>void *SHR<PLD>::getFromAckList( packet_t *pkt){ packet_queue_t::iterator iter; // m_ack_list is for storing packets that need to be ACKed for( iter = m_ack_list.begin(); iter != m_ack_list.end(); iter++) if( (*iter)->hdr.src_addr == pkt->hdr.src_addr && (*iter)->hdr.seq_number == pkt->hdr.seq_number) break; if( iter != m_ack_list.end()) return *iter; return NULL;}template <class PLD>void SHR<PLD>::removeFromAckList( packet_t *pkt, bool cancelTimer){ shrPrint( ("rFAL: ea %3d; sn%08X\n", (int) MyEtherAddr, pkt->hdr.seq_number)); if( cancelTimer == true) { ackTimer.Cancel( pkt->hdr.ackIndex); pkt->free(); } m_ack_list.remove( pkt); return;}template <class PLD>void SHR<PLD>::doRouteRepair( packet_t *pktFromList, packet_t *rcvdPkt){ if( RouteRepairEnabled == false || rcvdPkt->hdr.expected_hop == pktFromList->hdr.expected_hop - 1) return; const char *str; switch( rcvdPkt->hdr.type) { case ACK: str = "dAS-ack"; break; case DATA: str = "dAS-data"; break; case REPLY: str = "dAS-reply"; break; default: str = "dAS-other"; break; } updateHopCountInCache( pktFromList->hdr.dst_addr, rcvdPkt->hdr.expected_hop + 1, Always, str, rcvdPkt); return;}template <class PLD>int SHR<PLD>::getHCFromCostTable( int addr){ cache_t::iterator iter; ether_addr_t ea = addr; iter = m_seq_cache.find( ea); return (int) iter->second.hopCount();}/*** Receive notification of receive-receive collisions. This must be defined** since the cxx compiler doesn't support #ifdef.*/template <class PLD>void SHR<PLD>::from_mac_recv_recv_coll( packet_t *pkt1, packet_t *pkt2){// addToNeighborMatrix( (int) pkt1->hdr.pre_addr, (int) MyEtherAddr);// addToNeighborMatrix( (int) pkt2->hdr.pre_addr, (int) MyEtherAddr); shrPrint( ("fmrrc: ea %3d; sn%08X (%3d) & sn%08X (%3d) @ %f\n", (int) MyEtherAddr, pkt1->hdr.seq_number, (int) pkt1->hdr.cur_addr, pkt2->hdr.seq_number, (int) pkt2->hdr.cur_addr, SimTime())); return;}template <class PLD>void SHR<PLD>::CancelPacket( ether_addr_t &src, unsigned int seq_number){ /* ** If the incoming packet is the same as the outgoing packet, cancel the ** outgoing packet. But, if the outgoing packet is an ACK, don't cancel it. ** This prevents the case of a slightly delayed DATA (or REPLY) packet that ** doesn't cause a collision from cancelling an ACK. */ if( m_mac_busy == true && m_active_packet->hdr.src_addr == src && m_active_packet->hdr.seq_number == seq_number && m_active_packet->hdr.type != ACK) {// shrPrint( ("CP: ea %3d; in progress 0x%08X; sn%08X\n", (int) MyEtherAddr, (unsigned int) m_active_packet, m_active_packet->hdr.seq_number)); //Printf((DumpPackets,"rr%d cancels the current packet\n",(int)MyEtherAddr)); CanceledPackets++; if( m_active_packet->hdr.suboptimal == true) CanceledSuboptimal++; m_active_packet->hdr.canceled = true; cancel(); return; } packet_queue_t::iterator iter; packet_t *pktFromQ; // Now, look for the packet in the backoff list // Packets sourced from this node don't have a sequence number, but those // packets won't be cancelled. for( iter = m_delay_list.begin(); iter != m_delay_list.end(); iter++) if( (*iter)->hdr.src_addr == src && (*iter)->hdr.seq_number == seq_number) break; if( iter != m_delay_list.end()) { shrPrint( ("CP: ea %3d; 0x%08X; sn%08X; %f\n", (int) MyEtherAddr, (unsigned int) *iter, (*iter)->hdr.seq_number, SimTime())); pktDelayTimer.Cancel( (*iter)->hdr.pktDelayIndex); (*iter)->free(); m_delay_list.erase( iter); return; } // Now, look for the packet in m_send_queue. for( iter = m_send_queue.begin(); iter != m_send_queue.end(); iter++) if( (*iter)->hdr.src_addr == src && (*iter)->hdr.seq_number == seq_number) break; // If not found, then nothing to do. if( iter == m_send_queue.end()) return; pktFromQ = *iter; // If the pending packet is an ACK, don't cancel it. if( pktFromQ->hdr.type != ACK) { CanceledPackets++; if( pktFromQ->hdr.suboptimal == true) CanceledSuboptimal++; pktFromQ->free(); m_send_queue.erase( iter); } return;}/*** The routing layer has received an acknowledgement from the mac layer.** False indicates that the transmission failed.*/template <class PLD>void SHR<PLD>::from_mac_ack( bool flag){ bool testQueue = true; bool slotted = continuousBackOff == false && (MyEtherAddr != m_active_packet->hdr.src_addr) ? true : false; //Printf((DumpPackets,"rr%d receives an ack from mac\n",(int)MyEtherAddr)); // a non-ack packet failed, so resend it /* ** Continuous and slotted SSR handle resending differently. ** ** Continuous: Just send the packet back to the MAC layer. ** ** Slotted: Intermediate nodes delay the packet until the start of the next ** slot. Source nodes behave as continuous SSR. */ if( flag == false && m_active_packet->hdr.type != ACK) { //Printf((DumpPackets,"%d resends %s\n", (int)MyEtherAddr,m_active_packet->dump().c_str())); if( slotted == true) { m_active_packet->hdr.delay = slotWidth; SendPacket( m_active_packet); } else {// printf( "fma: rescheduling\n"); m_active_packet->hdr.delay = 0; m_active_packet->inc_ref(); SendToMac( m_active_packet); testQueue = false; // just sent to mac, so don't test queue } } else {#ifdef SHR_ACK// Because RREP packets are now flooded, they no longer put onto the ack queue. if( m_active_packet->hdr.canceled == false && m_active_packet->hdr.type == DATA && m_active_packet->hdr.actual_hop < m_active_packet->hdr.max_hop-1) { m_active_packet->inc_ref(); m_active_packet->hdr.ackIndex = ackTimer.Set( m_active_packet, SimTime() + MWLTimeoutMultiplier *#ifdef MWL_DOUBLE_DELAY (1<<m_active_packet->hdr.resend) *#endif // MWL_DOUBLE_DELAY ForwardDelay); m_ack_list.push_back( m_active_packet); }#endif //SHR_ACK m_active_packet->free(); } if( testQueue == true) if( m_send_queue.size()) { packet_t *packet = m_send_queue.front(); m_send_queue.pop_front(); shrPrint( ("fma: ea %3d; sn%08X; sending from queue\n", (int)MyEtherAddr, packet->hdr.seq_number)); //Printf((DumpPackets,"rr%d forwards %s from queue\n",(int)MyEtherAddr,packet->dump().c_str())); m_active_packet = packet; m_active_packet->inc_ref(); SendToMac( packet); } else m_mac_busy = false; return;}template <class PLD>void SHR<PLD>::AckTimer( packet_t *pkt, unsigned int){ shrPrint( ("AT: ea %3d; 0x%08X; sn%08X; resend %d\n", (int) MyEtherAddr, (unsigned int) pkt, pkt->hdr.seq_number, pkt->hdr.resend)); removeFromAckList( pkt, false); // Need to resend the packet, but do it without any delay pkt->hdr.delay = 0; if( pkt->hdr.resend < MaxResend) { //Printf((DumpPackets,"rr%d resends %s\n",(int)MyEtherAddr,pkt->dump().c_str())); pkt->hdr.resend++; SendPacket( pkt); }}template <class PLD>void SHR<PLD>::SendAck( ether_addr_t src_addr, ether_addr_t cur_addr, ether_addr_t pre_addr, unsigned int seq_number, simtime_t delay, bool fromDest){ packet_t *pkt = (packet_t *) createAckPkt( src_addr, cur_addr, pre_addr, seq_number, delay, fromDest); Printf( (DumpPackets, "%d SHR: %d->%d %s\n", (int) MyEtherAddr, (int)cur_addr, (int) pre_addr, pkt->dump().c_str())); shrPrint( ("SA: sn%08X; %3d->%3d %s @ %f\n", seq_number, (int) cur_addr, (int) pre_addr, pkt->dump().c_str(), SimTime())); SendPacket( pkt); return;}template <class PLD>void SHR<PLD>::CheckBuffer( ether_addr_t src_addr, unsigned int expected_hop){ packet_queue_t::iterator db_iter; db_iter = m_data_buffer.begin(); while(db_iter != m_data_buffer.end()) { if( (*db_iter)->hdr.dst_addr == src_addr) { packet_queue_t::iterator t=db_iter; db_iter++; (*t)->hdr.expected_hop = expected_hop; (*t)->hdr.max_hop = expected_hop + AdditionalHop; (*t)->hdr.delay = AckWindow; SendPacket( *t); m_data_buffer.erase( t); } else db_iter++; }}template <class PLD>bool SHR_Struct<PLD>::hdr_struct::dump( std::string &str) const { static char pkt_type[5][10] = { "REQ", "REPLY", "DATA", "ACK", "HELLO"}; char buffer[30]; sprintf( buffer, "%s %d->%d %d %d", pkt_type[type], (int) src_addr, (int) dst_addr, seq_number, size); str = buffer; return type == DATA;}#endif /*_shr_h_*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -