📄 wimedia.cc
字号:
} QRemoveUnAckedPacket(p); discard(p, DROP_MAC_RETRY_COUNT_EXCEEDED); p = 0; printf("WiMedia.cc CheckRetransmission() DATA discarded: Maximum retry count exceeded\n"); slrc_ = 0; } else { if(current_traffic_type_ != Traffic_NRT) { if(SendPacket(p, defer_duration) != -1) ++slrc_; } } return 0;} int Mac_WiMedia::CheckQueues(double defer_duration, MacState state) { // printf("current_slot_end_time_ :: %f\nScheduler::instance().clock() :: %f\n", current_slot_end_time_, Scheduler::instance().clock()); if(current_slot_end_time_ < Scheduler::instance().clock()) { printf("WiMedia.cc: CheckQueue() This is not the time to check the queue\n"); return -1; } // Dapeng Debug // printf("WiMedia.cc: CheckQueue() the flowid is %d\n", current_flowid_); if(current_flowid_ == -1) return -1; if(current_traffic_type_ == Traffic_NRT) { CheckNRTQueue(false); printf("WiMedia.cc: CheckQueue() CheckQueue should not be called\n"); exit(1); return -1; } if(state == MAC_WAIT_DELAYEDACK) { struct hdr_cmn *ch = HDR_CMN(pktNULL_); struct hdr_mac *mh = HDR_MAC(pktNULL_); ch->size() = TotalLen_Header(); ch->uid() = 0; ch->ptype() = PT_MAC; ch->error() = 0; mh->ftype_ = MF_NULL; mh->macDA_ = 0; mh->macSA_ = index_; mh->bRequestDelayedAck_ = true; double remaining = current_slot_end_time_ - Scheduler::instance().clock(); double timeout = TxTime(pktNULL_) + macmib_->sifs + macmib_->sifs + defer_duration; if(timeout >= remaining) { printf("WiMedia.cc: CheckQueue() - Not enough time to send a NULL packet\n"); return -1; } tx_state_ = MAC_WAIT_DELAYEDACK; struct hdr_ip *ih = HDR_IP(pktNULL_); mh->qs_ = QPacketCount(current_flowid_) + QUnAckedPacketCount(current_flowid_); mh->stream_index_ = (u_char)current_flowid_; ih->fid_ = current_flowid_; printf("WiMedia.cc: CheckQueue() - Sending a Null DELAYED REQUEST packet the the defer timer\n"); if(defer_duration == 0) Transmit(pktNULL_, timeout); else { if(mhDefer_.busy()) { printf("WiMedia.cc: CheckQueue() - Defer Timer is busy, can not send a request packet\n"); return -1; } else { mhDefer_.timeout_ = timeout; mhDefer_.pktSend_ = pktNULL_; mhDefer_.start(defer_duration); } } } else { if(current_ack_type_ == ACK_Immediate) { int ret = CheckRetransmission(defer_duration, state); if(ret == -1) return -1; } if(packet_queue_[current_flowid_].size() == 0) return -1; Packet *p = QGetNextPacket(current_flowid_); if(p != 0) { if((flow_list_[current_flowid_].flow_id_ != current_flowid_) || (flow_list_[current_flowid_].bFlowOut_ != true)) { printf("WiMedia.cc: CheckQueue() - Flow ID %d is not a registered flow\n", current_flowid_); exit(1); } if((QUnAckedPacketCount(current_flowid_) == (flow_list_[current_flowid_].nMaxAcks_ -1)) && (flow_list_[current_flowid_].ack_type_ == ACK_Delayed)) { hdr_mac* mhTemp1 = HDR_MAC(p); mhTemp1->bRequestDelayedAck_ = true; } else { hdr_mac* mhTemp1 = HDR_MAC(p); mhTemp1->bRequestDelayedAck_ = false; } if(SendPacket(p, defer_duration) != -1) { QRemovePacket(p); QAddUnAckedPacket(p); } } else return -1; } return 0;}int Mac_WiMedia::CheckNRTQueue(bool bIdle) { Packet *p; if(mhBackoff_.busy() && (!mhBackoff_.paused())) return 0; if(!is_idle()) return -1; if(mhBackoff_.paused()) mhBackoff_.resume(); else { // printf("current_slot_end_time_ is %f\nScheduler::instance().clock() is %f\n", current_slot_end_time_, Scheduler::instance().clock()); if(current_slot_end_time_ < Scheduler::instance().clock()) return -1; if(current_traffic_type_ != Traffic_NRT) return -1; if(unacked_queue_[current_flowid_].size() != 0) { p = QGetNextUnAckedPacket(current_flowid_, true); if(p == 0) return -1; hdr_cmn *ch = HDR_CMN(p); hdr_mac *mh = HDR_MAC(p); hdr_ip *ih = HDR_IP(p); if((u_int32_t)mh->macDA_ == (u_int32_t)MAC_BROADCAST) { if(ih->daddr() == (nsaddr_t)IP_BROADCAST) { QRemoveUnAckedPacket(p); Packet::free(p); p = 0; return -1; } } if(slrc_ > macmib_->LongRetryLimit) { macmib_->FailedCount++; if(ch->xmit_failure_) { ch->size() -= TotalLen_Header(); ch->xmit_reason_ = XMIT_REASON_ACK; ch->xmit_failure_(p->copy(), ch->xmit_failure_data_); } QRemoveUnAckedPacket(p); discard(p, DROP_MAC_RETRY_COUNT_EXCEEDED); p = 0; slrc_ = 0; } else { mhBackoff_.start(cw_, bIdle); return 0; } } // Dapeng Modified Here if(packet_queue_[current_flowid_].size() == 0) return -1; p = QGetNextPacket(current_flowid_); if(p != 0) { mhBackoff_.start(cw_, bIdle); return 0; } else return -1; } return -1;}void Mac_WiMedia::Transmit(Packet *p, double t) { tx_active_ = 1; if(rx_state_ != MAC_IDLE) { struct hdr_cmn *ch = HDR_CMN(pktRx_); ch->error() = 1; } // end of if downtarget_->recv(p->copy(), this); mhIF_.start(TxTime(p)); mhSend_.start(t);}int Mac_WiMedia::SendBeacon(Packet *p) { struct hdr_mac *mh = HDR_MAC(p); mh->ftype_ = MF_BEACON; double timeout = TxTime(p); if(!is_idle()) { collision(p); return 0; } tx_state_ = MAC_POLLING; Transmit(p, timeout); return 0;}void Mac_WiMedia::OnSendTimer() { switch(tx_state_) { case MAC_SEND: tx_resume(0); break; case MAC_WAIT_DELAYEDACK: tx_resume(0); break; case MAC_SEND_CONTINUE: tx_resume(0); case MAC_ACK: Packet::free(pktACK_); pktACK_ = 0; tx_resume(macmib_->sifs); break; case MAC_POLLING: // printf("OnSendTimer called by MAC_POLLING\n"); tx_resume(macmib_->sifs); break; default: printf("Error in MAC_801_15\n"); break; } // end of switch}void Mac_WiMedia::OnIFTimer() { tx_active_ = 0;}void Mac_WiMedia::OnBeaconTimer() { if(isPNC_ && pnc_) pnc_->OnBeaconTimer(&mhBeacon_); else { printf("OnBeaconTimer: Beacon Timer is running even though I am not a PNC! Quitting programming\n"); exit(1); }}void Mac_WiMedia::OnDeferTimer() { printf("Mac_WiMedia->OnDeferTimer\n"); Transmit(mhDefer_.pktSend_, mhDefer_.timeout_);}void Mac_WiMedia::OnTDMATimer() { current_slot_end_time_ = Scheduler::instance().clock() + schedule_info_.gts_duration_[next_gts_] * 1e-6; current_flowid_ = schedule_info_.gts_flowid_[next_gts_]; current_traffic_type_ = schedule_info_.gts_traffic_type_[next_gts_]; current_ack_type_ = schedule_info_.gts_ack_type_[next_gts_]; mhBackoff_.pause(); tx_resume(0); ++next_gts_; // Dapeng Debug // printf("WiMedia.cc >> OnTDMATimer :: schedule_info_.flow_count_ is %d, next_gts_ is %d\n", schedule_info_.flow_count_, next_gts_); if(schedule_info_.flow_count_ > next_gts_) { // Dapeng Debug //printf("recursive calling OnTDMATimer\n"); mhTDMA_.start(schedule_info_.gts_start_[next_gts_] * 1e-6 - (Scheduler::instance().clock() - beacon_offset_)); }}bool Mac_WiMedia::IsStillValid(Packet *p) { struct hdr_ip* ih = HDR_IP(p); int flowid = ih->fid_; if(flowid > MAX_FLOWS || flowid < 0) { printf("WiMedia.cc:IsStillValid()-> Invalid flowid %d\n", flowid); exit(1); } if(flow_list_[flowid].deadline_ == 0) return true;// struct hdr_cmn* ch = HDR_CMN(p); struct hdr_mac* mh = HDR_MAC(p); if(Scheduler::instance().clock() > (mh->timestamp_ + flow_list_[flowid].deadline_)) { printf("WiMedia.cc:IsStillValid()-> Packet %d expired\n", mh->seq_no_); return false; } return true;}Packet* Mac_WiMedia::QGetNextPacket(int flowid) { if(flowid >= MAX_FLOWS || flowid < 0) { printf("WiMedia.cc: QGetNextPacket()->Invalid flowid(%d)\n", flowid); exit(1); } list <Packet*>::iterator i = packet_queue_[flowid].begin(); list <Packet*>::iterator iEnd = packet_queue_[flowid].end(); while(i != iEnd) {// hdr_ip *ih = HDR_IP(*i); if(IsStillValid(*i)) { flow_list_[flowid].qs_ = packet_queue_[flowid].size(); return *i; } else { printf("WiMedia.cc: QGetNextPacket()-> Packet expired. Packet dropped\n"); Packet::free(*i); i = packet_queue_[flowid].erase(i); iEnd = packet_queue_[flowid].end(); } } flow_list_[flowid].qs_ = packet_queue_[flowid].size(); return 0;}Packet* Mac_WiMedia::QGetNextUnAckedPacket(int flowid, bool bCheckDeadline) { if(flowid >= MAX_FLOWS || flowid < 0) { printf("WiMedia.cc: QGetNextPacket()->Invalid flowid(%d)\n", flowid); exit(1); } // End of if list <Packet*>::iterator i = unacked_queue_[flowid].begin(); list <Packet*>::iterator iEnd = unacked_queue_[flowid].end(); while(i !=iEnd) { if(!bCheckDeadline) return *i; else { if(IsStillValid(*i)) return *i; else { printf("WiMedia.cc::QGetNextUnAckedPacket() - Unacked packet expired. Packet dropped\n"); Packet::free(*i); i = unacked_queue_[flowid].erase(i); iEnd = unacked_queue_[flowid].end(); return 0; } // End of ifelse } // End of ifelse } // End of While return 0;}void Mac_WiMedia::OnBackoffTimer(){ printf("WiMedia.cc->OnBackoffTimer called\n"); if(is_idle()) { Packet *p = QGetNextUnAckedPacket(current_flowid_, true); if(p != 0) { if(SendPacket(p, 0) != -1) { if(slrc_ > 1) increment_cw(); } } else { p = QGetNextPacket(current_flowid_); if(p != 0) { if(SendPacket(p, 0) != -1) { QRemovePacket(p); QAddUnAckedPacket(p); } else CheckNRTQueue(false); } } } else { printf("WiMedia.cc->OnBackoffTimer() - BACKOFF TIMER SCREWED UP!! Exitting\n"); exit(1); }}void Mac_WiMedia::rx_resume() { rx_state_ = MAC_IDLE;}void Mac_WiMedia::recvBeacon(Packet *p) { // Dapeng Debug // printf("WiMedia.cc->recvBeacon() - Fully receive a beacon\n"); stats_.ReceiveBeaconFromLower(index_, p); struct hdr_mac *mh = HDR_MAC(p); beacon_offset_ = Scheduler::instance().clock(); schedule_info_.flow_count_ = 0; // Dapeng Debug // printf("mh->beacon_.cta_count is %d\n", mh->beacon_.cta_count); for(int i = 0; i < mh->beacon_.cta_count; i++) { struct InfoElement_CTA &cta = mh->beacon_.cta[i]; // Dapeng Debug // printf("cta.src_id_ is %d, and index_ is %d\n", cta.src_id_, index_); if(cta.src_id_ == index_ || cta.traffic_type_ == Traffic_NRT) { schedule_info_.gts_start_[schedule_info_.flow_count_] = cta.slot_location_; schedule_info_.gts_duration_[schedule_info_.flow_count_] = cta.slot_duration_; schedule_info_.gts_flowid_[schedule_info_.flow_count_] = cta.stream_idx_; schedule_info_.gts_traffic_type_[schedule_info_.flow_count_] = cta.traffic_type_; schedule_info_.gts_ack_type_[schedule_info_.flow_count_] = cta.ack_type_; ++schedule_info_.flow_count_; } } // Dapeng Debug // printf("schedule_info_.flow_count is %d\n", schedule_info_.flow_count_); if(schedule_info_.flow_count_ > 0) { next_gts_ = 0; mhTDMA_.start(schedule_info_.gts_start_[next_gts_]*1e-6 - (Scheduler::instance().clock() - beacon_offset_)); } Packet::free(p); // Dapeng Debug // printf("WiMedia.cc >> recvBeacon() finished, during which a the TDMA_Timer has been started up\n");}void Mac_WiMedia::ACKPacketsInArray(int flowid, int* nAckArray, int nAckCount) { nAckCount = nAckCount * 3; tx_state_ = MAC_SEND_CONTINUE; printf("WiMedia.cc->ACKPacketsInArray() - Flowid = %d, Packets ACKed\n", flowid); list <Packet *>::iterator i = unacked_queue_[flowid].begin(); list <Packet *>::iterator iEnd = unacked_queue_[flowid].end(); while(i != iEnd) { Packet *pktUnAcked = (*i); struct hdr_mac *mhUnAcked = HDR_MAC(pktUnAcked); int nIdx = 0; bool bDeleted = false; while(nAckArray[nIdx + 0] != -1) { // The following line has been modified by Dapeng if((u_int32_t)nAckArray[nIdx + 0] == mhUnAcked->seq_no_) { if((nAckArray[nIdx + 2] > 0) && (nAckArray[nIdx + 1] == mhUnAcked->frag_seq_)) { Packet::free(pktUnAcked); i = unacked_queue_[flowid].erase(i); iEnd = unacked_queue_[flowid].end(); bDeleted = true; pktUnAcked = 0; break; } else if(!(nAckArray[nIdx + 2] > 0)) { Packet::free(pktUnAcked); i = unacked_queue_[flowid].erase(i); iEnd = unacked_queue_[flowid].end(); bDeleted = true; pktUnAcked = 0; break; } } nIdx += 3; if(nAckCount > 0) { if(nIdx >= nAckCount) { break; } } } if(!bDeleted) ++i; } // Move the remaining packets to the queue list <Packet *>::reverse_iterator r = unacked_queue_[flowid].rbegin(); list <Packet *>::reverse_iterator rEnd = unacked_queue_[flowid].rend(); while(r != rEnd) { packet_queue_[flowid].push_front((*r)); ++r; } unacked_queue_[flowid].clear();}void Mac_WiMedia::ParseAckInfoInBeacon(Packet *p) { struct hdr_mac *mhBeacon = HDR_MAC(p); int nOffset = 0; int flowid = mhBeacon->beacon_.ms_acked_seqno_[0]; int prevFlowid = flowid; int i; for(i = 0; i < MAX_ACKED_IN_BEACON; i++) { flowid = mhBeacon->beacon_.ms_acked_seqno_[i]; if(flowid == -1) break; if(flowid != prevFlowid) { if((flow_list_[prevFlowid].flow_id_ == prevFlowid) && (flow_list_[prevFlowid].bFlowOut_ == true) && (flow_list_[prevFlowid].ack_type_ == ACK_Beacon)) { if(i > nOffset) ACKPacketsInArray(prevFlowid, (int*)((&mhBeacon->beacon_.ms_acked_packets_[nOffset][0])), (i - nOffset)); } nOffset = i; prevFlowid = flowid; } } // End of for if((flow_list_[prevFlowid].flow_id_ = prevFlowid) && (flow_list_[prevFlowid].bFlowOut_ == true) && (flow_list_[prevFlowid].ack_type_ == ACK_Beacon) && (i > nOffset) && (prevFlowid != -1)) ACKPacketsInArray(prevFlowid, (int *)(&(mhBeacon->beacon_.ms_acked_packets_[nOffset][0])), (i - nOffset));}void Mac_WiMedia::recvMSBeacon(Packet *p) { ParseAckInfoInBeacon(p); recvBeacon(p);}void Mac_WiMedia::recvACK(Packet *p) { last_ack_received_ = Scheduler::instance().clock(); struct hdr_mac *mh = HDR_MAC(p); if((tx_state_ != MAC_SEND) && (tx_state_ != MAC_WAIT_DELAYEDACK)) { discard(p, DROP_MAC_INVALID_STATE); return; } stats_.ReceiveAckFromLower(index_, p); if(mh->ack_type_ == ACK_Immediate) { Packet *pktUnAcked = QGetNextUnAckedPacket(current_flowid_, false); if(pktUnAcked == 0) { discard(p, DROP_MAC_INVALID_STATE); return; } QRemoveUnAckedPacket(pktUnAcked); cw_ = CW_MIN; Packet::free(pktUnAcked); pktUnAcked = 0; mhSend_.stop(); Packet::free(p); slrc_ = 0; // Dapeng Debug // printf("tx_resume called by recvACK\n"); tx_resume(macmib_->sifs); } else if(mh->ack_type_ == ACK_Delayed) { ACKPacketsInArray(current_flowid_, (int *)mh->acked_packets_, -1); cw_ = CW_MIN; mhSend_.stop(); Packet::free(p); slrc_ = 0; tx_resume(macmib_->sifs); }}void Mac_WiMedia::SendDataToUp(Packet *p) {// 2007-6-9 struct hdr_ip *ih = HDR_IP(p); int flowid = ih->fid_; struct hdr_mac *mh = HDR_MAC(p); struct hdr_cmn *ch = HDR_CMN(p); // int dst = mh->macDA_; int src = mh->macSA_; ch->num_forwards() += 1; if((ih->dst_).addr_ != index_) return;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -