📄 ashr.h
字号:
// else h_table > h_pkt-1, longer route, send during T3 // T3 is slots 1..numT3Slots // slot within T3 determined by h_table - h_pkt else if( h_table <= h_pkt + numT3Slots) { slot = h_table - h_pkt; T3PktsSent[ slot]++; forwardPkt = true; } else // major topology change or isolated node; drop packet { DropPkts++; forwardPkt = false; } } // Backoff has been calculated, forward packet if required if( forwardPkt == true) { mwlPrint( ("FP: ea %3d; from %3d; 0x%08X; sn%08X; %c pkt %2d; table %2d; slot %2d\n", (int) MyEtherAddr, (int) pkt->hdr.pre_addr, (int) pkt, pkt->hdr.seq_number, mwlFlag, h_pkt, h_table, slot)); backOffTime = slot * slotWidth + Random( transitionTime); // insert an AckWindow before first slot pkt->hdr.delay = backOffTime + AckWindow; pkt->hdr.slotNumber = slot; SendPacket( pkt, false); } else { mwlPrint( ("FP: ea %3d; from %3d; 0x%08X; sn%08X; %c pkt %2d; table %2d; dropping\n", (int) MyEtherAddr, (int) pkt->hdr.pre_addr, (int) pkt, pkt->hdr.seq_number, mwlFlag, h_pkt, h_table)); pkt->free(); // not forwarding, so free packet } return;}/*** Determine if a packet should generate an ACK packet.** If the packet that was just received is a REPLY or DATA packet, then check** to see if the packet is a rebroadcast of a packet that was sent by this** node. (Packet is on either the m_T3_queue or m_collPktsSent_queue.)** In addition, also gather statistics on the classification of the packet that** was received.*/template <class PLD>bool SSRv02<PLD>::determineAckStatus( packet_t *pkt){ if( pkt->hdr.type == REQUEST) return false; packet_queue_t::iterator iter; packet_t *orig; bool doAck; int i = pkt->hdr.type == REPLY ? 0 : 1; // for stats keeping mwlPrint( ("dAS: ea %3d; Looking %s on m_T3_queue\n", (int) MyEtherAddr, pkt->dump().c_str())); // get original packet from queue of sent packets for( iter = m_T3_queue.begin(); iter != m_T3_queue.end(); iter++) { mwlPrint( ("dAS: ea %3d; Found %s on m_T3_queue\n", (int) MyEtherAddr, (*iter)->dump().c_str())); if( (*iter)->hdr.src_addr == pkt->hdr.src_addr && (*iter)->hdr.dst_addr == pkt->hdr.dst_addr && (*iter)->hdr.seq_number == pkt->hdr.seq_number && (*iter)->hdr.type == pkt->hdr.type) break; // match found } // if not found, check COLL packet queue if( iter == m_T3_queue.end()) { for( iter = m_collPktsSent_queue.begin(); iter!=m_collPktsSent_queue.end(); iter++) { mwlPrint( ("dAS: ea %3d; Found %s on m_collPktsSent_queue\n", (int) MyEtherAddr, (*iter)->dump().c_str())); if( (*iter)->hdr.src_addr == pkt->hdr.src_addr && (*iter)->hdr.dst_addr == pkt->hdr.dst_addr && (*iter)->hdr.seq_number == pkt->hdr.seq_number && (*iter)->hdr.type == pkt->hdr.type) break; // match found } if( iter == m_collPktsSent_queue.end()) return false; mwlPrint( ("dAS: ea %3d; match m_collPktsSent_queue\n", (int) MyEtherAddr)); } else mwlPrint( ("dAS: ea %3d; match m_T3_queue\n", (int) MyEtherAddr)); orig = *iter; doAck = true; if( orig->hdr.canceled == true) CanceledPktsRcvd[i]++; else if( orig->hdr.cur_addr != pkt->hdr.pre_addr) BadAddrPktsRcvd[i]++; else if( orig->hdr.actual_hop+1 != pkt->hdr.actual_hop) WrongHopPktsRcvd[i]++; else { // account for the AckWindow added to forwarding delay double delta = SimTime() - orig->hdr.xmit_end_time - AckWindow; int slot = (int) (delta / slotWidth); if( slot < 1) T1PktsRcvd[i]++; else if( slot <= numT2Slots) T2PktsRcvd[i][ slot - 1]++; else if( slot <= numT2Slots + numT3Slots) T3PktsRcvd[i][ slot - numT2Slots - 1]++; else { // don't want to ack these packets // wait for timer to expire (started in from_mac_ack) doAck = false; T4PktsRcvd[i]++; } if( doAck == true && pkt->hdr.expected_hop != orig->hdr.expected_hop - 1) updateHopCountInCache( orig->hdr.dst_addr, pkt->hdr.expected_hop + 1, true, "dAS", orig); }//mwl else//mwl OtherPktsRcvd[i]++; return doAck;}/*** This node has detected the retransmission of a packet that it had sent.** - Cancel retransmission of the packet** - Send an ACK packet*/template <class PLD>void SSRv02<PLD>::performAck( packet_t *pkt){ CancelRetransmission( pkt->hdr.src_addr, pkt->hdr.seq_number); if( pkt->hdr.pre_addr == MyEtherAddr) //mwl this test shouldn't be needed { mwlPrint( ("pA: ea %3d; 0x%08X; sn%08X; sending ACK\n", (int) MyEtherAddr, (int) pkt, pkt->hdr.seq_number)); SendAck( pkt->hdr.src_addr, MyEtherAddr, MyEtherAddr, pkt->hdr.seq_number, 0.0); } else { mwlPrint( ("pA: ea %3d; 0x%08X; sn%08X; resend<-MaxResend\n", (int) MyEtherAddr, (int) pkt, pkt->hdr.seq_number)); //printf("rr%d receives again %s\n",(int)MyEtherAddr,(*iter)->dump().c_str());// (*iter)->hdr.resend = MaxResend; } return;}/*** A receive-receive collision has been detected.** This will affect every packet on the m_T3_queue since these are the packets** that have yet to be rebroadcast by the next node.*/template <class PLD>void SSRv02<PLD>::from_mac_recv_recv_coll( packet_t *pkt1, packet_t *pkt2){ packet_queue_t::iterator iter; // for each pkt on m_T3_queue for( iter = m_T3_queue.begin(); iter != m_T3_queue.end(); iter++) { packet_t *pkt = *iter; double delta; int slot;/*** determine time slot of collision** Remember, AckWindow is added to the packet's transmission time, so account** for that value here. If a collision occurs before the end of AckWindow, it** must be an external collision, so it is ignored.*/ delta = SimTime() - pkt->hdr.xmit_end_time - AckWindow; if( delta < 0.0) continue; slot = (int) (delta / slotWidth); // record statistics if( slot < 1) T1Collisions++; else if( slot <= numT2Slots) T2Collisions[ slot - 1]++; else if( slot <= numT2Slots + numT3Slots) T3Collisions[ slot - 1 - numT2Slots]++; else IgnoreCollisions++; // record in packet when collision was detected if( slot < 1 + numT2Slots + numT3Slots) { mwlPrint( ("fmrrc: ea %3d; pkt 0x%08X sn%08X st %f @ %f [%d] (%3d, sn%08X; %3d, sn%08X)\n", (int) MyEtherAddr, (unsigned int) (*iter), (*iter)->hdr.seq_number, (*iter)->hdr.xmit_start_time, SimTime(), slot, (int) pkt1->hdr.cur_addr, pkt1->hdr.seq_number, (int) pkt2->hdr.cur_addr, pkt2->hdr.seq_number)); pkt->hdr.collDetected = true; pkt->hdr.slotNumber = slot; } } return;}template <class PLD>void SSRv02<PLD>::CancelPacket( ether_addr_t &src, unsigned int seq_number){// mwlPrint( ("CP: ea %3d; src %3d; sn%08X @ %f\n", (int) MyEtherAddr,// (int) src, seq_number, SimTime())); /* ** 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) { mwlPrint( ("CP: ea %3d; src %3d; sn%08X cancel active @ %f\n", (int) MyEtherAddr, (int) src, seq_number, SimTime())); //Printf((DumpPackets,"rr%d cancels the current packet\n",(int)MyEtherAddr)); m_active_packet->hdr.canceled = true; cancel(); return; } // Now, look for the packet in m_send_queue. packet_queue_t::iterator iter; 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; packet_t *pktFromQ = *iter; // If the pending packet is an ACK, don't cancel it. if( pktFromQ->hdr.type != ACK) { CanceledPackets++;//mwl if( pktFromQ->hdr.suboptimal == true)//mwl CanceledSuboptimal++; pktFromQ->free(); m_send_queue.erase( iter); } return;}/*** Cancel future retransmissions of a packet.** - Remove the packet from the m_T3_queue** - Cancel the T1, T2 & T3 timers** - Remove the packet from the m_collPktsSent_queue*/template <class PLD>void SSRv02<PLD>::CancelRetransmission( ether_addr_t &src, unsigned int seq_number){ packet_queue_t::iterator iter; packet_t *orig; mwlPrint( ("CR: ea %3d; [%3d, sn%08X]\n", (int) MyEtherAddr, (int) src, seq_number));/*** Search m_T3_queue looking for a matching packet. If it is found, then send** an ACK message.*/ for( iter = m_T3_queue.begin(); iter != m_T3_queue.end(); iter++) if( (*iter)->hdr.src_addr == src && (*iter)->hdr.seq_number == seq_number) break; // match found // if found, cancel timers if( iter != m_T3_queue.end()) { orig = *iter; mwlPrint( ("CR: ea %3d; removing 0x%08X from m_T3_queue\n", (int) MyEtherAddr, (int) orig)); // cancel COLL packet timers 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); m_T3_queue.erase( iter); orig->free(); } // if pkt on Coll Sent queue, remove it for( iter = m_collPktsSent_queue.begin(); iter != m_collPktsSent_queue.end(); iter++) if( (*iter)->hdr.src_addr == src && (*iter)->hdr.seq_number == seq_number) break; // match found if( iter != m_collPktsSent_queue.end()) { orig = *iter; mwlPrint( ("CR: ea %3d; removing 0x%08X from m_collPktsSent_queue\n", (int) MyEtherAddr, (int) orig)); if( endCollTimer.Active( orig->hdr.collIndex) == true) endCollTimer.Cancel( orig->hdr.collIndex); m_collPktsSent_queue.erase( iter); orig->free(); } return;}/*** The routing layer has received an acknowledgement from the mac layer.** False indicates that the transmission failed.*/template <class PLD>void SSRv02<PLD>::from_mac_ack( bool flag){ bool dataReply = m_active_packet->hdr.canceled == false && (m_active_packet->hdr.type == REPLY || m_active_packet->hdr.type == DATA); bool testQueue = true; //Printf((DumpPackets,"rr%d receives an ack from mac\n",(int)MyEtherAddr)); // a non-ack packet failed, so resend it /* ** Resending is handled differently with ASHR. The old way (SSR) was to ** always resechedule non-ACK packets. With ASHR, a DATA or REPLY packet that ** is being sent by an intermediate node is not rescheduled. ASHR will send a ** COLL packet at the end of T2. Note that if a collision occurs when the ** source sends a packet, no COLL packet will be sent. Therefore, in this ** case the packet must be rescheduled. */ if( flag == false && m_active_packet->hdr.type != ACK) { if( MyEtherAddr == m_active_packet->hdr.src_addr || (m_active_packet->hdr.type != DATA && m_active_packet->hdr.type != REPLY)) { mwlPrint( ("fma: ea %3d; cur %3d; reschedule %s; @ %f\n", (int) MyEtherAddr, (int) m_active_packet->hdr.cur_addr, m_active_packet->dump().c_str(), SimTime())); //Printf((DumpPackets,"%d resends %s\n", (int)MyEtherAddr,m_active_packet->dump().c_str())); m_active_packet->inc_ref(); SendToMac( m_active_packet); testQueue = false; // just sent to mac, so don't test queue } else { mwlPrint( ("fma: ea %3d; cur %3d; dropping %s; @ %f\n", (int) MyEtherAddr, (int) m_active_packet->hdr.cur_addr, m_active_packet->dump().c_str(), SimTime())); // add to T3 queue m_active_packet->inc_ref(); m_T3_queue.push_back( m_active_packet); } } else { m_active_packet->hdr.xmit_end_time = SimTime(); if( dataReply == true) { double start; mwlPrint( ("fma: ea %3d; Starting timers %3d->%3d; %c; %c; %s @ %f\n", (int) MyEtherAddr, (int) m_active_packet->hdr.src_addr, (int) m_active_packet->hdr.dst_addr, m_active_packet->hdr.type == DATA ? 'D' : m_active_packet->hdr.type == REPLY ? 'R' : '?', m_active_packet->hdr.t3Flag == true ? 'T' : 'F', m_active_packet->dump().c_str(), SimTime())); // start T1, T2 & T3 timers & add pkt to end of queue if( endT1Timer.Active( m_active_packet->hdr.t1Index) == true) mwlPrint( ("fma: ea %3d; sn%08X; T1 (%d) active (%f)\n", (int) MyEtherAddr, m_active_packet->hdr.seq_number, m_active_packet->hdr.t1Index, endT1Timer.GetTime( m_active_packet->hdr.t1Index))); if( endT2Timer.Active( m_active_packet->hdr.t2Index) == true) mwlPrint( ("fma: ea %3d; sn%08X; T2 (%d) active (%f)\n", (int) MyEtherAddr, m_active_packet->hdr.seq_number, m_active_packet->hdr.t2Index, endT2Timer.GetTime( m_active_packet->hdr.t2Index))); start = SimTime() + slotWidth + 2 * transitionTime + AckWindow; m_active_packet->hdr.t1Index = endT1Timer.Set( m_active_packet, start); start += (numT2Slots + 1) * slotWidth; m_active_packet->hdr.t2Index = endT2Timer.Set( m_active_packet, start);//mwl start += numT3Slots * slotWidth;//mwl m_active_packet->hdr.t3Index = endT3Timer.Set( m_active_packet, start); // add to T3 queue m_active_packet->inc_ref(); m_T3_queue.push_back( m_active_packet); } else { mwlPrint( ("fma: ea %3d; dropping !dataReply %3d->%3d; sn %08X @ %f\n", (int) MyEtherAddr, (int) m_active_packet->hdr.src_addr, (int) m_active_packet->hdr.dst_addr, m_active_packet->hdr.seq_number, SimTime())); ; } m_active_packet->free(); } if( testQueue == true) if( m_send_queue.size() != 0) { packet_t *packet = m_send_queue.front(); m_send_queue.pop_front(); mwlPrint( ("fma: ea %3d; 0x%08X; sn %08X from send queue\n", (int) MyEtherAddr, (int) packet, 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 SSRv02<PLD>::SendAck( ether_addr_t src_addr, ether_addr_t cur_addr, ether_addr_t pre_addr, unsigned int seq_number, simtime_t delay){ packet_t *p = (packet_t *) createAckPkt( src_addr, cur_addr, pre_addr, seq_number, delay); Printf((DumpPackets,"%d SSRv02: %d->%d %s\n",(int)MyEtherAddr,(int)cur_addr, (int)pre_addr,p->dump().c_str())); mwlPrint( ("SA: ack %3d->%3d %s @ %f\n", (int) cur_addr, (int) pre_addr, p->dump().c_str(), SimTime())); SendPacket( p, false); return;}template <class PLD>void SSRv02<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++; } return;}template <class PLD>bool SSRv02_Struct<PLD>::hdr_struct::dump( std::string &str) const { static char pkt_type[][10]={ "REQ", "REPLY", "DATA", "ACK", "COLL", "HELLO", "BACK"};//mwl char buffer[30]; char buffer[50];///mwl sprintf( buffer, "0x%08X %s %d->%d %d %d", (int) this, pkt_type[type], sprintf( buffer, "0x%08X %s %c %d->%d sn%08X %d", (int) this, pkt_type[type], t3Flag == true ? 'T' : 'F', (int) src_addr, (int) dst_addr, seq_number, size); str = buffer; return type == DATA;}#endif /*SSRv02_h*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -