📄 mac-802_16.cc
字号:
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 + -