📄 ashr.h
字号:
newPkt->hdr.t3Flag = false; return newPkt;}template <class PLD>void *SSRv02<PLD>::createDataPkt( payload_t &pld, ether_addr_t dst, unsigned int size){ packet_t *newPkt = (packet_t *) createBasicPkt(); newPkt->hdr.type = DATA; newPkt->hdr.size = size + DATA_SIZE; newPkt->hdr.src_addr = MyEtherAddr; newPkt->hdr.dst_addr = dst; newPkt->hdr.cur_addr = MyEtherAddr; newPkt->hdr.pre_addr = MyEtherAddr; newPkt->pld = pld; return newPkt;}template <class PLD>void *SSRv02<PLD>::createT3Pkt( packet_t *pkt){ packet_t *newPkt = pkt->copy(); assert( pkt->hdr.type == DATA || pkt->hdr.type == REPLY); newPkt->hdr.resend = pkt->hdr.resend + 1; newPkt->hdr.numSlots = numT2Slots; newPkt->hdr.collDetected = false; newPkt->hdr.collPktSent = false; newPkt->hdr.t3Flag = true; return newPkt;}template <class PLD>void *SSRv02<PLD>::createRequestPkt( ether_addr_t dst){ packet_t *newPkt = (packet_t *) createBasicPkt(); newPkt->hdr.type = REQUEST; newPkt->hdr.size = REQUEST_SIZE; newPkt->hdr.expected_hop = 1; newPkt->hdr.max_hop = TimeToLive; newPkt->hdr.src_addr = MyEtherAddr; newPkt->hdr.pre_addr = MyEtherAddr; newPkt->hdr.dst_addr = dst; newPkt->hdr.cur_addr = MyEtherAddr;//mwl newPkt->hdr.delay = AckWindow; return newPkt;}template <class PLD>void *SSRv02<PLD>::createReplyPkt( ether_addr_t src, unsigned int expectedHop){ packet_t *newPkt = (packet_t *) createBasicPkt(); newPkt->hdr.type = REPLY; newPkt->hdr.size = REPLY_SIZE; newPkt->hdr.expected_hop = expectedHop; newPkt->hdr.max_hop = expectedHop + AdditionalHop; newPkt->hdr.src_addr = MyEtherAddr; newPkt->hdr.dst_addr = src; newPkt->hdr.cur_addr = MyEtherAddr; newPkt->hdr.pre_addr = MyEtherAddr; return newPkt;}template <class PLD>void *SSRv02<PLD>::createAckPkt( ether_addr_t src_addr, ether_addr_t cur_addr, ether_addr_t pre_addr, unsigned int seq_number, simtime_t delay){ packet_t *newPkt = (packet_t *) createBasicPkt(); newPkt->hdr.type = ACK; newPkt->hdr.size = ACK_SIZE; newPkt->hdr.src_addr = src_addr; newPkt->hdr.cur_addr = cur_addr; newPkt->hdr.pre_addr = pre_addr; newPkt->hdr.seq_number = seq_number; newPkt->hdr.delay = delay; newPkt->hdr.expected_hop = 0 mwl; // should this be moved to createBasicPkt newPkt->hdr.max_hop = 0; return newPkt;}template <class PLD>void *SSRv02<PLD>::createCollPkt( packet_t *pkt){ packet_t *newPkt = (packet_t *) createBasicPkt(); newPkt->hdr.type = COLL; newPkt->hdr.size = COLL_SIZE; newPkt->hdr.expected_hop = 1; newPkt->hdr.src_addr = pkt->hdr.src_addr; newPkt->hdr.dst_addr = pkt->hdr.dst_addr; newPkt->hdr.cur_addr = pkt->hdr.cur_addr; newPkt->hdr.pre_addr = pkt->hdr.pre_addr; newPkt->hdr.slotNumber = pkt->hdr.slotNumber; newPkt->hdr.seq_number = pkt->hdr.seq_number; return newPkt;}template <class PLD>void *SSRv02<PLD>::createBackupPkt( packet_t *pkt){ packet_t *newPkt = (packet_t *) createBasicPkt(); newPkt->hdr.type = BACKUP; newPkt->hdr.size = BACKUP_SIZE; newPkt->hdr.expected_hop = 1; newPkt->hdr.src_addr = pkt->hdr.src_addr; newPkt->hdr.dst_addr = pkt->hdr.dst_addr; newPkt->hdr.cur_addr = pkt->hdr.cur_addr; newPkt->hdr.pre_addr = pkt->hdr.pre_addr; return newPkt;}template <class PLD>void *SSRv02<PLD>::createHelloPkt(){ packet_t *newPkt = (packet_t *) createBasicPkt(); newPkt->hdr.type = HELLO; newPkt->hdr.size = HELLO_SIZE; newPkt->hdr.expected_hop = 1; newPkt->hdr.src_addr = MyEtherAddr; newPkt->hdr.dst_addr = 0; //what's the dest addr of a hello pkt? newPkt->hdr.cur_addr = MyEtherAddr; newPkt->hdr.pre_addr = MyEtherAddr; return newPkt;}template <class PLD>SSRv02<PLD>::SSRv02(){ connect transitionTimer.to_component, TransitionTimer; connect endT1Timer.to_component, EndT1Timer; connect endT2Timer.to_component, EndT2Timer;//mwl connect endT3Timer.to_component, EndT3Timer; connect endCollTimer.to_component, EndCollTimer; return;}template <class PLD>SSRv02<PLD>::~SSRv02(){ return;}template <class PLD>void SSRv02<PLD>::Start() { m_mac_busy = false;//mwl m_seq_number = 1u; m_seq_number = (int) MyEtherAddr << 16; m_seq_cache.insert( make_pair( MyEtherAddr, seq_number_t())); SentPackets = RecvPackets = RecvUniPackets = 0l; TotalDelay = 0.0; TotalHop = 0; TotalSamples = 0; RecvDataPackets = 0; for( int i = HCArraySize-1; i >= 0; i--) HopCounts[i] = 0; for( int i = MaxT2Slots-1; i >= 0; i--) T2PktsSent[i] = T2Collisions[i] = 0; for( int i = MaxT3Slots-1; i >= 0; i--) T3PktsSent[i] = T3Collisions[i] = 0; DropPkts = T1PktsSent = T3AbnormalPktsSent = 0; T1Collisions = IgnoreCollisions = 0; T1PktsRcvd[0] = 0; T1PktsRcvd[1] = 0; T4PktsRcvd[0] = 0; T4PktsRcvd[1] = 0;//mwl OtherPktsRcvd[0] = 0;//mwl OtherPktsRcvd[1] = 0; CanceledPktsRcvd[0] = 0; CanceledPktsRcvd[1] = 0; BadAddrPktsRcvd[0] = 0; BadAddrPktsRcvd[1] = 0; WrongHopPktsRcvd[0] = 0; WrongHopPktsRcvd[1] = 0; for( int i = MaxT2Slots-1; i>= 0; --i) T2PktsRcvd[0][i] = T2PktsRcvd[1][i] = 0; for( int i = MaxT3Slots-1; i>= 0; --i) T3PktsRcvd[0][i] = T3PktsRcvd[1][i] = 0; return;}template <class PLD>void SSRv02<PLD>::Stop() { //printf("%s: sent %d, recv %d\n",GetName(),SentPackets,RecvPackets); //printf("%s: %f \n", GetName(), (double)RecvPackets/RecvUniPackets); if( m_collPktsSent_queue.size() != 0) { printf( "%3d: contents of m_collPktsSent_queue\n", (int) MyEtherAddr); packet_queue_t::iterator iter = m_collPktsSent_queue.begin(); for( ; iter != m_collPktsSent_queue.end(); iter++) printf( " %s\n", (*iter)->dump().c_str()); //mwl } return;}template <class PLD>void SSRv02<PLD>::from_transport( payload_t &pld, ether_addr_t &dst, unsigned int size){ if( size > 1500) printf( "ft: ea%3d; Oversize packet\n", (int) MyEtherAddr); //create the data packet packet_t *p = (packet_t *) createDataPkt( pld, dst, size); Printf((DumpPackets, "%d SSRv02: %d->%d *%s\n", (int) MyEtherAddr, (int) MyEtherAddr, (int) dst, p->dump().c_str())); mwlPrint( ("ft: %3d->%3d *%s @ %f ea %3d\n", (int) MyEtherAddr, (int) dst, p->dump().c_str(), SimTime(), (int) MyEtherAddr)); cache_t::iterator iter = m_seq_cache.find( dst); if( iter == m_seq_cache.end()) { // the destination is not in the active node table // must send a REQUEST packet first; packet_t *rp = (packet_t *) createRequestPkt( dst); Printf((DumpPackets, "%d SSRv02: %d->%d %s\n", (int) MyEtherAddr, (int) MyEtherAddr, (int) dst, rp->dump().c_str())); mwlPrint( ("ft: (REQ) %3d->%3d %s @ %f ea %3d\n", (int) MyEtherAddr, (int) dst, rp->dump().c_str(), SimTime(), (int) MyEtherAddr)); //printf("rr%d sends a REQUEST to rr%d %s\n",(int)MyEtherAddr,(int)dst,rp->dump().c_str()); SendPacket( rp); m_data_buffer.push_back( p); // add to end of queue } else { // The SSR spec calls for decrementing expected_hop before transmitting. // In SENSE, >1 nodes reference same packet in memory, so can't decrement p->hdr.expected_hop = (*iter).second.hopCount(); p->hdr.max_hop = p->hdr.expected_hop + AdditionalHop; p->hdr.delay = AckWindow; SendPacket( p); }}template <class PLD>void SSRv02<PLD>::SendPacket( packet_t *pkt, bool new_seq){ mwlPrint( ("SP: ea %3d; sending %s @ %f\n", (int) MyEtherAddr, pkt->dump().c_str(), SimTime())); pkt->hdr.canceled = false; if( new_seq && pkt->hdr.src_addr == MyEtherAddr) { m_seq_number++; m_seq_cache[MyEtherAddr].check(m_seq_number); pkt->hdr.seq_number = m_seq_number; //Printf((DumpPackets,"SSRv02%d assigns seq number to %s \n",(int)MyEtherAddr,pkt->dump().c_str()));// mwlPrint( ("SP: ea %3d; assigning sn%08X\n", (int) MyEtherAddr, m_seq_number)); printf( "SP: ea %3d; assigning sn%08X\n", (int) MyEtherAddr, m_seq_number); } SentPackets++; if( m_mac_busy == false) { m_mac_busy = true; m_active_packet = pkt; m_active_packet->inc_ref(); SendToMac( pkt); } else { mwlPrint( ("SP: ea %3d; mac busy\n", (int) MyEtherAddr)); packet_queue_t::iterator iter = m_send_queue.begin(); while( iter != m_send_queue.end() && (*iter)->hdr.delay <= pkt->hdr.delay) iter++; m_send_queue.insert( iter, pkt); } return;}/*** SendToMac was added in February 2006.**** Its purpose is to simulate the small amount of time that elapses between** when the hardware stops sensing the carrier and it is able to actually start** transmission of the packet.**** For backwards compatibility, the transition time may be zero. In this case,** forward the packet directly to the mac layer instead of starting a timer.*/template <class PLD>void SSRv02<PLD>::SendToMac( packet_t *pkt){// mwlPrint( ("STM: %3d->%3d; ea %3d @ %f\n", (int) pkt->hdr.src_addr, (int) pkt->hdr.dst_addr, (int) MyEtherAddr, SimTime())); m_mac_busy = true; if( transitionTime != 0) { // start timer transitionTimer.Set( SimTime() + transitionTime); // save packet transitionPkt = pkt; } else { pkt->hdr.collDetected = false; pkt->hdr.xmit_start_time = SimTime(); to_mac( pkt, pkt->hdr.size, pkt->hdr.delay); } return;}/*** TransitionTimer was added in February 2006.**** Timer has expired indicating that the hardware has finished its transition** from sensing the carrier and is finally starting to transmit the packet.*/int mwl = 0;template <class PLD>void SSRv02<PLD>::TransitionTimer( trigger_t &){ if( (int) MyEtherAddr == 63) mwl++; // send saved packet to mac transitionPkt->hdr.collDetected = false; transitionPkt->hdr.xmit_start_time = SimTime(); to_mac( transitionPkt, transitionPkt->hdr.size, transitionPkt->hdr.delay); transitionPkt = 0; return;}/*** EndT1Timer was added in April 2006.**** Timer has expired indicating that the time is now just past the end of** T1.** If a collision has been detected:** - schedule a COLL** - cancel the T2 and T3 timers** - If there's an associated packet on the collision queue, remove it** - remove the packet from the ack queue*/template <class PLD>void SSRv02<PLD>::EndT1Timer( packet_t *pkt, unsigned int index){ mwlPrint( ("ET1T: ea %3d; 0x%08X %3d->%3d; sn%08X @ %f\n", (int) MyEtherAddr, (int) pkt, (int) pkt->hdr.src_addr, (int) pkt->hdr.dst_addr, pkt->hdr.seq_number, SimTime())); if( pkt->hdr.collDetected == true) sendCollisionPacket( pkt); return;}/*** EndT2Timer was added in April 2006.**** Timer has expired indicating that the time is now just past the end of** T2.** If a collision has been detected (it must have occurred during T2):** - schedule a COLL** - cancel the T2 and T3 timers** - If there's an associated packet on the collision queue, remove it** - remove the packet from the ack queue*/template <class PLD>void SSRv02<PLD>::EndT2Timer( packet_t *pkt, unsigned int ){ mwlPrint( ("ET2T: ea %3d; 0x%08X %3d->%3d; sn%08X @ %f\n", (int) MyEtherAddr, (int) pkt, (int) pkt->hdr.src_addr, (int) pkt->hdr.dst_addr, pkt->hdr.seq_number, SimTime())); if( pkt->hdr.collDetected == true) sendCollisionPacket( pkt); else if( pkt->hdr.resend < MaxResend) { packet_t *newPkt = (packet_t *) createT3Pkt( pkt); newPkt->hdr.delay = 0.0; // don't need AckWindow SendPacket( newPkt, false); // same sequence # m_T3_queue.remove( pkt); // remove old packet from t3 queue pkt->free(); // free old packet newPkt->inc_ref(); // save m_T3_queue.push_back( newPkt); // add new packet to t3 queue } else mwlPrint( ("ET2T: ea %3d; 0x%08X %3d->%3d; sn%08X MaxResent\n", (int) MyEtherAddr, (int) pkt, (int) pkt->hdr.src_addr, (int) pkt->hdr.dst_addr, pkt->hdr.seq_number)); return;}/*** EndCollTimer was added in April 2006.**** The timer has expired indicating that the time is now just past the end** of T3 after sending a COLL. This means that the node didn't overhear a** retransmission of the packet. This in turn means that the other nodes in** range either didn't hear the COLL packet or ignored it. The former could be due** to a collision (nothing to be done about that). The latter happens when the** receiver has already forwarded the packet. In this case, the COLL packet was** a false alarm. So, remove the packet from m_collPktsSent_queue.*/template <class PLD>void SSRv02<PLD>::EndCollTimer( packet_t *pkt, unsigned int index){ packet_queue_t::iterator iter; mwlPrint( ("ECT: 0x%08X %3d->%3d; ea %3d; sn%08X @ %f\n", (int) pkt, (int) pkt->hdr.src_addr, (int) pkt->hdr.dst_addr, (int) MyEtherAddr, pkt->hdr.seq_number, SimTime())); for( iter = m_collPktsSent_queue.begin(); iter != m_collPktsSent_queue.end(); iter++) { 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) break; // match found } m_collPktsSent_queue.erase( iter); (*iter)->free(); pkt->free(); return;}/*** Find the packet's source address in this node's cache. If the entry is not** found, create it. If the hop count in the cache is greater than the hop** count of the packet, update the cache.*/template <class PLD>void SSRv02<PLD>::updateHopCountInCache( ether_addr_t dst, unsigned int hopCount, bool always, // if this is false, only lower hop count const char *str, packet_t *mwl){ cache_t::iterator iter; iter = m_seq_cache.find( dst); // If the destination address is not found, create a new record. if( iter == m_seq_cache.end()) { mwlPrint( ("%s: uHCIC: ea %3d; dst %3d; hc %2d new\n", str, (int) MyEtherAddr, (int) dst, hopCount)); iter = (m_seq_cache.insert( make_pair( dst, seq_number_t()))).first; iter->second.hopCount( hopCount, false); } else if( always == true || iter->second.hopCount() > hopCount) { mwlPrint( ("%s: uHCIC: ea %3d; dst %3d; hc %2d->%2d update", str, (int) MyEtherAddr, (int) dst, iter->second.hopCount(), hopCount)); iter->second.hopCount( hopCount, mwlDoPrint); } return;}/*** A collision has been detected, so send a COLL packet.** - Cancel pending Tx timers** - Cancel Ack timer
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -