📄 mac-802_16.cc
字号:
mac_16->type=1;
mac_16->CI=1;
mac_16->EKS=1;
mac_16->LEN=3;
mac_16->CID=0;
mac_16->HCS=0;
mac_16->mmt=3;
ulmap->management_message_type=3;
ulmap->uplink_channel_id=1;
allocation_start_time=Scheduler::instance().clock()+dlmapDuration_;
for(int i=0;i<UL_burst_profile;i++)
{
ULMAP_IE[i].cid=ULMAP_SS[i];
ULMAP_IE[i].uiuc=i+1;
ULMAP_IE[i].OFDMA_Symbol_offset=Symbol_offset;
ULMAP_IE[i].Subchannel_offset=0x0;
if(Search_BCID(ULMAP_SS[i])->SS_UL_BW/(channelNO_*dataSize_)-(int)(Search_BCID(ULMAP_SS[i])->SS_UL_BW/(channelNO_*dataSize_))>0.0)
{
ULMAP_IE[i].OFDMA_Symbol_number = (int)(Search_BCID(ULMAP_SS[i])->SS_UL_BW/(channelNO_*dataSize_))+1;
}
else
{
ULMAP_IE[i].OFDMA_Symbol_number = (int)(Search_BCID(ULMAP_SS[i])->SS_UL_BW/(channelNO_*dataSize_));
}
ULMAP_IE[i].Subchannel_number=channelNO_;
ULMAP_IE[i].Ranging_Method=0x0;
Symbol_offset+=ULMAP_IE[i].OFDMA_Symbol_number;
}
ULMAP_IE[UL_burst_profile].uiuc=0xc;
pktULMAP_=p;
SendUL.start(2*symbolDuration_);
}
void Mac802_16::sendDLMAP(int DL_burst_profile)
{
printf("There are %d Downlink SSs \n",DL_burst_profile);
Packet *p=Packet::alloc();
struct hdr_cmn *hdr = HDR_CMN(p);
struct hdr_mac *mac_ = HDR_MAC(p);
struct hdr_mac802_16 *mac_16 = HDR_MAC802_16(p);
struct DL_MAP* dlmap=HDR_MAC802_16_DL_MAP(p);
int Symbol_offset=0;
mac_->macDA_ = MAC_BROADCAST;
mac_->macSA_ = creatid;
hdr->txtime() = 0.000001;
hdr->uid() = 0;
hdr->ptype() = PT_DLMAP;
hdr->size() = 10;
hdr->iface() = -2;
hdr->error() = 0;
mac_16->HT =0;
mac_16->EC =1;
mac_16->type=1;
mac_16->CI=1;
mac_16->EKS=1;
mac_16->LEN=3;
mac_16->CID=0;
mac_16->HCS=0;
mac_16->mmt=2;
dlmap->management_message_type=2;
dlmap->BS_ID=0;
pktDLMAP_=p;
SendDL.start(0);
if(DL_burst_profile>0)
{
DLMAP_IE[0].diuc=1;
DLMAP_IE[0].N_CID=DL_burst_profile-1;
DLMAP_IE[0].CID=DLMAP_SS[0];
DLMAP_IE[0].OFDMA_Symbol_offset=Symbol_offset;
DLMAP_IE[0].Subchannel_offset=0x0;
if(Search_BCID(DLMAP_SS[0])->SS_DL_BW/(channelNO_*dataSize_)
-(int)(Search_BCID(DLMAP_SS[0])->SS_DL_BW/(channelNO_*dataSize_))>0.0)
{
DLMAP_IE[0].OFDMA_Symbol_number = (int)(Search_BCID(DLMAP_SS[0])->SS_DL_BW/(channelNO_*dataSize_))+1;
}
else
{
DLMAP_IE[0].OFDMA_Symbol_number = (int)(Search_BCID(DLMAP_SS[0])->SS_DL_BW/(channelNO_*dataSize_));
}
DLMAP_IE[0].Subchannel_number=channelNO_;
Symbol_offset+=DLMAP_IE[0].OFDMA_Symbol_number;
dlmaptimer.start(4*symbolDuration_, 0, Symbol_offset);
}
else
DLMAP_IE[DL_burst_profile].diuc=0xe;
}
void Mac802_16::DLmapHandler(long double time, int DL_burst_num, int Symbol_offset)
{
BS_Scheduler(DLMAP_SS[DL_burst_num],DLMAP_IE[DL_burst_num].OFDMA_Symbol_number);
if(DL_burst_num+1<DL_burst_profile)
{
DLMAP_IE[DL_burst_num+1].diuc=DL_burst_num+1;
DLMAP_IE[DL_burst_num+1].N_CID=DL_burst_profile-1;
DLMAP_IE[DL_burst_num+1].CID=DLMAP_SS[DL_burst_num+1];
DLMAP_IE[DL_burst_num+1].OFDMA_Symbol_offset=Symbol_offset;
DLMAP_IE[DL_burst_num+1].Subchannel_offset=0x0;
if(Search_BCID(DLMAP_SS[DL_burst_num+1])->SS_DL_BW/(channelNO_*dataSize_)
-(int)(Search_BCID(DLMAP_SS[DL_burst_num+1])->SS_DL_BW/(channelNO_*dataSize_))>0.0)
{
DLMAP_IE[DL_burst_num+1].OFDMA_Symbol_number
= (int)(Search_BCID(DLMAP_SS[DL_burst_num+1])->SS_DL_BW/(channelNO_*dataSize_))+1;
}
else
{
DLMAP_IE[DL_burst_num+1].OFDMA_Symbol_number
= (int)(Search_BCID(DLMAP_SS[DL_burst_num+1])->SS_DL_BW/(channelNO_*dataSize_));
}
DLMAP_IE[DL_burst_num+1].Subchannel_number=channelNO_;
/*If we don't add 0.001s to the equation, it will lead to the overlap of PDU timer and have segmentation fault.*/
dlmaptimer.start(DLMAP_IE[DL_burst_num+1].OFDMA_Symbol_number*symbolDuration_+0.0001
, DL_burst_num+1, Symbol_offset+DLMAP_IE[DL_burst_num+1].OFDMA_Symbol_number);
}
else
{
DLMAP_IE[DL_burst_profile].diuc=0xe;
dlmaptimer.stop();
}
}
void Mac802_16::transmit(Packet* p, double timeout)
{
mhDefer_.start(timeout);
}
void Mac802_16::PDU_Generator(packet_t ser_type, int grab_byte,int bcid)
{
printf("Downlink Session Start (Dealing with BCID %d): \n",bcid);
switch(ser_type){
case PT_UGS:
printf("BS will grab %d bytes from UGS-Queue, and There are %d bytes in Queue\n",grab_byte,Queue_list->Search_BCID(bcid)->UGS.byteLength());
Frag_or_Pack(PT_UGS, Queue_list->Search_BCID(bcid)->UGS.count(grab_byte), bcid);
break;
case PT_rtPS:
printf("BS will grab %d bytes from rtPS-Queue, and There are %d bytes in Queue \n",grab_byte,Queue_list->Search_BCID(bcid)->rtPS.byteLength());
Frag_or_Pack(PT_rtPS, Queue_list->Search_BCID(bcid)->rtPS.count(grab_byte), bcid);
break;
case PT_ertPS:
printf("BS will grab %d bytes from ertPS-Queue, and There are %d bytes in Queue \n",grab_byte,Queue_list->Search_BCID(bcid)->ertPS.byteLength());
Frag_or_Pack(PT_ertPS, Queue_list->Search_BCID(bcid)->ertPS.count(grab_byte), bcid);
break;
case PT_nrtPS:
printf("BS will grab %d bytes from nrtPS-Queue, and There are %d bytes in Queue \n",grab_byte,Queue_list->Search_BCID(bcid)->nrtPS.byteLength());
Frag_or_Pack(PT_nrtPS, Queue_list->Search_BCID(bcid)->nrtPS.count(grab_byte), bcid);
break;
case PT_BE:
printf("BS will grab %d bytes from BE-Queue, and There are %d bytes in Queue\n",grab_byte,Queue_list->Search_BCID(bcid)->BE.byteLength());
Frag_or_Pack(PT_BE, Queue_list->Search_BCID(bcid)->BE.count(grab_byte), bcid);
break;
default:
break;
}
}
void Mac802_16::Frag_or_Pack(packet_t ser_type, int num, int user)
{
static int32_t tmp_size = PDUSIZE;
Packet* pkt_tmp=Packet::alloc();
Packet* tmp=Packet::alloc();
begin:
while(num)
{
switch(ser_type)
{
case PT_UGS:
tmp=Queue_list->Search_BCID(user)->UGS.deque();
break;
case PT_rtPS:
tmp=Queue_list->Search_BCID(user)->rtPS.deque();
break;
case PT_ertPS:
tmp=Queue_list->Search_BCID(user)->ertPS.deque();
break;
case PT_nrtPS:
tmp=Queue_list->Search_BCID(user)->nrtPS.deque();
break;
case PT_BE:
tmp=Queue_list->Search_BCID(user)->BE.deque();
break;
default:
break;
}
struct hdr_cmn* pkt = HDR_CMN(tmp);
//struct hdr_cmn* pkt_tmp_cmn=HDR_CMN(pkt_tmp);
struct hdr_mac802_16* dh = HDR_MAC802_16(tmp);
//struct hdr_mac802_16* pkt_tmp_dh = HDR_MAC802_16(pkt_tmp);
if(pkt->size() <= tmp_size)
{ //need to pack
dh->type = 0x01;
pack_subheader_t* psh = sub_HDR_MAC802_16_pack(tmp);
//printf("Add packing subheader FSN:%d\n",psh->FSN);
psh->FSN=((psh->FSN)+1)%8;
if(pkt->size() < tmp_size)
{ //Add PACKing subheader; add SDU or SDU fragment
psh->FC=0x0;
psh->Length = pkt->size();
tmp_size -= pkt->size();
//printf("Need to Pack:\n");
break;
}
else{ //add PACKing subheader; add fragment
psh->FC=0x2;
pkt_tmp=tmp;
Queue_list->Search_BCID(user)->PDUQueue.enque(pkt_tmp->copy());
//printf("Complete a MPDU\nPacking with fragmetation; The remaining fragment is stored in queue\n");
tmp_size = PDUSIZE;
}
num--;
goto begin;
}
else{ //Need fragmetation
dh->type = 0x04;
tmp->type_=2;
if(Queue_list->Search_BCID(user)->fragQueue.length()!= 0)
{ //Fragment-queue is not empty;
Frag_que: pkt_tmp=Queue_list->Search_BCID(user)->fragQueue.deque();
struct hdr_cmn* pkt = HDR_CMN(pkt_tmp);
struct frag_subheader_t* fsh = sub_HDR_MAC802_16_frag(pkt_tmp);
//printf("Add fragmentation subheader FSN:%d\n",fsh->FSN);
fsh->FSN=((fsh->FSN)+1)%8;
if( pkt->size()<= tmp_size)
{ //Add SDU to payload
//printf("Add SDU to payload\nLast Fragment\n");
if(pkt->size() == tmp_size)
{
fsh->FC=0x1; // last fragment
//printf("Complete a MPDU\n\n");
tmp_size = PDUSIZE;
Queue_list->Search_BCID(user)->PDUQueue.enque(pkt_tmp->copy());
}
else
{
fsh->FC=0x3; // continue fragment need pack
tmp_size-=pkt->size();
}
}
else
{
//dh->type = 0x04;
fsh->FC=0x3; // continue fragment
//printf("Continue Fragment\n");
int i=pkt->size();
pkt->size()=tmp_size;
Queue_list->Search_BCID(user)->PDUQueue.enque(pkt_tmp->copy());
pkt->size()=i-tmp_size;
Queue_list->Search_BCID(user)->fragQueue.enque(pkt_tmp->copy());
//printf("Complete a MPDU\n The remaining fragment is stored in queue\n");
tmp_size = PDUSIZE;
goto Frag_que;
}
}
else
{ //there're no fragments in fragment-queue
//dh->type = 0x04;
struct frag_subheader_t* fsh = sub_HDR_MAC802_16_frag(tmp);
struct hdr_cmn* pkt = HDR_CMN(tmp);
//printf("Add fragmentation subheader FSN:%d\n",fsh->FSN);
fsh->FSN=((fsh->FSN)+1)%8;
if(pkt->size()>tmp_size)
{ //need to fragmentation
int i=pkt->size();
pkt->size()=tmp_size;
//printf("First Fragmentaton\n");
fsh->FC=0x2; //first fragment
Queue_list->Search_BCID(user)->PDUQueue.enque(tmp->copy());
pkt->size()=i-tmp_size;
Queue_list->Search_BCID(user)->fragQueue.enque(tmp->copy());
//printf("Complete a MPDU\n The remaining fragment is stored in queue\n");
tmp_size = PDUSIZE;
goto Frag_que;
}
}
}
num--;
}
resumeBSBurst.start(0.00001,user);
return;
}
void Mac802_16::SS_PDU_Generator(packet_t ser_type, int grab_byte,int bcid)
{
printf("Uplink Session Start (Dealing with BCID %d): \n",bcid);
switch(ser_type)
{
case PT_UGS:
printf("SS will grab %d bytes from UGS-Queue, and There are %d bytes in Queue\n",grab_byte
,ss_buf->lookup(Search_BCID(bcid)->srcIP)->UGS.byteLength());
SS_Frag_or_Pack(PT_UGS, ss_buf->lookup(Search_BCID(bcid)->srcIP)->UGS.count(grab_byte), bcid);
break;
case PT_rtPS:
printf("SS will grab %d bytes from rtPS-Queue, and There are %d bytes in Queue\n",grab_byte
,ss_buf->lookup(Search_BCID(bcid)->srcIP)->rtPS.byteLength());
SS_Frag_or_Pack(PT_rtPS, ss_buf->lookup(Search_BCID(bcid)->srcIP)->rtPS.count(grab_byte), bcid);
break;
case PT_ertPS:
printf("SS will grab %d bytes from ertPS-Queue, and There are %d bytes in Queue\n",grab_byte
,ss_buf->lookup(Search_BCID(bcid)->srcIP)->ertPS.byteLength());
SS_Frag_or_Pack(PT_ertPS, ss_buf->lookup(Search_BCID(bcid)->srcIP)->ertPS.count(grab_byte), bcid);
break;
case PT_nrtPS:
printf("SS will grab %d bytes from nrtPS-Queue, and There are %d bytes in Queue\n",grab_byte
,ss_buf->lookup(Search_BCID(bcid)->srcIP)->nrtPS.byteLength());
SS_Frag_or_Pack(PT_nrtPS, ss_buf->lookup(Search_BCID(bcid)->srcIP)->nrtPS.count(grab_byte), bcid);
break;
case PT_BE:
printf("SS will grab %d bytes from BE-Queue, and There are %d bytes in Queue\n",grab_byte
,ss_buf->lookup(Search_BCID(bcid)->srcIP)->BE.byteLength());
SS_Frag_or_Pack(PT_BE, ss_buf->lookup(Search_BCID(bcid)->srcIP)->BE.count(grab_byte), bcid);
break;
default:return;
}
return;
}
void Mac802_16::SS_Frag_or_Pack(packet_t ser_type, int num, int user)
{
static int32_t tmp_size = PDUSIZE;
Packet* pkt_tmp=Packet::alloc();
Packet* pkt_tmp_head = Packet::alloc();
Packet* tmp=Packet::alloc();
pkt_tmp_head=tmp;
start:
while(num)
{
switch(ser_type)
{
case PT_UGS:
tmp=ss_buf->lookup(Search_BCID(user)->srcIP)->UGS.deque();
break;
case PT_rtPS:
tmp=ss_buf->lookup(Search_BCID(user)->srcIP)->rtPS.deque();
break;
case PT_ertPS:
tmp=ss_buf->lookup(Search_BCID(user)->srcIP)->ertPS.deque();
break;
case PT_nrtPS:
tmp=ss_buf->lookup(Search_BCID(user)->srcIP)->nrtPS.deque();
break;
case PT_BE:
tmp=ss_buf->lookup(Search_BCID(user)->srcIP)->BE.deque();
break;
default:
break;
}
struct hdr_cmn* pkt = HDR_CMN(tmp);
struct hdr_mac802_16* dh = HDR_MAC802_16(tmp);
//struct hdr_cmn* pkt_tmp_cmn=HDR_CMN(pkt_tmp);
//struct hdr_mac802_16* pkt_tmp_dh = HDR_MAC802_16(pkt_tmp);
if(pkt->size() <= tmp_size)
{ //need to pack
dh->type = 0x01;
tmp->type_=1;
struct pack_subheader_t* psh = sub_HDR_MAC802_16_pack(tmp);
//printf("Add packing subheader FSN:%d\n",psh->FSN);
psh->FSN=((psh->FSN)+1)%8;
if(pkt->size() < tmp_size)
{ //Add PACKing subheader; add SDU or SDU fragment
psh->FC=0x0;
psh->Length = pkt->size();
tmp_size -= pkt->size();
//printf("Need to Pack:\n");
}
else
{ //add PACKing subheader; add fragment
psh->FC=0x2;
pkt_tmp=tmp;
ss_buf->lookup(Search_BCID(user)->srcIP)->PDUQUEUE.enque(tmp->copy());
//printf("Complete a MPDU\nPacking with fragmetation; The remaining fragment is stored in queue\n");
tmp_size = PDUSIZE;
}
num--;
goto start;
}
else
{//Need fragmetation
dh->type = 0x04;
tmp->type_=2;
if(ss_buf->lookup(Search_BCID(user)->srcIP)->fragQUEUE.length()!= 0)
{ //Fragment-queue is not empty;
SS_Frag_que: pkt_tmp=ss_buf->lookup(Search_BCID(user)->srcIP)->fragQUEUE.deque();
struct hdr_cmn* pkt = HDR_CMN(pkt_tmp);
struct frag_subheader_t* fsh = sub_HDR_MAC802_16_frag(pkt_tmp);
//printf("Add fragmentation subheader FSN:%d\n",fsh->FSN);
fsh->FSN=((fsh->FSN)+1)%8;
if( pkt->size()<= tmp_size)
{ //Add SDU to payload
//printf("Add SDU to payload\nLast Fragment\n");
if(pkt->size() == tmp_size)
{
fsh->FC=0x1; // last fragment
printf("Complete a MPDU\n\n");
tmp_size = PDUSIZE;
ss_buf->lookup(Search_BCID(user)->srcIP)->PDUQUEUE.enque(pkt_tmp->copy());
}
else
{
fsh->FC=0x1; // last fragment need pack
tmp_size-=pkt->size();
}
}
else
{
//dh->type = 0x04;
fsh->FC=0x3; // continue fragment
//printf("Continue Fragment\n");
int i=pkt->size();
pkt->size()=tmp_size;
ss_buf->lookup(Search_BCID(user)->srcIP)->PDUQUEUE.enque(pkt_tmp->copy());
pkt->size()=i-tmp_size;
ss_buf->lookup(Search_BCID(user)->srcIP)->fragQUEUE.enque(pkt_tmp->copy());
//printf("Complete a MPDU\n The remaining fragment is stored in queue\n");
tmp_size = PDUSIZE;
goto SS_Frag_que;
}
}
else
{ //there're no fragments in fragment-queue
//dh->type = 0x04;
struct frag_subheader_t* fsh = sub_HDR_MAC802_16_frag(tmp);
struct hdr_cmn* pkt = HDR_CMN(tmp);
//printf("Add fragmentation subheader FSN:%d\n",fsh->FSN);
fsh->FSN=((fsh->FSN)+1)%8;
if(pkt->size()>tmp_size){ //need to fragmentation
int i=pkt->size();
pkt->size()=tmp_size;
//printf("First Fragmentaton\n");
fsh->FC=0x2; //first fragment
ss_buf->lookup(Search_BCID(user)->srcIP)->PDUQUEUE.enque(tmp->copy());
pkt->size()=i-tmp_size;
ss_buf->lookup(Search_BCID(user)->srcIP)->fragQUEUE.enque(tmp->copy());
//printf("Complete a MPDU\n The remaining fragment is stored in queue\n");
tmp_size = PDUSIZE;
goto SS_Frag_que;
}
}
}
num--;
}
resumeSSBurst.start(0.00001,user);
return;
}
Packet* Mac802_16::Add_Mac_Header(Packet* p,int CID,packet_t ptype)
{
struct hdr_cmn* ch=HDR_CMN(p);
struct hdr_mac802_16* mac_16 =HDR_MAC802_16(p);
ch->uid() = 0;
ch->ptype() = ptype;
ch->iface() = -2;
ch->error() = 0;
ch->size() = 24+PDUSIZE;
mac_16->HT = 0;
mac_16->EC = 0;
mac_16->CI = 0;
mac_16->LEN = 24+PDUSIZE;
mac_16->CID = CID;
(p->type_==1) ? mac_16->type=1 : mac_16->type=2;
return p;
}
void Mac802_16::ResumeBS16timerHandler(int user)
{
if(Queue_list->Search_BCID(user)->PDUQueue.length()==0)
{
resumeBSBurst.stop();
return;
}
else
{
//printf("BS
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -