⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mac-802_16.cc

📁 802.16 Qos仿真平台的c++实现
💻 CC
📖 第 1 页 / 共 5 页
字号:
				while (bssf) {
					if (bssf->Direction == DL && bssf->Status == Active && bssf->ScheduleType == 2 && BsSearchSsInfo(bssf->MacAddr, -1)->BasicCID == dlmapie->CID) {
						//printf("Downlink Bandwidth %d CID %d BE SFID=%d req size %d[%d]\n",Bandwidth,dlmapie->CID,bssf->SFID,Bandwidth*bssf->TrafficPriority/TrafficPriority,bssf->SduQueue.count(Bandwidth*bssf->TrafficPriority/TrafficPriority));
						BsFragOrPack(bssf, bssf->SduQueue.count(Bandwidth*bssf->TrafficPriority/TrafficPriority));
						//printf("\tbs SduQ=%d\tPduQ=%d\n",bssf->SduQueue.byteLength(),bssf->PduQueue.byteLength());
					}
					bssf = bssf->next;
				}
			}
		}
		dlmapie = dlmapie->next;
	}
	BsBurstTransmit();
	return;
}

void
Mac802_16::SsScheduler()
{
	UlMapIe *ulmapie;
	if (!RangingStatus) {
		//Initial Ranging IE
		ulmapie = UlMapIe_head;
		while (ulmapie) {
			if (ulmapie->UIUC == 0xC && ulmapie->CID == 0xFFFF)
				sendRNGREQ(ulmapie);
			ulmapie = ulmapie->next;
		}
	} else {
		//Data Grant IE
		ulmapie = UlMapIe_head;
		while (ulmapie) {
			if (ulmapie->UIUC != 0xC && ulmapie->CID == BasicCID) {
				int Bandwidth = 0;
				int TrafficPriority = 0;
				switch (ModulCoding) {
					case QPSK_12: Bandwidth = ulmapie->Duration*6*3; break;
					case QPSK_34: Bandwidth = ulmapie->Duration*9*3; break;
					case QAM16_12:Bandwidth = ulmapie->Duration*12*3; break;
					case QAM16_34:Bandwidth = ulmapie->Duration*18*3; break;
					case QAM64_23:Bandwidth = ulmapie->Duration*24*3; break;
					case QAM64_34:Bandwidth = ulmapie->Duration*27*3; break;	
				}
				SsServiceFlow *sssf;
				sssf = SsSF_head;
				while (sssf) {
					if (sssf->Status == Active && sssf->ScheduleType == 6) {
						//printf("Uplink Bandwidth %d UGS SFID=%d req size %d[%d]\n",Bandwidth,sssf->SFID,sssf->SduQueue.byteLength(),sssf->SduQueue.count(sssf->SduQueue.byteLength()));
						SsFragOrPack(sssf, sssf->SduQueue.count(sssf->SduQueue.byteLength()));
						Bandwidth -= sssf->PduQueue.byteLength();
						//printf("\tss SduQ=%d\tPduQ=%d\n",sssf->SduQueue.byteLength(),sssf->PduQueue.byteLength());
					}
					if (sssf->Status == Active && sssf->BwReqSize != 0 && sssf->ScheduleType >= 3 && sssf->ScheduleType <= 5 ) {
						//printf("Uplink Bandwidth %d Polling SFID=%d req size %d[%d]\n",Bandwidth,sssf->SFID,sssf->BwReqSize,sssf->SduQueue.count(sssf->BwReqSize));
						SsFragOrPack(sssf, sssf->SduQueue.count(sssf->BwReqSize));
						sssf->BwReqSize = 0;
						Bandwidth -= sssf->PduQueue.byteLength();
						//printf("\tss SduQ=%d\tPduQ=%d\n",sssf->SduQueue.byteLength(),sssf->PduQueue.byteLength());
					}
					if (sssf->Status == Active && sssf->ScheduleType == 2) {
						TrafficPriority += sssf->TrafficPriority;
					}
					sssf = sssf->next;
				}
				if (Bandwidth > 0 && TrafficPriority > 0) {
					sssf = SsSF_head;
					while (sssf) {
						if (sssf->Status == Active && sssf->ScheduleType == 2) {
							//printf("Uplink Bandwidth %d BE SFID=%d req size %d[%d]\n",Bandwidth,sssf->SFID,Bandwidth*sssf->TrafficPriority/TrafficPriority,sssf->SduQueue.count(Bandwidth*sssf->TrafficPriority/TrafficPriority));
							SsFragOrPack(sssf, sssf->SduQueue.count(Bandwidth*sssf->TrafficPriority/TrafficPriority));
							//printf("\tss SduQ=%d\tPduQ=%d\n",sssf->SduQueue.byteLength(),sssf->PduQueue.byteLength());
						}
						sssf = sssf->next;
					}
				}
			}
			ulmapie = ulmapie->next;
		}
		
		//BW Request IE
		ulmapie = UlMapIe_head;
		while (ulmapie) {
			if (ulmapie->UIUC == 0xC && ulmapie->CID == BasicCID)
				sendBWREQ(ulmapie);
			ulmapie = ulmapie->next;
		}
	}
	SsBurstTransmit();
	return;
}

void 
Mac802_16::BsFragOrPack(BsServiceFlow *BsSF, int Size)
{	
	//printf("[1]BS SDU num=%d PDU num=%d\n",BsSF->SduQueue.length(),BsSF->PduQueue.length());
	static int32_t tmp_size = PDUSIZE;	
	Packet* frag;
	Packet* sdu;
BsStart:	
	while (Size) {				
		sdu = BsSF->SduQueue.deque();		
		struct hdr_cmn* sdu_hdr = HDR_CMN(sdu);
	    struct hdr_mac802_16* sdu_mac16 = HDR_MAC802_16(sdu);	
		
		if (sdu_hdr->size() <= tmp_size) {
			//need to pack
			sdu_mac16->generic_hdr.Type = 0x01;	
			sdu->type_ = 1;	
			struct subhdr_pack* psh = SUBHDR_Pack(sdu);
			//printf("Add packing subheader FSN:%d\n",psh->FSN);
			psh->FSN = (psh->FSN + 1)%8;				
			if (sdu_hdr->size() < tmp_size) {
				//Add PACKing subheader; add SDU or SDU fragment					
				psh->FC = 0x0;
				psh->Length = sdu_hdr->size();
				tmp_size -= sdu_hdr->size();
				//printf("Need to Pack:\n");	
				Packet::free(sdu);
			} else {
				//add PACKing subheader; add fragment					
				psh->FC = 0x2;
				frag = sdu;   
				BsSF->PduQueue.enque(sdu);	
				//printf("[1]Complete a MPDU\nPacking with fragmetation; The remaining fragment is stored in queue\n");					
				tmp_size = PDUSIZE;								
			}
			Size--;
			goto BsStart;				
		} else {
			//Need fragmetation
        	sdu_mac16->generic_hdr.Type = 0x04; 
			sdu->type_ = 2;		
			if (BsSF->FragQueue.length() != 0) { 		
BsFragQueue:	
				//Fragment-queue is not empty;
				Packet::free(sdu);				
				frag = BsSF->FragQueue.deque();
				struct hdr_cmn* frag_hdr = HDR_CMN(frag);
				struct subhdr_frag* fsh = SUBHDR_Frag(frag);				
				//printf("Add fragmentation subheader FSN:%d\n",fsh->FSN);
				fsh->FSN = (fsh->FSN + 1)%8;				
				if (frag_hdr->size() <= tmp_size) {
					//Add SDU to payload
					//printf("Add SDU to payload\nLast Fragment\n");						
					if (frag_hdr->size() < tmp_size) {
						// last fragment  need pack
						fsh->FC = 0x1;
						tmp_size -= frag_hdr->size();
						Packet::free(frag);
					} else {
						// last fragment
						fsh->FC = 0x1;
						// printf("Complete a MPDU\n\n");							 
						tmp_size = PDUSIZE;	
						BsSF->PduQueue.enque(frag);					
					}	
				} else {
					// continue fragment	
					fsh->FC = 0x3;		
					//printf("Continue Fragment\n");
					int i = frag_hdr->size();
					frag_hdr->size() = tmp_size;
					BsSF->PduQueue.enque(frag->copy());
					frag_hdr->size() = i - tmp_size;
					BsSF->FragQueue.enque(frag);
					//printf("[2]Complete a MPDU\n The remaining fragment is stored in queue\n");					
					tmp_size = PDUSIZE;
					goto BsFragQueue;	
				}
			} else {
				//there're no fragments in fragment-queue
				struct hdr_cmn* sdu_hdr = HDR_CMN(sdu);
				struct subhdr_frag* fsh = SUBHDR_Frag(sdu);
				//printf("Add fragmentation subheader FSN:%d\n",fsh->FSN);
				fsh->FSN = (fsh->FSN + 1)%8;
				if (sdu_hdr->size() > tmp_size) {
					//need to fragmentation
					int i = sdu_hdr->size();
					sdu_hdr->size() = PDUSIZE;
					//printf("First Fragmentaton\n");					 					
					fsh->FC = 0x2;  //first fragment
					BsSF->PduQueue.enque(sdu->copy());
					sdu_hdr->size() = i - tmp_size;
					BsSF->FragQueue.enque(sdu);
					//printf("[3]Complete a MPDU\n The remaining fragment is stored in queue\n");					
					tmp_size = PDUSIZE;					
					goto BsFragQueue;
				}
			}
		}
		Size--;
	}
	//printf("[2]BS SDU num=%d PDU num=%d\n",BsSF->SduQueue.length(),BsSF->PduQueue.length());
	return;
}

void 
Mac802_16::SsFragOrPack(SsServiceFlow *SsSF, int Size)
{	
	//printf("[1]SS SDU num=%d PDU num=%d\n",SsSF->SduQueue.length(),SsSF->PduQueue.length());
	static int32_t tmp_size = PDUSIZE;	
	Packet* frag;
	Packet* sdu;
SsStart:	
	while (Size) {				
		sdu = SsSF->SduQueue.deque();		
		struct hdr_cmn* sdu_hdr = HDR_CMN(sdu);
	    struct hdr_mac802_16* sdu_mac16 = HDR_MAC802_16(sdu);		
		if (sdu_hdr->size() <= tmp_size) {
			//need to pack
			sdu_mac16->generic_hdr.Type = 0x01;	
			sdu->type_ = 1;	
			struct subhdr_pack* psh = SUBHDR_Pack(sdu);
			//printf("Add packing subheader FSN:%d\n",psh->FSN);
			psh->FSN = (psh->FSN + 1)%8;				
			if (sdu_hdr->size() < tmp_size) {
				//Add PACKing subheader; add SDU or SDU fragment					
				psh->FC = 0x0;
				psh->Length = sdu_hdr->size();
				tmp_size -= sdu_hdr->size();
				//printf("Need to Pack:\n");	
				Packet::free(sdu);
			} else {
				//add PACKing subheader; add fragment					
				psh->FC = 0x2;
				frag = sdu;
				SsSF->PduQueue.enque(sdu);	
				//printf("[1]Complete a MPDU\nPacking with fragmetation; The remaining fragment is stored in queue\n");					
				tmp_size = PDUSIZE;								
			}
			Size--;
			goto SsStart;				
		} else {
			//Need fragmetation
        	sdu_mac16->generic_hdr.Type = 0x04; 
			sdu->type_ = 2;		
			if (SsSF->FragQueue.length() != 0) { 		
SsFragQueue:	
				//Fragment-queue is not empty;
				Packet::free(sdu);		
				frag = SsSF->FragQueue.deque();
				struct hdr_cmn* frag_hdr = HDR_CMN(frag);
				struct subhdr_frag* fsh = SUBHDR_Frag(frag);				
				//printf("Add fragmentation subheader FSN:%d\n",fsh->FSN);
				fsh->FSN = (fsh->FSN + 1)%8;				
				if (frag_hdr->size() <= tmp_size) {
					//Add SDU to payload
					//printf("Add SDU to payload\nLast Fragment\n");						
					if (frag_hdr->size() < tmp_size) {
						// last fragment  need pack
						fsh->FC = 0x1;
						tmp_size -= frag_hdr->size();
						Packet::free(frag);
					} else {
						// last fragment
						fsh->FC = 0x1;
						// printf("Complete a MPDU\n\n");							 
						tmp_size = PDUSIZE;	
						SsSF->PduQueue.enque(frag);					
					}	
				} else {
					// continue fragment	
					fsh->FC = 0x3;		
					//printf("Continue Fragment\n");
					int i = frag_hdr->size();
					frag_hdr->size() = tmp_size;
					SsSF->PduQueue.enque(frag->copy());
					frag_hdr->size() = i - tmp_size;
					SsSF->FragQueue.enque(frag);
					//printf("[2]Complete a MPDU\n The remaining fragment is stored in queue\n");					
					tmp_size = PDUSIZE;
					goto SsFragQueue;	
				}
			} else {
				//there're no fragments in fragment-queue
				struct hdr_cmn* sdu_hdr = HDR_CMN(sdu);
				struct subhdr_frag* fsh = SUBHDR_Frag(sdu);
				//printf("Add fragmentation subheader FSN:%d\n",fsh->FSN);
				fsh->FSN = (fsh->FSN + 1)%8;
				if (sdu_hdr->size() > tmp_size) {
					//need to fragmentation
					int i = sdu_hdr->size();
					sdu_hdr->size() = PDUSIZE;
					//printf("First Fragmentaton\n");					 					
					fsh->FC = 0x2;  //first fragment
					SsSF->PduQueue.enque(sdu->copy());
					sdu_hdr->size() = i - tmp_size;
					SsSF->FragQueue.enque(sdu);
					//printf("[3]Complete a MPDU\n The remaining fragment is stored in queue\n");					
					tmp_size = PDUSIZE;					
					goto SsFragQueue;
				}
			}
		}
		Size--;
	}
	//printf("[2]SS SDU num=%d PDU num=%d\n",SsSF->SduQueue.length(),SsSF->PduQueue.length());*/
	return;
}

