?? wimedia.cc
字號:
#include "delay.h"#include "connector.h"#include "packet.h"#include "random.h"#include "mobilenode.h"// #define DEBUG 99#include "arp.h"#include "ll.h"#include "mac.h"#include "mac-timers.h"#include "cmu-trace.h"// Added by Sushmita to support event tracing#include "agent.h"#include "basetrace.h"// #include "WiMedia_pnc.h"#include "WiMedia.h"#include "WiMedia_pnc.h"#include "WiMedia_stats.h"#include "WiMedia_defs.h"#define dapeng 99/* Globals *//* PNC: Piconet Coordinator - First created node is set to be the PNC! */PNC *pnc_ = 0;// Ussd to generate traffic statisticsMacStatsGenerator stats_;// MAC Magement Information BaseMacMib global_macmib_;/* ==================================== TCL Hooks for the simulator ==================================== */static class Mac_WiMedia_Class : public TclClass {public: Mac_WiMedia_Class() : TclClass("Mac/WiMedia") {} TclObject* create(int, const char*const*) { return (new Mac_WiMedia(&global_macmib_)); }} class_mac_WiMedia;/* ====================================== Mac Class Functions: Construct a Mac() ====================================== */Mac_WiMedia::Mac_WiMedia(MacMib *mib) : Mac(), macmib_(mib), mhBeacon_(this), mhIF_(this), mhSend_(this), mhDefer_(this), mhRecv_(this), mhTDMA_(this), mhBackoff_(this), tx_state_(MAC_IDLE), rx_state_(MAC_IDLE), tx_active_(0), pktACK_(0), slrc_(0), cw_(CW_MIN), next_gts_(-1), current_slot_end_time_(0),current_flowid_(-1), last_ack_received_(0), bDoFragmentation_(true), cache_node_count_(0), cache_(0) { if(pnc_ == 0){ isPNC_ = true; pnc_ = new PNC(this, &global_macmib_); } // Announce that the node has joined the PNC pnc_->AddNode(index_); max_frag_size_ = MAX_MAC153_FRAME_LENGTH; // You initialize something when a WiMedia MAC stats. for(int i = 0; i < MAX_FLOWS; i++) { sta_seqno_[i] = 1; fraq_cache_[i] = 0; bResetPToBeAckedOnRx_[i] = false; nNextPacketToUpper_[i] = 1; nNextFragToUpper_[i] = 0; flow_list_[i].flow_id_ = -1; flow_list_[i].ack_type_ = ACK_None; flow_list_[i].nMaxAcks_ = 16; } // End of for // Create the NULL Packet for once pktNULL_ = Packet::alloc(); 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->iface() = -2; ch->error() = 0; mh->macDA_ = 0; mh->macSA_ = index_; mh->ftype_ = MF_NULL; nTotalReceivedFrags_ = 0; nCorruptedReceivedFrags_ = 0; stats_.AddNode(index_);}Mac_WiMedia::~Mac_WiMedia() { Packet::free(pktNULL_);}int Mac_WiMedia::command(int argc, const char*const* argv) { if(argc > 1) { // Forward all the commands that stats with "scheduler" to the scheduler! if(strcmp(argv[1], "scheduler") == 0) { return pnc_->ExecuteCommand(argc, argv); } } if(argc == 3) { if(strcmp(argv[1], "set-scheduler") == 0) { pnc_->SetScheduler(argv[2]); return TCL_OK; } else if(strcmp(argv[1], "log-target") == 0) { logtarget_ = (NsObject*)TclObject::lookup(argv[2]); if(logtarget_ == 0) return TCL_ERROR; return TCL_OK; } else if(strcmp(argv[1], "nodes") == 0) { if(cache_) return TCL_ERROR; cache_node_count_ = atoi(argv[2]); cache_ = new Host2[cache_node_count_ + 1]; for(int i = 0; i < cache_node_count_ + 1; i++) { cache_[i].index_ = 0; for(int j = 0; j < MAX_FLOWS; j++) cache_[i].seqno_[j] = 0; } return TCL_OK; } else if(strcmp(argv[1], "set-pnc-type") == 0) { if(strcmp(argv[2], "802_15_3") == 0) pnc_->SetPNCType(PNC_802_15_3); else if(strcmp(argv[2], "802_11") == 0) pnc_->SetPNCType(PNC_802_11); else { printf("[in WiMedia.cc --- Command()]: PNC Type %s is not defined!\n", argv[2]); exit(1); } return TCL_OK; } } // end of argc=3 else if(argc == 2) { if(strcmp(argv[1], "run-pnc") == 0) { pnc_->StartBeaconing(&mhBeacon_); return TCL_OK; } else if(strcmp(argv[1], "error-stats") == 0) { printf("\n Node ID: %d, Total Received Packets: %d Corrupted: %d Error Rate: %2.3f\n", index_, nTotalReceivedFrags_, nCorruptedReceivedFrags_, (double)((double)nCorruptedReceivedFrags_ / ((double)nTotalReceivedFrags_))); return TCL_OK; } } // end of argc=2 else if(argc == 5) { if(strcmp(argv[1], "add-flow-in") == 0) { int flowid = atoi(argv[2]); stats_.AddFlowIn(index_, flowid, flowid); flow_list_[flowid].flow_id_ = flowid; flow_list_[flowid].bFlowOut_ =false; flow_list_[flowid].nMaxAcks_ = atoi(argv[4]); if(strcmp(argv[3], "NoACK") == 0) flow_list_[flowid].ack_type_ = ACK_None; else if(strcmp(argv[3], "ImmediateACK") == 0) flow_list_[flowid].ack_type_ = ACK_Immediate; else if(strcmp(argv[3], "DelayedACK") == 0) flow_list_[flowid].ack_type_ = ACK_Delayed; else if(strcmp(argv[3], "BeaconACK") == 0) flow_list_[flowid].ack_type_ = ACK_Beacon; return TCL_OK; } } // End of argc == 5 else if(argc == 6){ if(strcmp(argv[1], "add-flow-out") == 0) { int flowid = atoi(argv[2]); double deadline = ((double)atoi(argv[3])); flow_list_[flowid].flow_id_ = flowid; flow_list_[flowid].bFlowOut_ = true; flow_list_[flowid].deadline_ = deadline; flow_list_[flowid].qs_ = 0; flow_list_[flowid].unacked_qs_ = 0; flow_list_[flowid].nMaxAcks_ = atoi(argv[5]); if(strcmp(argv[4], "NoACK") == 0) flow_list_[flowid].ack_type_ = ACK_None; else if(strcmp(argv[4], "ImmediateACK") == 0) flow_list_[flowid].ack_type_ = ACK_Immediate; else if(strcmp(argv[4], "DelayedACK") == 0) flow_list_[flowid].ack_type_ = ACK_Delayed; else if(strcmp(argv[4], "BeaconACK") == 0) flow_list_[flowid].ack_type_ = ACK_Beacon; stats_.AddFlowOut(index_, flowid, flowid); return TCL_OK; } } return Mac::command(argc, argv);}int Mac_WiMedia::SendNullPacket(int flowid, double remaining, double defer_duration, bool bRequestDelayedAck) { if(current_traffic_type_ == Traffic_NRT) return -1; printf("In WiMedia.cc->SendNullPacket(): Try to send null packet\n"); 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_ = bRequestDelayedAck; double timeout = TxTime(pktNULL_) + defer_duration + macmib_->sifs; if(bRequestDelayedAck) { timeout += TxTime_ACK(); timeout += macmib_->sifs; } if(timeout >= remaining) { printf("In WiMedia.cc->SendNullPacket: There is not enough time to send a NULL Pakcet\n"); return -1; } // if(bRequestDelayedAck) tx_state_ = MAC_WAIT_DELAYEDACK; else tx_state_ = MAC_SEND; struct hdr_ip *ih = HDR_IP(pktNULL_); mh->qs_ = QPacketCount(flowid) + QUnAckedPacketCount(flowid); mh->stream_index_ = (u_char)flowid; ih->fid_ = flowid; printf("WiMedia.cc->SendNullPacket: Sending NULL packet to the defer timer. Flowid:%d, QS:%d\n", flowid, mh->qs_); if(defer_duration == 0) Transmit(pktNULL_, timeout); else { if(mhDefer_.busy()) { printf("WiMedia.cc->SendNullPacket: Defer timer is busy!\n"); return -1; } // End of if else { mhDefer_.timeout_ = timeout; mhDefer_.pktSend_ = pktNULL_; mhDefer_.start(defer_duration); } // End of else } return 0;}int Mac_WiMedia::QPacketCount(int flowid) { if(flowid >= MAX_FLOWS || flowid < 0) { printf("WiMedia.cc: QPacketCount: Invalid flowid (%d)\n", flowid); exit(1); } // End of if return packet_queue_[flowid].size(); // Yes, this is the size of the list vector, the number of packets stored}int Mac_WiMedia::QUnAckedPacketCount(int flowid) { if(flowid >= MAX_FLOWS || flowid <0) { printf("WiMedia.cc: QUnAckedPacketCount() - Invalid flowid(%d)\n", flowid); exit(1); } // End of if return unacked_queue_[flowid].size();}inline int Mac_WiMedia::is_idle() { if(rx_state_ != MAC_IDLE) return 0; if(tx_state_ != MAC_IDLE) return 0; return 1;}int Mac_WiMedia::CheckAckPacket() { if(pktACK_ == 0) return -1; if(!is_idle()) { collision(pktACK_); printf("WiMedia.cc:CheckAckPacket-> Channel is supposed to be idle, but it is not\n"); return 0; } // End of if struct hdr_mac *mh = HDR_MAC(pktACK_); double timeout; switch(mh->ftype_) { case MF_ACK: tx_state_ = MAC_ACK; timeout = TxTime_ACK(); break; default: printf("WiMedia.cc:CheckAckPacket-> Invalid MAC Control subtype\n"); exit(1); } // End of switch if(mhDefer_.busy()) printf("WiMedia.cc:CheckAckPacket()-> ERROR: Defer timer is busy\n"); else { mhDefer_.timeout_ = timeout; mhDefer_.pktSend_ = pktACK_; mhDefer_.start(macmib_->sifs); } // End of if return 0;}void Mac_WiMedia::collision(Packet* p) { switch(rx_state_) { case MAC_RECV: rx_state_ = MAC_COLL; case MAC_COLL: if(TxTime(p) > mhRecv_.expire()) { mhRecv_.stop(); discard(pktRx_, DROP_MAC_COLLISION); pktRx_ = p; mhRecv_.start(TxTime(pktRx_)); } // End of if else discard(p, DROP_MAC_COLLISION); break; default: printf("Mac_WiMedia:collision()->Unknown MAC state\n"); } // End of switch}void Mac_WiMedia::discard(Packet* p, const char* why) { hdr_mac* mh = HDR_MAC(p); hdr_cmn* ch = HDR_CMN(p); if(ch->error() != 0) { Packet::free(p); return; } switch(mh->ftype_) { case MF_BEACON: case MF_MS_BEACON: drop(p, why); printf("WiMedia.cc:discard()-> Discard packet - %s\n", why); return; case MF_ACK: if((u_int32_t)mh->macDA_ == (u_int32_t)index_) { drop(p, why); printf("WiMedia.cc:discard()-> Discard packet - %s\n", why); return; } // End of if break; case MF_DATA: case MF_NULL: if((u_int32_t)mh->macDA_ == (u_int32_t)index_ || (u_int32_t)mh->macSA_ == (u_int32_t)index_ || (u_int32_t)mh->macDA_ == (u_int32_t)MAC_BROADCAST) { drop(p, why); printf("WiMedia.cc:discard()-> Discard packet - %s\n", why); return; } // End of if break; default: printf("WiMedia.cc:discard()-> Discard packet - Invalid MAC type (%x)\n", mh->ftype_); exit(1); } // End of switch Packet::free(p);}void Mac_WiMedia::tx_resume(double defer_duration) { MacState nTempStatus = tx_state_; tx_state_ = MAC_IDLE; if(nTempStatus == MAC_WAIT_DELAYEDACK) { double remaining = current_slot_end_time_ - Scheduler::instance().clock(); SendNullPacket(current_flowid_, remaining, defer_duration, true); } else { if(CheckAckPacket() == -1) { // Dapeng Debug // printf("current_traffic_type is %d, and Traffic_NRT is %d\n", current_traffic_type_, Traffic_NRT); if(current_traffic_type_ != Traffic_NRT) { // printf("current_traffic_type_ != Traffic_NRT, current_traffic_type is %d, Traffic_NRT is %d\n", current_traffic_type_, Traffic_NRT); CheckQueues(defer_duration, nTempStatus); } else CheckNRTQueue(false); } }}void Mac_WiMedia::AdjustQueueSize(Packet *p) { struct hdr_mac *mh = HDR_MAC(p); struct hdr_ip *ih = HDR_IP(p); mh->qs_ = QPacketCount(ih->fid_) + QUnAckedPacketCount(ih->fid_) - 1;}int Mac_WiMedia::SendPacket(Packet *p, double defer_duration) { printf("WiMedia.cc->SendPacket()\n"); double timeout; hdr_mac *mh = HDR_MAC(p); if(mh->ftype_ != MF_DATA) { printf("WiMedia.cc->SendPacket(): Invalid Packet Type\n"); exit(1); } // End of if double remaining = current_slot_end_time_ - Scheduler::instance().clock(); if(!is_idle()) { collision(p); printf("WiMedia.cc->SendPacket(): Channel is supposed to be idle, but it is not\n"); return 0; } double nTempAckTime = 0; switch(current_ack_type_) { case ACK_Immediate: mh->ack_type_ = ACK_Immediate; tx_state_ = MAC_SEND; nTempAckTime = Timeout_ACK(); break; case ACK_Delayed: mh->ack_type_ = ACK_Delayed; if(mh->bRequestDelayedAck_ = true) { tx_state_ = MAC_WAIT_DELAYEDACK; nTempAckTime = Timeout_ACK(); } else { tx_state_ = MAC_SEND_CONTINUE; nTempAckTime = 0; } break; case ACK_Beacon: mh->ack_type_ = ACK_Beacon; tx_state_ = MAC_SEND_CONTINUE; nTempAckTime = 0; case ACK_None: mh->ack_type_ = ACK_None; tx_state_ = MAC_SEND_CONTINUE; nTempAckTime = 0; break; } // End of switch if((TxTime(p) + defer_duration + nTempAckTime) >= remaining) { printf("WiMedia.cc->SendPacket() Not enough time\n"); tx_state_ = MAC_IDLE; SendNullPacket(current_flowid_, remaining, defer_duration, mh->bRequestDelayedAck_); return -1; } AdjustQueueSize(p); if((u_int32_t)mh->macDA_ !=(u_int32_t)MAC_BROADCAST) { if((tx_state_ == MAC_SEND) || (tx_state_ == MAC_WAIT_DELAYEDACK)) timeout = TxTime(p) + Timeout_ACK(); else timeout = TxTime(p) + macmib_->mifs; } else { struct hdr_ip *ih = HDR_IP(p); if(ih->daddr() != (nsaddr_t)IP_BROADCAST) timeout = TxTime(p) + Timeout_ACK(); else timeout = TxTime(p); } if(defer_duration == 0) Transmit(p, timeout); else { if(mhDefer_.busy()) printf("WiMedia.cc->SendPacket(): The defer timer is busy now\n"); else { mhDefer_.timeout_ = timeout; mhDefer_.pktSend_ = p; mhDefer_.start(defer_duration); } } return 0;}bool Mac_WiMedia::QRemovePacket(Packet *p) { struct hdr_ip *ih = HDR_IP(p); int flowid = ih->fid_; if(flowid > MAX_FLOWS || flowid < 0) { printf("WiMedia.cc->QRemovePacket(): Invalid flowid %d\n", flowid); exit(1); } packet_queue_[flowid].remove(p); flow_list_[flowid].qs_ = packet_queue_[flowid].size(); return true;}void Mac_WiMedia::QAddUnAckedPacket(Packet *p) { struct hdr_ip *ih = HDR_IP(p); struct hdr_mac *mh = HDR_MAC(p); int flowid = ih->fid_; if(flowid >= MAX_FLOWS || flowid < 0) { printf("WiMedia.cc->QAddUnAckedPacket() - Invalid flowid (%d)\n", flowid); exit(1); } unacked_queue_[flowid].push_back(p); flow_list_[flowid].unacked_qs_ = unacked_queue_[flowid].size(); if((mh->ack_type_ == ACK_Immediate) && (unacked_queue_[flowid].size() > 1)) { printf("WiMedia.cc->QAddUnAckedPacket() - There are more than one unacked packets in the unacked queue\n"); exit(1); }}bool Mac_WiMedia::QRemoveUnAckedPacket(Packet *p) { struct hdr_ip *ih = HDR_IP(p); int flowid = ih->fid_; if(flowid >= MAX_FLOWS || flowid < 0) { printf("WiMedia.cc -> QRemoveUnAckedPacket - Invalid flowid %d\n", flowid); exit(1); } unacked_queue_[flowid].remove(p); flow_list_[flowid].unacked_qs_ = unacked_queue_[flowid].size(); return true;}int Mac_WiMedia::CheckRetransmission(double defer_duration, MacState state) { // Dapeng Debug // printf("WiMedia.cc->CheckRetransmission::\n"); if(unacked_queue_[current_flowid_].size() == 0) return -1; Packet *p = QGetNextUnAckedPacket(current_flowid_, true); if(p == 0) { printf("WiMedia.cc->CheckRetransmission - Unacked packet expired. Packet dropped\n"); return -1; } struct hdr_cmn *ch = HDR_CMN(p); struct hdr_mac *mh = HDR_MAC(p); struct 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; } } printf("WiMedia.cc CheckRetransmission() ACK Time out! Packet will be retransmitted\n"); macmib_->ACKFailureCount++; 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_);
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -