/* 输入:随机接入队列,当前节点的指针 输出:随机接入调度完成后,剩余的资源 如果没有资源,则返回0 */ static unsigned int Do_DL_RIV(u16 rapid) { int Nprb,lcrbs; int RBstart,RIV; int i; u16 rnti; FIN(Do_DL_RIV()); SV_PTR_GET(mac_sv); Nprb=GetNprb(); lcrbs=Nprb/DL_SCHEDULE_NUM; lcrbs=lcrbs/4;//decrease the value of RIV to send; rnti=convert_rapid_rnti(rapid); switch(rnti)//5个用户中的第几个,0:0-19PRB 1:20-39prb,以此类推 { case RNTI_A: RBstart=0;break; case RNTI_B : RBstart=20;break; case RNTI_C : RBstart=40;break; case RNTI_D : RBstart=60;break; case RNTI_E : RBstart=80;break; default: fsm_printf("Do_DL_RIV function sth is wrong!");break; } //note:the length of RIV->RAR_DCI,is 9bit----means the biggest value is:2^9-1=511 if(lcrbs <= 1 + Nprb/2) //down limit { RIV=Nprb*(lcrbs-1)+RBstart;//420 } else { RIV=Nprb*(Nprb-lcrbs+1)+(Nprb-1-RBstart); } //test code Geng 20141027 fsm_printf("\nIn the function DL_RIV the value of RIV is:%d\n",RIV); FRET(RIV); }
//函数能够将bsr的大小和物理层上传的数据,增加到S_UEinfo的队列中。 void Add_sueinfo_Node(PHYtoMAC_Info *temp, int m_bsr, int type_bsr) { struct S_UEinfo * p_ul_UEinfo; FIN(Add_sueinfo_Node()); SV_PTR_GET(mac_sv); p_ul_UEinfo=(S_UEinfo *)fsm_mem_alloc(sizeof(S_UEinfo)); while(p_ul_UEinfo==NULL)//申请内存失败 p_ul_UEinfo=(S_UEinfo *)fsm_mem_alloc(sizeof(S_UEinfo)); p_ul_UEinfo->datasizeof_bsr =cal_bsrsize(m_bsr,type_bsr); p_ul_UEinfo->rnti =temp->rnti; p_ul_UEinfo->cqi =temp->cqi; p_ul_UEinfo->crc =temp->crc; p_ul_UEinfo->harqindex =temp->harqindex; //p_ul_UEinfo->pgtype =temp->pgtype; p_ul_UEinfo->pmi =temp->pmi; p_ul_UEinfo->sfn =temp->sfn; p_ul_UEinfo->sr =temp->sr; p_ul_UEinfo->subframeN =temp->subframeN; p_ul_UEinfo->ta =temp->ta; fsm_printf("###BSR_SIZE is:%d",p_ul_UEinfo->datasizeof_bsr); insert_ULschedQue(SV(ULschedQue_p), p_ul_UEinfo); //test_code Geng fsm_printf("\n###finsh inser node!\n"); FOUT; }
//此函数生成的是整个RAR下行数据包的DCI,由于RA-RNTI相同,多个UE可能仅RAPID不同; //但是在目前最简系统中,我们随机选择一个正在进行随机接入的UE的下行资源用来发送RAR, //就不会发生冲突(因为其还处于随机接入过程,没有下行数据发送,信道没有被占用) int Do_RAR_DCI1C(struct S_RAinfo *ra_UEinfo) { ENBMAC_TO_PHY_Rardci * p_rar_ici_dci; FIN(Do_RAR_DCI()); p_rar_ici_dci=(ENBMAC_TO_PHY_Rardci *)fsm_mem_alloc(sizeof(ENBMAC_TO_PHY_Rardci)); p_rar_ici_dci->m_rnti =ra_UEinfo->ra_rnti; p_rar_ici_dci->m_tbsize =Get_Format1C_TbSize(ra_UEinfo->cqi);//这个为什么是这样的,与RIV是对应的吗? p_rar_ici_dci->dci_format=4;//format 1C p_rar_ici_dci->cfi=Do_DlDci_cfi(); p_rar_ici_dci->rar_dci.m_gap =1;//还未找到出处,暂时使用Gap2(频域距离) //20141022由于为下行数据,下行用户是固定的,所以最简系统目前的RIV是与bitmap相对应的 //由于在随机接入前,UE并未获取C-RNTI,所以为了让下行静态调度结果与随机分配相结合,宏定义任意5个中的一个RNTI,得到RIV值(5个值是相同的) p_rar_ici_dci->rar_dci.RIV =Do_DL_RIV(ra_UEinfo->rapid); //此处还没有更改完全,RIV的资源分配应该和下行调度有关系 p_rar_ici_dci->rar_dci.I_TBS =Get_ITbSize(ra_UEinfo->cqi); p_rar_ici_dci->rar_dci.emptybits =0; //Test code Geng 20141027 fsm_printf("\n##After Test Do_RAR_DCI1C:"); fsm_printf("\nSome important paramters are:"); fsm_printf(" RA-RNTI:%d",p_rar_ici_dci->m_rnti); fsm_printf(" dci_format:%d",p_rar_ici_dci->dci_format); fsm_printf(" m_tbsize:%d",p_rar_ici_dci->m_tbsize); fsm_printf(" CFI:%d",p_rar_ici_dci->cfi); fsm_printf(" RIV:%d",p_rar_ici_dci->rar_dci.RIV); fsm_printf(" m_gap:%d",p_rar_ici_dci->rar_dci.m_gap); fsm_printf(" I_TBS:%d\n",p_rar_ici_dci->rar_dci.I_TBS); fsm_do_ioctrl(STRM_TO_SRIO, IOCCMD_MACTOPHY_RAR_DCI, (void *) p_rar_ici_dci, sizeof(ENBMAC_TO_PHY_Rardci)); fsm_mem_free(p_rar_ici_dci); FRET(Cal_usable_ResOfBitmap(ra_UEinfo->cqi,ra_UEinfo->subframeN)); }
/************************************************************************************************************************************************ **Function name:send_rrc_connection_release_msg_to_ue **Desciption:use for testing ,generated rrcConnectionRelease info **Input : **Output:generated rrcConnectionRelease info ,and stored in the global variable. **Created by:zhou yang **Created Date:2014/09/08 **-------------------------------------------------------------------------------------------------- **Modified by:zhou yang **Modified Date:2014/10/07 **Descriptions:modified format **-------------------------------------------------------------------------------------------------- *************************************************************************************************************************************************/ void send_rrc_connection_release_msg_to_ue() { SV_PTR_GET(rrc_sv_enb_ue); char *msg=NULL; int msg_len; int message_type; struct RRCConnectionRelease rrcConnectionRelease ; struct DL_DCCH_Message *dl_dcch_message; FIN(send_rrc_connection_release_msg_to_ue()); fsm_printf("[rrc] [conn_release] send_rrc_connection_release_msg_to_ue().\n"); dl_dcch_message=(struct DL_DCCH_Message *)fsm_mem_alloc(sizeof(struct DL_DCCH_Message )); rrcConnectionRelease.rrcTransactionIdentifier=1; rrcConnectionRelease.haveIdleModeMobilityControlInfo=true; rrcConnectionRelease.releaseCause=other; rrcConnectionRelease.idleModeMobilityControlInfo.have_t320=true; rrcConnectionRelease.idleModeMobilityControlInfo.t320_Value=min5; rrcConnectionRelease.idleModeMobilityControlInfo.haveCellReselectionPriorityInfo=false; dl_dcch_message->msg.rrcConnectionRelease=rrcConnectionRelease; dl_dcch_message->type=2; msg=(char*)dl_dcch_message; msg_len=sizeof(struct RRCConnectionRelease); message_type=4; //fsm_octets_print(msg, msg_len); packet_send_to_rlc(msg, msg_len, message_type, SV(crnti)); //fsm_mem_free(rrcConnectionRelease); //rrcConnectionRelease=NULL; FOUT; }
void ra_aloha_ss_init(void) { Objid my_objid; FIN(ra_aloha_ss_init()); /* * * stream : MAC [0] -> rt_0 [0] * stream : MAC [1] -> sink [0] * stream : rr_0 [0] -> MAC [0] * stream : traffic [0] -> MAC [1] */ svptr = (struct SS_SVar*) op_prg_mem_alloc(sizeof (struct SS_SVar)); svptr->istrm_hl=1; svptr->istrm_ll=0; svptr->ostrm_hl=1; svptr->ostrm_ll=0; my_objid = op_id_self(); op_ima_obj_attr_get_int32(my_objid, "SS ID", & svptr->ss_id); svptr->sh_load_bits = op_stat_reg("ALOHA SS.Load(bits/sec)", OPC_STAT_INDEX_NONE, OPC_STAT_LOCAL); svptr->sh_goodput_bits = op_stat_reg("ALOHA SS.Goodput(bits/sec)", OPC_STAT_INDEX_NONE, OPC_STAT_LOCAL); svptr->gsh_load_bits = op_stat_reg("ALOHA SS.Load(bits/sec)", OPC_STAT_INDEX_NONE, OPC_STAT_GLOBAL); FOUT; }
//GENG 2014/9/11更改 int Do_judge_rnti(u16 receive_rnti) { FIN(Do_judge_rnti()); SV_PTR_GET(mac_sv); if( C_RNTI == find_type_rnti(receive_rnti) )//C-RNTI { FRET(2); } if( TC_RNTI==find_type_rnti(receive_rnti) )//TC-RNTI { if( 1==SV(RAR_receive_crnti) )//同时,如果MAC控制单元中存在C-RNTI { recall_rnti(receive_rnti);//将该receive_rnti(即TC-RNTI收回) SV(RAR_receive_crnti)=0;// } else { fsm_printf("[xxx]: This UE is first access!\n"); } FRET(1); } if( 0==find_type_rnti(receive_rnti)) { fsm_printf("##error: system hasn't allocated the rnti\n"); FRET(0); } }
Opencell_Func_Fin_Status opencell_cur_frame_calc (Opencell_Frame_Struct* frame_struct, simtime_t cur_time) { int cur_slot_num; FIN(opencell_cur_frame_calc(frame_struct, cur_time)); assert(frame_struct); cur_slot_num = (int)(cur_time-global_share->start_of_epoch)/SLOT_DURATION; frame_struct->ts_seq = cur_slot_num % SLOT_PER_FRAME; frame_struct->hyper_frame_seq = (int) frame_struct->ts_seq / SLOT_PER_HYPERFRAME; frame_struct->super_frame_seq = frame_struct->ts_seq / SLOT_PER_SUPERFRAME; if (frame_struct->super_frame_seq>=2048) frame_struct->super_frame_seq %= 2048; /*how many TDMA frames are there?*/ frame_struct->tdma_frame_seq = (int) (frame_struct->ts_seq / SLOT_PER_FRAME); if (frame_struct->multiframe_type==Opencell_Ctrl) { frame_struct->multi_frame_seq = (int) (frame_struct->tdma_frame_seq / 51); frame_struct->tdma_frame_seq %= 51; } else { frame_struct->multi_frame_seq = (int) (frame_struct->tdma_frame_seq / 26); frame_struct->tdma_frame_seq %= 26; } FRET (OPENCELL_SUCCESS); }
/* ****************************** ->Change Data and time: ->Function:About DATA manage ->Change: ->Details:下面几个函数主要是完成数据的处理和计算 ->Special:GetNprb()函数,信道带宽取值为1.4/3/5/10/15/20,因为linux内核不支持浮点数,所以(int)(1.4)=1. ******************************* */ static unsigned int GetMcsFromCqi (u16 cqi) { unsigned int mcs; FIN(GetMcsFromCqi()); mcs = McsforCqi[cqi]; FRET(mcs); }
static unsigned int Get_Format1C_TbSize(u16 cqi) { unsigned int itbs; FIN(Get_Format1C_TbSize()); itbs=Get_ITbSize (cqi); FRET(TBSizeTableofFormat1c[itbs]); }
static unsigned int Get_ITbSize(u16 cqi) { unsigned int mcs,itbs; FIN(Get_ITbSize()); mcs=GetMcsFromCqi (cqi); itbs = Ul_McsToItbsize[mcs]; FRET(itbs); }
//计算绝对值上限的小函数,输入除数和被除数,输出商的上限。 static int cal_ul_abs(int divisor,int dividend) { int val; FIN(cal_ul_abs()); if(divisor % dividend != 0) val=(int)(divisor / dividend)+1; else val=(int)(divisor / dividend); FRET(val); }
static unsigned int Get_Dl_TbSize(u16 cqi,int nprb) { unsigned int mcs,itbs; FIN(Get_Dl_TbSize()); mcs=GetMcsFromCqi(cqi); itbs = Dl_McsToItbsize[mcs]; FRET(TransportBlockSizeTable[nprb - 1][itbs]); }
/*-------------------------------------------------------------------------------- * Function: wban_up0_traffic_generate * * Description: creates a MSDU requiring acknowledge based on the MSDU generation * specifications of the source model and sends it to the lower layer. * * No parameters *--------------------------------------------------------------------------------*/ static void wban_up0_traffic_generate() { Packet* msdu_ptr; Packet* app_traffic_ptr; int msdu_size; /* size in bits */ double next_intarr_time; /* interarrival time of next MSDU */ double abs_next_intarr_time; /* absolute interarrival time of next MSDU */ /* Stack tracing enrty point */ FIN (wban_up0_traffic_generate); /* Generate a MSDU size outcome. */ msdu_size = (int) ceil (oms_dist_outcome (up0_msdu_size_dist_ptr)); /* 0 <= MAC frame body <= pMaxFrameBodyLength_Bits */ if (msdu_size > pMaxFrameBodyLength_Bits) msdu_size = pMaxFrameBodyLength_Bits; /* The size of generated MSDU is bigger than the maximum - the size is set to the maximum. */ if (msdu_size < 0) msdu_size = 0; /* We produce unformatted packets. Create one. */ msdu_ptr = op_pk_create (msdu_size); /* create a App traffic frame that encapsulates the msdu packet */ app_traffic_ptr = op_pk_create_fmt ("wban_app_traffic_format"); /* increment the data sequence number by 1 at a time */ dataSN = (dataSN + 1) % 32768; op_pk_nfd_set (app_traffic_ptr, "App Sequence Number", dataSN); op_pk_nfd_set (app_traffic_ptr, "User Priority", 0); op_pk_nfd_set_pkt (app_traffic_ptr, "MSDU Payload", msdu_ptr); // wrap msdu in app traffic /* schedule next MSDU generation */ next_intarr_time = oms_dist_outcome (up0_msdu_interarrival_dist_ptr); /* Make sure that interarrival time is not negative. In that case it will be set to 0. */ if (next_intarr_time <0) next_intarr_time = 0.0; abs_next_intarr_time = op_sim_time () + next_intarr_time; // printf(" [Node %s] t = %f, msdu_create_time = %f, app_pkt_create_time = %f\n", \ // node_name, op_sim_time(), op_pk_creation_time_get(msdu_ptr), op_pk_creation_time_get(app_traffic_ptr)); /* send the App traffic via the stream to the lower layer. */ op_pk_send (app_traffic_ptr, STRM_FROM_UP_TO_MAC); // printf (" [Node %s] t= %f -> UP7 MSDU (size = %d bits) \ // was generated and sent to MAC layer.\n", node_name, op_sim_time(), msdu_size); if ((abs_next_intarr_time <= up0_stop_time) || (up0_stop_time == SC_INFINITE_TIME)) { up0_next_msdu_evh = op_intrpt_schedule_self (abs_next_intarr_time, SC_GENERATE_UP0); // printf ("\t Next UP0 MSDU will be generated at %f\n\n", abs_next_intarr_time); } /* Stack tracing exit point */ FOUT; }
//返回接收到的rnti对应的类型 //可以用来调用,以确认rnti是那种类型,从而判断当前系统处于什么状态 static unsigned short find_type_rnti(u16 receive_rnti) { int i; FIN(find_rnti()); SV_PTR_GET(mac_sv); for(i=0;i<NUM_RNTI;i++) { if(SV(rntiarray[i]).m_rnti==receive_rnti) FRET(SV(rntiarray[i]).Type_rnti); } }
static unsigned short Do_Data_of_MacRarPdu_BI(u16 subframe,u16 cqi) { // FIN(Do_Data_of_MacRarPdu_BI()); if(Do_ulgrant_ulDelay(subframe,cqi)==1) { FRET(1); } else FRET(0);//backoff=0; }
//上行子帧现假设全部资源可用,待物理层设计好上行链路后再细化 static unsigned int Get_Ul_PerPrb_Datasize(u16 cqi)/* u16 subframe*/ { unsigned int mcs; unsigned int modulation_order; unsigned int datasize; FIN(Get_Ul_PerPrb_Datasize()); mcs=GetMcsFromCqi(cqi); modulation_order=Ul_ModulationSchemeForMcs[mcs]; datasize=modulation_order*12*(CPMODE_OFDM*2); FRET(datasize); }
static void note_tc_rnti() { int i; FIN(note_tc_rnti()); SV_PTR_GET(mac_sv); for(i=0;i<NUM_RNTI;i++) { if(SV(rntiarray[i].Type_rnti) == TC_RNTI)//如果是TC-RNTI SV(tc_rnti_notes[i])=1; } FOUT; }
Packet* ra_aloha_ss_dequeue(void) { Packet* pkptr; FIN(ra_aloha_ss_dequeue()); //if (op_subq_empty()) return; // pkptr = op_subq_pk_remove(0, OPC_QPOS_HEAD); FRET (pkptr); }
/************************************************************************************************************************************************ **Function name:stop_timer **Desciption:stop all timer except t320 **Input : **Output: **Created by:zhou yang **Created Date:2014/09/08 **-------------------------------------------------------------------------------------------------- **Modified by:zhou yang **Modified Date:2014/09/30 **Descriptions:modified format **-------------------------------------------------------------------------------------------------- *************************************************************************************************************************************************/ void stop_timer(void) { FIN(stop_timer()); SV_PTR_GET(rrc_sv_enb_ue); fsm_printf("[rrc] [conn_release] stop_timer().\n"); // cancleTimer(0); // cancleTimer(1); // cancleTimer(2); // cancleTimer(5); // cancleTimer(11); // cancleTimer(21); FOUT; }
//根据rnti的值,返回该rnti值对应的数据量,给令牌桶使用byte int Do_cal_datasize(u16 rnti) { int i; FIN(Do_cal_datasize()); SV_PTR_GET(mac_sv); for(i=0;i<DL_SCHEDULE_NUM;i++) { if(SV(schedule_scheme[i]).m_rnti==rnti) FRET(SV(schedule_scheme[i]).m_data_size); } FRET(0);//modified by lhl 没有匹配的RNTI,返回0 }
//用于检查prb_bitmap是否有剩余资源,prb_bitmap2、prb_bitmap7; //目前资源分配的原则是顺序分配,即如果发现某个prb_bitmap位不等于0,则代表后面的资源均未被分配。 //输入:cqi,mac层bitmap映射物理层,但是不同的终端的cqi不同则调制方式可能不同,从而导致每个prb可以承载的数据量不同 static int Cal_usable_ResOfBitmap(u16 cqi,u16 subframe) { int i,remain_res,idle_bit2,idle_bit7; FIN(Cal_usable_ResOfBitmap()); SV_PTR_GET(mac_sv); idle_bit2=idle_bit7=0;//如果bitmap2和7均无剩余位,则函数返回0. if(subframe==2) { for(i=0;i<100;i++) { if(0==SV(next_prb_bitmap2[i])) { idle_bit2=100-i; break; } } for(i=0;i<100;i++) { if(0==SV(prb_bitmap7[i])) { idle_bit7=100-i; break; } } } if(subframe==7) { for(i=0;i<100;i++) { if(0==SV(next_prb_bitmap2[i])) { idle_bit2=100-i; break; } } for(i=0;i<100;i++) { if(0==SV(next_prb_bitmap7[i])) { idle_bit7=100-i; break; } } } remain_res=Get_Ul_PerPrb_Datasize(cqi) * (idle_bit2 + idle_bit7); FRET(remain_res); }
static unsigned int Get_Dl_PerPrb_Datasize(u16 cqi, u16 subframe) { unsigned int mcs; unsigned int modulation_order; unsigned int datasize; FIN(Get_Dl_PerPrb_Datasize()); mcs=GetMcsFromCqi(cqi); modulation_order=Dl_ModulationSchemeForMcs[mcs]; if(subframe==1 || subframe==6) datasize=modulation_order*12*(CPMODE_OFDM*2-CFI_OFDM-SPECIAL_OFDM)-8;//424 除去特殊子帧占用的部分,还需要减去天线RS占用的 else datasize=modulation_order*12*(CPMODE_OFDM*2-CFI_OFDM)-12;//612 减去RS占用的 FRET(datasize); }
//清空prb_bitmap函数。 //20141018改 void Reset_Prb_Bitmap() { int i; FIN(Reset_Prb_Bitmap()); SV_PTR_GET(mac_sv); for(i=0;i<100;i++) { SV(prb_bitmap7[i])=SV(next_prb_bitmap7[i]); SV(next_prb_bitmap7[i])=0; SV(next_prb_bitmap2[i])=0; } FOUT; }
simtime_t opencell_next_slot (simtime_t cur_time) { simtime_t next_slot_time; //simtime_t delta; int times; double delta; double cur_time_; FIN(opencell_next_slot() ); times = (int) ((double)cur_time) / SLOT_DURATION; next_slot_time = (times+1)*SLOT_DURATION; FRET (next_slot_time); }
void ra_aloha_ss_sche_retx(double time_offset) { static int retx_times = 0; FIN(ra_aloha_ss_sche_retx); op_intrpt_schedule_self(Cur_Time+time_offset, TR_RETX); if (retx_times++ > max_retx_times) { errh_print(Err_Cause_Max_Retx_Exceed); }; FOUT; }
void delete_overtime_tc_rnti() { int i; FIN(delete_overtime_tc_rnti()); SV_PTR_GET(mac_sv); //重新启动定时器 fsm_schedule_self(2000000 , TC_RNTI_CHECK_TIMER); for(i=0;i<NUM_RNTI;i++) { if( SV(tc_rnti_notes[i])== 1 && SV(rntiarray[i].Type_rnti)==TC_RNTI)//20ms过后,如果存在TC-RNTI且其tcrnti的记录表记录为有tc-rnti SV(rntiarray[i].Type_rnti) = UNALLOCATED_RNTI; } note_tc_rnti();//重新记录TC-RNTI状态 FOUT; }
//回收分配出去的rnti值 static void recall_rnti(u16 receive_rnti) { int i; FIN(recall_tc_rnti()); SV_PTR_GET(mac_sv); for(i=0;i<NUM_RNTI;i++) { if(receive_rnti==SV(rntiarray[i]).m_rnti) { SV(rntiarray[i]).Type_rnti=UNALLOCATED_RNTI; } } FOUT; }
static unsigned short convert_rapid_rnti(u16 RAPID) { unsigned short rnti; FIN(convert_rapid_rnti()); if(RAPID==1) rnti=RNTI_A; if(RAPID==2) rnti=RNTI_B; if(RAPID==3) rnti=RNTI_C; if(RAPID==4) rnti=RNTI_D; if(RAPID==5) rnti=RNTI_E; FRET(rnti); }
static unsigned short DoAllocate_Rnti(int m_type_rnti) { int i; FIN(DoAllocate_Rnti()); SV_PTR_GET(mac_sv); for(i=5;i<NUM_RNTI;i++) { //07、30加,耿灿锡,目前仅考虑了分配TC-RNTI的情况,所以&&了tc-ranti的标记数组,防止在20ms内同一个rnti值被重复分配,引起tc-rnti定时清除的错误 if(UNALLOCATED_RNTI==SV(rntiarray[i]).Type_rnti && SV(tc_rnti_notes[i])!=1) { SV(rntiarray[i]).Type_rnti=m_type_rnti; break; } } FRET(SV(rntiarray[i]).m_rnti); }
//记录C-RNTI,TC-RNTI->C-RNTI void convert_TcRntiToCRnti(u16 receive_rnti) { int i; FIN(convert_TcRntiToCRnti()); SV_PTR_GET(mac_sv); for(i=0;i<NUM_RNTI;i++) { if(receive_rnti==SV(rntiarray[i]).m_rnti) { SV(rntiarray[i]).Type_rnti=C_RNTI; } } FOUT; }