void
Mac802_16::BsBurstTransmit()
{////////////////////////本部分是我增加的,BS发送给SS的控制信息必须在一帧的下行子帧内发送,原补丁没有考虑这一层,只要BS收到SS的RNGREQ、DSAREQ等消息就马上作出回复,这是不符合协议的,因为此时SS正处于上行子帧发送状态,TDD下是不可能全双工的(长庚大学的wimax采用的是TDD模式)	while(BsMsgQueue.length()!=0) {		Packet* msg=BsMsgQueue.deque();		hdr_cmn *msg_hdr = HDR_CMN(msg->copy());		if(msg_hdr->ptype()==PT_RNGRSP) 			RangingFlag=false;//如果BsMsgQueue中有测距回复消息,将RangingFlag恢复		downtarget_->recv(msg, this);	}///////////////////////////////////////////
	BsServiceFlow *bssf = NULL;
	bssf = BsSF_head;
	while (bssf) {
		while (bssf->Direction == DL && bssf->PduQueue.length() != 0) {
			Packet *p = bssf->PduQueue.deque();
			struct hdr_cmn *hdr = HDR_CMN(p);
			struct hdr_mac *mac = HDR_MAC(p); 
			struct hdr_mac802_16 *mac16 = HDR_MAC802_16(p);

			mac->macDA() = bssf->MacAddr;
			mac->macSA() = BsID;
			mac->set(MF_DATA, NodeID);
			state(MAC_SEND);
	
			//hdr->uid() = 0;//这部分是我注释掉的,因为它导致了MAC层发送封包的时候将封包uid_全部设置为0了
			hdr->size() += sizeof(GenericHdr);
			hdr->iface() = -2;
			hdr->error() = 0; 
			hdr->txtime() = SymbolLength;
	
			mac16->generic_hdr.HT = 0;
			mac16->generic_hdr.EC = 1;
			mac16->generic_hdr.Type = 1;
			mac16->ge

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -