Commit 7a1d8e30 authored by AlanLi's avatar AlanLi

Fixed bugs for SIB23

parent 0daeb68d
......@@ -223,8 +223,10 @@ void common_signal_procedures_NB_IoT(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc)
LTE_DL_FRAME_PARMS *fp = &eNB->frame_parms;
NB_IoT_eNB_NPBCH_t *broadcast_str = &eNB->npbch;
//NB_IoT_eNB_NDLSCH_t *sib1 = &eNB->ndlsch_SIB;
NB_IoT_DL_eNB_SIB_t *sib1 = &eNB->ndlsch_SIB.content_sib1;
NB_IoT_DL_eNB_SIB_t *sib23 = &eNB->ndlsch_SIB.content_sib23;
NB_IoT_eNB_NDLSCH_t *ndlsch = &eNB->ndlsch_SIB;
NB_IoT_DL_eNB_SIB_t *sib1 = &ndlsch->content_sib1;
NB_IoT_DL_eNB_SIB_t *sib23 = &ndlsch->content_sib23;
int **txdataF = eNB->common_vars.txdataF[0];
int subframe = proc->subframe_tx;
uint32_t frame = proc->frame_tx;
......@@ -299,6 +301,10 @@ void common_signal_procedures_NB_IoT(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc)
if(subframe == 0)
{
LOG_I(PHY,"MIB NB-IoT content:\n");
for(int i = 0; i<6;i++)
printf("%02X",broadcast_str->pdu[i]);
printf("\n");
generate_npbch(broadcast_str,
txdataF,
......@@ -313,6 +319,12 @@ void common_signal_procedures_NB_IoT(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc)
///////////////////////////////////////////////////////// SIB1 ////////////////////////////////////
if((subframe == 4) && (frame%2==0) && (frame%32<16) ) ////if((subframe != 0) && (subframe != 4) && (subframe != 9) )
{
LOG_I(PHY,"SIB1 NB-IoT content:\n");
for(int i = 0; i<6;i++)
printf("%02X",sib1->pdu[i]);
printf("\n");
if( frame%32 == 0 )
{
dlsch_encoding_NB_IoT(sib1_pdu,
......@@ -345,6 +357,11 @@ void common_signal_procedures_NB_IoT(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc)
//////////////////////////////////////////////////// SIB23 ////////////////////////////////////////////////////////////////////////
if( (subframe >0) && (subframe !=5) && (With_NSSS == 0) && (frame%2==1) && (frame%64<16) ) ////if((subframe != 0) && (subframe != 4) && (subframe != 9) )
{
LOG_I(PHY,"SIB2 NB-IoT content:\n");
for(int i = 0; i<6;i++)
printf("%02X",sib23->pdu[i]);
printf("\n");
if( subframe == 1 )
{
dlsch_encoding_NB_IoT(sib23_pdu,
......
......@@ -298,4 +298,4 @@ typedef struct rrc_config_NB_IoT_s{
}rrc_config_NB_IoT_t;
#endif
\ No newline at end of file
#endif
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.0 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
/*! \file eNB_scheduler_NB_IoT.c
* \brief top level of the scheduler, it scheduled in pdcch period based.
* \author NTUST BMW Lab./Nick HO, Xavier LIU, Calvin HSU
* \date 2017 - 2018
* \email: nick133371@gmail.com, sephiroth7277@gmail.com , kai-hsiang.hsu@eurecom.fr
* \author NTUST BMW Lab./
* \date 2017
* \email:
* \version 1.0
*
*/
......@@ -37,17 +18,6 @@
#define flag_css_type2 0x2
#define flag_uss_v 0x4
#if 0 // disable now
#define flag_css_type1_ce0 0x1
#define flag_css_type1_ce1 0x2
#define flag_css_type1_ce2 0x4
#define flag_css_type2_ce0 0x8
#define flag_css_type2_ce1 0x10
#define flag_css_type2_ce2 0x20
#define flag_uss_v 0x40
#endif
// common
#define flag_mib 0x1
......@@ -56,10 +26,6 @@
#define flag_nsss 0x8
#define num_flags 2
// type2 css, type1 css
//extern BCCH_DL_SCH_Message_NB_IoT_t SIB;
void eNB_scheduler_computing_flag_NB_IoT(eNB_MAC_INST_NB_IoT *mac_inst, uint32_t abs_subframe, uint32_t *scheduler_flags, uint32_t *common_flags, uint32_t *max_subframe){
......@@ -70,6 +36,7 @@ void eNB_scheduler_computing_flag_NB_IoT(eNB_MAC_INST_NB_IoT *mac_inst, uint32_t
//NPRACH_Parameters_NB_IoT_r13_t **type2_css_info = SIB.message.choice.c1.choice.systemInformation_r13.criticalExtensions.choice.systemInformation_r13.sib_TypeAndInfo_r13.choice.sib2_r13.radioResourceConfigCommon_r13.nprach_Config_r13.nprach_ParametersList_r13.list.array;
// fixed scheduling part (e.g. MIB, NPSS, NSSS, SIB1)
if(subframe == 0){
*common_flags |= flag_mib;
}else if(subframe == 5){
......@@ -81,7 +48,7 @@ void eNB_scheduler_computing_flag_NB_IoT(eNB_MAC_INST_NB_IoT *mac_inst, uint32_t
}
/* uint32_t type2_css_pp[3] = { type2_css_info[0]->npdcch_NumRepetitions_RA_r13*type2_css_info[0]->npdcch_StartSF_CSS_RA_r13, type2_css_info[1]->npdcch_NumRepetitions_RA_r13*type2_css_info[1]->npdcch_StartSF_CSS_RA_r13, type2_css_info[2]->npdcch_NumRepetitions_RA_r13*type2_css_info[2]->npdcch_StartSF_CSS_RA_r13 };*/
uint32_t type2_css_pp[3] = {256, 256, 256};
uint32_t type2_css_pp[3] = {256, 256, 256}; // TODO RRC config should get from structure
uint32_t start_subframe;
for(i=0; i<1; ++i){ // only CE0
start_subframe = 0;
......@@ -119,7 +86,7 @@ void eNB_scheduler_computing_flag_NB_IoT(eNB_MAC_INST_NB_IoT *mac_inst, uint32_t
}
}
*max_subframe = max;
*max_subframe = max; // the maximum subframe to be extend
}
/*function description:
......@@ -129,16 +96,13 @@ void eNB_scheduler_computing_flag_NB_IoT(eNB_MAC_INST_NB_IoT *mac_inst, uint32_t
void eNB_dlsch_ulsch_scheduler_NB_IoT(eNB_MAC_INST_NB_IoT *mac_inst, uint32_t abs_subframe){
int i;
uint8_t MIB_flag,SIB1_flag ;
uint8_t tx_mib=0, tx_sib1=0;
uint32_t scheduler_flags, max_subframe, common_flags;
/*Check this subframe should schedule something, set the flag*/
scheduler_flags = 0;
common_flags = 0;
MIB_flag = 0;
SIB1_flag = 0;
uint32_t h,f,sf;
int a;
eNB_scheduler_computing_flag_NB_IoT(mac_inst, abs_subframe, &scheduler_flags, &common_flags, &max_subframe);
if(scheduler_flags > 0){
......@@ -147,7 +111,7 @@ void eNB_dlsch_ulsch_scheduler_NB_IoT(eNB_MAC_INST_NB_IoT *mac_inst, uint32_t ab
maintain_available_resource(mac_inst);
if((abs_subframe % rachperiod[4]) == rachstart[0]){
if((abs_subframe % rachperiod[4]) == rachstart[0]){ //TODO, configuration should be pass by configuration module
add_UL_Resource();
}
......@@ -159,6 +123,7 @@ void eNB_dlsch_ulsch_scheduler_NB_IoT(eNB_MAC_INST_NB_IoT *mac_inst, uint32_t ab
//Check if type1 searching space scheduling
if((scheduler_flags&flag_css_type1)>0){
// paging, direct indication
scheduler_flags &= ~(flag_css_type1);
}
//The scheduling time is current subframe + 1
......@@ -175,22 +140,22 @@ void eNB_dlsch_ulsch_scheduler_NB_IoT(eNB_MAC_INST_NB_IoT *mac_inst, uint32_t ab
}
}
if(common_flags == flag_mib)
MIB_flag = 1;
if(common_flags == flag_sib1)
SIB1_flag = 1;
convert_system_number(abs_subframe, &h, &f, &sf);
if(common_flags&flag_mib){
tx_mib = 1;
}
if(common_flags&flag_sib1){
tx_sib1 = 1;
}
a = output_handler(mac_inst, (module_id_t)0, 0, h, f, sf, MIB_flag, SIB1_flag, abs_subframe);
convert_system_number(abs_subframe, &h, &f, &sf);
if(a != 0){
if(0 != output_handler(mac_inst, (module_id_t)0, 0, h, f, sf, tx_mib, tx_sib1, abs_subframe)){
LOG_D(MAC,"output handler error\n");
}
}
void schedule_uss_NB_IoT(module_id_t module_id, eNB_MAC_INST_NB_IoT *mac_inst, uint32_t subframe, uint32_t frame, uint32_t hypersfn, int index_ss)
{
// printf_FUNCTION_IN("[USS]");
//SCHEDULE_NB_IoT_t *scheduler = &eNB->scheduler;
mac_inst->scheduling_flag.flag_uss[0]=1;
......@@ -245,6 +210,5 @@ void schedule_uss_NB_IoT(module_id_t module_id, eNB_MAC_INST_NB_IoT *mac_inst, u
UE_ID = UE_template_temp->next;
}
// printf_FUNCTION_OUT("[USS]");
}
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.0 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
/*! \file eNB_scheduler_RA_NB_IoT.c
* \brief functions used in Random access scheduling
* \author NTUST BMW Lab./Calvin HSU
* \date 2017 - 2018
* \email: kai-hsiang.hsu@eurecom.fr
* \author NTUST BMW Lab./
* \date 2017
* \email:
* \version 1.0
*
*/
#include "assertions.h"
#include "platform_types.h"
#include "PHY/defs.h"
#include "PHY/extern.h"
#include "msc.h"
#include "SCHED/defs.h"
#include "SCHED/extern.h"
#include "LAYER2/MAC/defs.h"
#include "LAYER2/MAC/extern.h"
#include "LAYER2/MAC/proto.h"
#include "UTIL/LOG/log.h"
#include "UTIL/LOG/vcd_signal_dumper.h"
#include "UTIL/OPT/opt.h"
#include "OCG.h"
#include "OCG_extern.h"
#include "RRC/LITE/extern.h"
#include "RRC/L2_INTERFACE/openair_rrc_L2_interface.h"
//#include "LAYER2/MAC/pre_processor.c"
#include "pdcp.h"
#if defined(ENABLE_ITTI)
# include "intertask_interface.h"
#endif
#include "SIMULATION/TOOLS/defs.h" // for taus
#include "T.h"
///////////////////////////////////////////////////////////////////////////////////////////////////////
#include "defs_NB_IoT.h"
#include "proto_NB_IoT.h"
#include "extern_NB_IoT.h"
......@@ -146,7 +92,6 @@ uint16_t find_suit_i_delay(uint32_t rmax, uint32_t r, uint32_t dci_candidate){
void schedule_rar_NB_IoT(eNB_MAC_INST_NB_IoT *mac_inst, int abs_subframe){
// printf_FUNCTION_IN("schedule rar");
RA_TEMPLATE_NB_IoT *msg2_nodes = mac_inst->RA_msg2_list.head;
//RA_TEMPLATE_NB_IoT *msg3_list_tail = mac_inst->RA_msg3_list.tail;
RA_TEMPLATE_NB_IoT *migrate_node;
......@@ -282,11 +227,6 @@ void schedule_rar_NB_IoT(eNB_MAC_INST_NB_IoT *mac_inst, int abs_subframe){
dci_result->R_harq = 0;
dci_result->next = (schedule_result_t *)0;
dci_result->DCI_pdu = (void *)dci_n1_rar;
//dci_result->printf_str = &str1[0];
//dci_result->dl_sdly = msg2_subframe - dci_end_subframe;
//dci_result->ul_sdly = msg3_subframe - msg2_end_subframe;
//dci_result->num_sf = msg2_end_subframe - msg2_subframe+1;
// for msg2
msg2_result->output_subframe = msg2_first_subframe;//msg2_subframe;
msg2_result->end_subframe = msg2_end_subframe;
......@@ -301,10 +241,7 @@ void schedule_rar_NB_IoT(eNB_MAC_INST_NB_IoT *mac_inst, int abs_subframe){
msg2_result->R_harq = 0;
msg2_result->next = (schedule_result_t *)0;
msg2_result->DCI_pdu = (void *)dci_n1_rar;
//msg2_result->printf_str = str2;
msg2_result->rar_buffer = msg2_nodes->rar_buffer;
//msg2_result->dl_sdly = -1;
//msg2_result->ul_sdly = -1;
// for msg3(fake DCI N0)
dci_n0->type = 0;
......@@ -374,8 +311,6 @@ void schedule_rar_NB_IoT(eNB_MAC_INST_NB_IoT *mac_inst, int abs_subframe){
if(flag==1)
LOG_D(MAC,"[%04d][RA scheduler][MSG2] failed number: %d\n", abs_subframe-1, fail_num);
//printf_FUNCTION_OUT("schedule rar");
return ;
}
......@@ -607,13 +542,6 @@ void schedule_msg3_retransimission_NB_IoT(eNB_MAC_INST_NB_IoT *mac_inst, int abs
dci_result->R_harq = 0;
dci_result->next = (schedule_result_t *)0;
dci_result->DCI_pdu = (void *)dci_n0_msg3;
// dci_result->printf_str = str6;
// dci_result->dl_sdly = msg3_subframe - dci_end_subframe + 1;
// dci_result->ul_sdly = -1;
//dci_result->num_sf = -1;
//dci_result->harq_round = msg3_nodes->msg3_retransmit_count;
//simulate_rx(&simulate_rx_msg3_list, msg3_nodes->ue_rnti, npusch_info.sf_start);
// fill dci resource
fill_resource_DL(mac_inst, dci_node, dci_first_subframe, dci_end_subframe, dci_result);
......@@ -699,7 +627,6 @@ void receive_msg4_ack_NB_IoT(eNB_MAC_INST_NB_IoT *mac_inst, rnti_t rnti){
// msg4 scheduling: both first time or retransmit would be scheduled in this function(msg4_list).
void schedule_msg4_NB_IoT(eNB_MAC_INST_NB_IoT *mac_inst, int abs_subframe){
//printf_FUNCTION_IN("[SCHEDULER RA MSG4]");
RA_TEMPLATE_NB_IoT *msg4_nodes = mac_inst->RA_msg4_list.head;//, *migrate_node;
available_resource_DL_t *dci_node, *msg4_node;
......@@ -761,8 +688,6 @@ void schedule_msg4_NB_IoT(eNB_MAC_INST_NB_IoT *mac_inst, int abs_subframe){
if(msg4_nodes->wait_msg4_ack == 0){
fail=0;
//printf_FUNCTION_IN("[SCHEDULER RA MSG4 DCI]");
// check dci resource
rmax = mac_inst->rrc_config.mac_NPRACH_ConfigSIB[msg4_nodes->ce_level].mac_npdcch_NumRepetitions_RA_NB_IoT;//32;
num_candidate = 8;//rmax / r;
......@@ -790,9 +715,6 @@ void schedule_msg4_NB_IoT(eNB_MAC_INST_NB_IoT *mac_inst, int abs_subframe){
//failed
fail|=1;
}
//printf_FUNCTION_OUT("[SCHEDULER RA MSG4 DCI]");
//printf_FUNCTION_IN("[SCHEDULER RA MSG4 PAYLOAD]");
// check msg4 resource
rep = dl_rep[msg4_nodes->ce_level];
num_msg4_subframe = 1*rep; // 8 subframes
......@@ -810,9 +732,7 @@ void schedule_msg4_NB_IoT(eNB_MAC_INST_NB_IoT *mac_inst, int abs_subframe){
//failed
fail|=2;
}
//printf_FUNCTION_OUT("[SCHEDULER RA MSG4 PAYLOAD]");
//printf_FUNCTION_IN("[SCHEDULER RA MSG4 HARQ]");
rep = mac_inst->rrc_config.mac_NPRACH_ConfigSIB[msg4_nodes->ce_level].mac_numRepetitionsPerPreambleAttempt_NB_IoT;
for(HARQ_delay=0;HARQ_delay<4;++HARQ_delay){
end_flagHARQ=Check_UL_resource(msg4_end_subframe+get_HARQ_delay(1, HARQ_delay), rep, &HARQ_info, 0, 1); // RA_template->R
......@@ -826,7 +746,6 @@ void schedule_msg4_NB_IoT(eNB_MAC_INST_NB_IoT *mac_inst, int abs_subframe){
if(4 == HARQ_delay){
fail |= 4;
}
//printf_FUNCTION_OUT("[SCHEDULER RA MSG4 HARQ]");
if(0==fail){
LOG_D(MAC,"[%04d][RA scheduler][MSG4][CE%d] rnti: %d scheduling success\n", abs_subframe-1, msg4_nodes->ce_level, msg4_nodes->ue_rnti);
......@@ -857,10 +776,6 @@ void schedule_msg4_NB_IoT(eNB_MAC_INST_NB_IoT *mac_inst, int abs_subframe){
dci_result->R_harq = 0;
dci_result->next = (schedule_result_t *)0;
dci_result->DCI_pdu = (void *)dci_n1_msg4;
//dci_result->dl_sdly = msg4_subframe - dci_end_subframe;
//dci_result->ul_sdly = harq_subframe - msg4_end_subframe;
//dci_result->num_sf = msg4_end_subframe - msg4_subframe+1;
//dci_result->harq_round = msg4_nodes->msg4_retransmit_count;
// for msg4
msg4_result = (schedule_result_t *)malloc(sizeof(schedule_result_t));
......@@ -876,7 +791,6 @@ void schedule_msg4_NB_IoT(eNB_MAC_INST_NB_IoT *mac_inst, int abs_subframe){
msg4_result->R_harq = 0;
msg4_result->next = (schedule_result_t *)0;
msg4_result->DCI_pdu = (void *)dci_n1_msg4;
//msg4_result->harq_round = msg4_nodes->msg4_retransmit_count;
harq_result = (schedule_result_t *)malloc(sizeof(schedule_result_t));
harq_result->rnti = msg4_nodes->ue_rnti;
......@@ -891,18 +805,6 @@ void schedule_msg4_NB_IoT(eNB_MAC_INST_NB_IoT *mac_inst, int abs_subframe){
harq_result->channel = NPUSCH;
harq_result->next = (schedule_result_t *)0;
/*if(msg4_nodes->msg4_retransmit_count==0){
dci_result->printf_str = str3;
msg4_result->printf_str = str4;
harq_result->printf_str = str5;
}else{
dci_result->printf_str = str8;
msg4_result->printf_str = str9;
harq_result->printf_str = str10;
}*/
//simulate_rx(&simulate_rx_msg4_list, msg4_nodes->ue_rnti, harq_subframe);
LOG_D(MAC,"[%04d][RA scheduler][MSG4] UE:%x MSG4DCI %d-%d MSG4 %d-%d HARQ %d-%d\n", abs_subframe-1, msg4_nodes->ue_rnti, dci_first_subframe, dci_end_subframe, msg4_first_subframe, msg4_end_subframe, HARQ_info.sf_start, HARQ_info.sf_end);
LOG_D(MAC,"[%04d][RA scheduler][MSG4][CE%d] MSG4 DCI %d-%d MSG4 %d-%d HARQ %d-%d\n", abs_subframe-1, msg4_nodes->ce_level, dci_first_subframe, dci_end_subframe, msg4_first_subframe, msg4_end_subframe, HARQ_info.sf_start, HARQ_info.sf_end);
msg4_nodes->msg4_retransmit_count++;
......@@ -933,12 +835,10 @@ void schedule_msg4_NB_IoT(eNB_MAC_INST_NB_IoT *mac_inst, int abs_subframe){
msg4_nodes = msg4_nodes->next;
}
//printf_FUNCTION_OUT("[SCHEDULER RA MSG4]");
return ;
}
void schedule_RA_NB_IoT(eNB_MAC_INST_NB_IoT *mac_inst){
//printf_FUNCTION_IN("[SCHEDULER RA]");
uint32_t schedule_subframe = mac_inst->current_subframe + 1;
schedule_subframe = schedule_subframe % 1048576; // 20 bits, 10 bits + 10 bits
......@@ -947,7 +847,6 @@ void schedule_RA_NB_IoT(eNB_MAC_INST_NB_IoT *mac_inst){
schedule_rar_NB_IoT(mac_inst, schedule_subframe);
schedule_msg4_NB_IoT(mac_inst, schedule_subframe);
//printf_FUNCTION_OUT("[SCHEDULER RA]");
return ;
}
......@@ -1000,55 +899,5 @@ void fill_rar_NB_IoT(
rar[5] = (uint8_t)(ra_template->ue_rnti&0xff);
}
///////////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////// NB-IoT testing /////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////
void initiate_ra_proc_NB_IoT(module_id_t module_idP, int CC_id,frame_t frameP, uint16_t preamble_index,int16_t timing_offset,uint8_t sect_id,sub_frame_t subframeP,
uint8_t f_id)
{
uint8_t i;
RA_TEMPLATE *RA_template = (RA_TEMPLATE *)&eNB_mac_inst[module_idP].common_channels[CC_id].RA_template[0];
printf("xxxxxxxxxxxxxxxx NB-IoT xxxxxxxxxxxxxx");
for (i=0; i<NB_RA_PROC_MAX; i++) {
if (RA_template[i].RA_active==FALSE &&
RA_template[i].wait_ack_Msg4 == 0) {
// int loop = 0;
RA_template[i].RA_active=TRUE;
RA_template[i].generate_rar=1;
RA_template[i].generate_Msg4=0;
RA_template[i].wait_ack_Msg4=0;
RA_template[i].timing_offset=timing_offset;
RA_template[i].RA_rnti = 1 + (frameP/4);
RA_template[i].preamble_index = preamble_index;
/* TODO: find better procedure to allocate RNTI */
/* do {
RA_template[i].rnti = taus();
loop++;
} while (loop != 100 &&
// TODO: this is not correct, the rnti may be in use without
// being in the MAC yet. To be refined.
//
/// !(find_UE_id(module_idP, RA_template[i].rnti) == -1 &&
// 1024 and 60000 arbirarily chosen, not coming from standard //
// RA_template[i].rnti >= 1024 && RA_template[i].rnti < 60000));
if (loop == 100) {
printf("%s:%d:%s: FATAL ERROR! contact the authors\n", __FILE__, __LINE__, __FUNCTION__); abort(); }
RA_template[i].RA_rnti = 1 + (frameP/4);
RA_template[i].preamble_index = preamble_index; /// preamble_index=000000;
LOG_D(MAC,"[eNB %d][RAPROC] CC_id %d Frame %d Activating RAR generation for process %d, rnti %x, RA_active %d\n",
module_idP,CC_id,frameP,i,RA_template[i].rnti,
RA_template[i].RA_active);*/
return;
}
}
LOG_E(MAC,"[eNB %d][RAPROC] FAILURE: CC_id %d Frame %d Initiating RA procedure for preamble index %d\n",module_idP,CC_id,frameP,preamble_index);
}
......@@ -464,8 +464,8 @@ int l2_init(LTE_DL_FRAME_PARMS *frame_parms,int eMBMS_active, char *uecap_xer,ui
mac_xface->eNB_dlsch_ulsch_scheduler = eNB_dlsch_ulsch_scheduler;
mac_xface->get_dci_sdu = get_dci_sdu;
mac_xface->fill_rar = fill_rar;
//mac_xface->initiate_ra_proc = initiate_ra_proc;
mac_xface->initiate_ra_proc = initiate_ra_proc_NB_IoT;
mac_xface->initiate_ra_proc = initiate_ra_proc;
//mac_xface->initiate_ra_proc = initiate_ra_proc_NB_IoT;
mac_xface->cancel_ra_proc = cancel_ra_proc;
mac_xface->set_msg3_subframe = set_msg3_subframe;
mac_xface->SR_indication = SR_indication;
......
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.0 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
/*! \file main_NB_IoT.c
* \brief top init of Layer 2
* \author NTUST BMW Lab./Nick HO, Xavier LIU, Calvin HSU
* \date 2017 - 2018
* \email: nick133371@gmail.com, sephiroth7277@gmail.com , kai-hsiang.hsu@eurecom.fr
* \author NTUST BMW LAB./
* \date 2017
* \version 1.0
*
* \email:
*/
......@@ -71,6 +51,7 @@ void init_mac_NB_IoT(eNB_MAC_INST_NB_IoT *mac_inst)
LOG_I(MAC,"[NB-IoT] MAC start initialization\n");
mac_inst->current_subframe = 0;
for(i=0;i<64;++i)
{
mac_inst->sib1_flag[i] = 0;
......@@ -119,6 +100,7 @@ void init_mac_NB_IoT(eNB_MAC_INST_NB_IoT *mac_inst)
mac_inst->rrc_config.si_window_length = ms160;
mac_inst->rrc_config.sibs_NB_IoT_sched[0].si_periodicity = rf64;
mac_inst->rrc_config.si_radio_frame_offset = 1;
for(i=0;i<256;++i){
mac_inst->sibs_table[i] = -1;
......@@ -183,45 +165,14 @@ void init_mac_NB_IoT(eNB_MAC_INST_NB_IoT *mac_inst)
LOG_I(MAC,"[NB-IoT] List_number %d R_max %d G %.1f a_offset %.1f T %d SS_start %d\n", i, (mac_inst->UE_list_spec+i)->NPDCCH_config_dedicated.R_max, (mac_inst->UE_list_spec+i)->NPDCCH_config_dedicated.G, (mac_inst->UE_list_spec+i)->NPDCCH_config_dedicated.a_offset, (mac_inst->UE_list_spec+i)->NPDCCH_config_dedicated.T, (mac_inst->UE_list_spec+i)->NPDCCH_config_dedicated.ss_start_uss);
}
/*
//Initial one UE template
//UE_TEMPLATE_NB_IoT *UE_info=(UE_TEMPLATE_NB_IoT*)malloc(USER_NUM_USS*sizeof(UE_TEMPLATE_NB_IoT));
mac_inst->UE_list_spec->head=0;
mac_inst->UE_list_spec->tail=0;
for(i=0;i<USER_NUM_USS;++i)
{
UE_info_setting(mac_inst->UE_list_spec->UE_template_NB_IoT+i);
if(i==0)
{
(mac_inst->UE_list_spec->UE_template_NB_IoT+i)->prev=-1;
(mac_inst->UE_list_spec->UE_template_NB_IoT+i)->next=1;
//mac_inst->UE_list_spec->next[i]=-1;
}
else if(i>=USER_NUM_USS-1)
{
(mac_inst->UE_list_spec->UE_template_NB_IoT+i)->prev=i-1;
(mac_inst->UE_list_spec->UE_template_NB_IoT+i)->next=-1;
}
else
{
(mac_inst->UE_list_spec->UE_template_NB_IoT+i)->prev=i-1;
(mac_inst->UE_list_spec->UE_template_NB_IoT+i)->next=i+1;
}
//mac_inst->UE_list_spec->UE_template_NB_IoT[i]=UE_info[i];
mac_inst->UE_list_spec->tail=i;
}
*/
//UL initial
//Setting nprach configuration
setting_nprach();
//Initialize uplink resource from nprach configuration
Initialize_Resource();
//add_UL_Resource(mac_inst);
extend_available_resource_DL(mac_inst, mac_inst->current_subframe + 1 + 160);
extend_available_resource_DL(mac_inst, mac_inst->current_subframe + 1 + mac_inst->rrc_config.si_window_length);
}
......
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.0 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
/*! \file schedule_tool_NB_IoT.c
* \brief scheduler helper function
* \author NTUST BMW Lab./Nick HO, Xavier LIU, Calvin HSU
* \date 2017 - 2018
* \email: nick133371@gmail.com, sephiroth7277@gmail.com , kai-hsiang.hsu@eurecom.fr
* \author NTUST BMW Lab./
* \date 2017
* \email:
* \version 1.0
*
*/
......@@ -118,30 +99,30 @@ void print_scheduling_result_UL(void)
void setting_nprach(){
nprach_list[0].nprach_Periodicity = rachperiod[4];
nprach_list[0].nprach_StartTime = rachstart[0];
nprach_list[0].nprach_SubcarrierOffset = rachscofst[0];
nprach_list[0].nprach_NumSubcarriers = rachnumsc[0];
nprach_list[0].numRepetitionsPerPreambleAttempt = rachrepeat[1];
nprach_list[1].nprach_Periodicity = rachperiod[4];
nprach_list[1].nprach_StartTime = rachstart[0];
nprach_list[1].nprach_SubcarrierOffset = rachscofst[1];
nprach_list[1].nprach_NumSubcarriers = rachnumsc[0];
nprach_list[1].numRepetitionsPerPreambleAttempt = rachrepeat[3];
nprach_list[2].nprach_Periodicity = rachperiod[4];
nprach_list[2].nprach_StartTime = rachstart[0];
nprach_list[2].nprach_SubcarrierOffset = rachscofst[2];
nprach_list[2].nprach_NumSubcarriers = rachnumsc[1];
nprach_list[2].numRepetitionsPerPreambleAttempt = rachrepeat[5];
// fixed nprach configuration
nprach_list[0].nprach_Periodicity = rachperiod[4];
nprach_list[0].nprach_StartTime = rachstart[0];
nprach_list[0].nprach_SubcarrierOffset = rachscofst[0];
nprach_list[0].nprach_NumSubcarriers = rachnumsc[0];
nprach_list[0].numRepetitionsPerPreambleAttempt = rachrepeat[1];
nprach_list[1].nprach_Periodicity = rachperiod[4];
nprach_list[1].nprach_StartTime = rachstart[0];
nprach_list[1].nprach_SubcarrierOffset = rachscofst[1];
nprach_list[1].nprach_NumSubcarriers = rachnumsc[0];
nprach_list[1].numRepetitionsPerPreambleAttempt = rachrepeat[3];
nprach_list[2].nprach_Periodicity = rachperiod[4];
nprach_list[2].nprach_StartTime = rachstart[0];
nprach_list[2].nprach_SubcarrierOffset = rachscofst[2];
nprach_list[2].nprach_NumSubcarriers = rachnumsc[1];
nprach_list[2].numRepetitionsPerPreambleAttempt = rachrepeat[5];
// fixed nprach configuration
}
void Initialize_Resource_node(available_resource_UL_t *tone_head, available_resource_UL_t *npusch_frame, int tone)
{
int i=0;
available_resource_UL_t *second_node;
......@@ -162,22 +143,22 @@ void Initialize_Resource_node(available_resource_UL_t *tone_head, available_reso
second_node->next =NULL;
tone_head->next = second_node;
*npusch_frame = *tone_head->next;
////////////////////////CALVIN TIMING DIAGRAM GENERATOR///////////////////////////
#ifdef TIMING_GENERATOR
uint32_t ii, jj;
for(ii=(nprach_list+i)->nprach_StartTime; ii<tone_head->start_subframe; ++ii){
if(ii == sim_end_time) break;
uint32_t ii, jj;
for(ii=(nprach_list+i)->nprach_StartTime; ii<tone_head->start_subframe; ++ii){
if(ii == sim_end_time) break;
for(jj=0; jj<(nprach_list+i)->nprach_NumSubcarriers; ++jj){
ul_scheduled(ii, 0, (nprach_list+i)->nprach_SubcarrierOffset + jj, _NPRACH, 0, (char *)0);
}
}
for(ii=tone_head->end_subframe+1; ii<second_node->start_subframe; ++ii){
if(ii == sim_end_time) break;
for(jj=0; jj<(nprach_list+i)->nprach_NumSubcarriers; ++jj){
ul_scheduled(ii, 0, (nprach_list+i)->nprach_SubcarrierOffset + jj, _NPRACH, 0, (char *)0);
}
}
ul_scheduled(ii, 0, (nprach_list+i)->nprach_SubcarrierOffset + jj, _NPRACH, 0, (char *)0);
}
}
for(ii=tone_head->end_subframe+1; ii<second_node->start_subframe; ++ii){
if(ii == sim_end_time) break;
for(jj=0; jj<(nprach_list+i)->nprach_NumSubcarriers; ++jj){
ul_scheduled(ii, 0, (nprach_list+i)->nprach_SubcarrierOffset + jj, _NPRACH, 0, (char *)0);
}
}
#endif
////////////////////////CALVIN TIMING DIAGRAM GENERATOR///////////////////////////
}
......@@ -194,52 +175,52 @@ void Initialize_Resource(void){
available_resource_UL->singletone2_Head = (available_resource_UL_t *)0;
available_resource_UL->singletone3_Head = (available_resource_UL_t *)0;
available_resource_UL->sixtone_end_subframe = 0;
available_resource_UL->threetone_end_subframe = 0;
available_resource_UL->singletone1_end_subframe = 0;
available_resource_UL->singletone2_end_subframe = 0;
available_resource_UL->singletone3_end_subframe = 0;
add_UL_Resource();
add_UL_Resource();
available_resource_UL->sixtone_end_subframe = 0;
available_resource_UL->threetone_end_subframe = 0;
available_resource_UL->singletone1_end_subframe = 0;
available_resource_UL->singletone2_end_subframe = 0;
available_resource_UL->singletone3_end_subframe = 0;
add_UL_Resource();
add_UL_Resource();
LOG_D(MAC,"Initialization of the UL Resource grid has been done\n");
}
void add_UL_Resource_node(available_resource_UL_t **head, uint32_t *end_subframe, uint32_t ce_level){
available_resource_UL_t *new_node, *iterator;
available_resource_UL_t *new_node, *iterator;
new_node = (available_resource_UL_t *)malloc(sizeof(available_resource_UL_t));
new_node->next = (available_resource_UL_t *)0;
new_node->next = (available_resource_UL_t *)0;
new_node->prev = (available_resource_UL_t *)0;
new_node->start_subframe = *end_subframe + ceil( (nprach_list+ce_level)->nprach_StartTime + 1.4*4*((nprach_list+ce_level)->numRepetitionsPerPreambleAttempt) ) ;
new_node->start_subframe = *end_subframe + ceil( (nprach_list+ce_level)->nprach_StartTime + 1.4*4*((nprach_list+ce_level)->numRepetitionsPerPreambleAttempt) ) ;
new_node->end_subframe = *end_subframe + (nprach_list+ce_level)->nprach_Periodicity - 1;
if( (available_resource_UL_t *)0 == *head){
*head = new_node;
new_node->prev = (available_resource_UL_t *)0;
}else{
iterator = *head;
while( (available_resource_UL_t *)0 != iterator->next){
iterator = iterator->next;
}
iterator->next = new_node;
new_node->prev = iterator;
}
if( (available_resource_UL_t *)0 == *head){
*head = new_node;
new_node->prev = (available_resource_UL_t *)0;
}else{
iterator = *head;
while( (available_resource_UL_t *)0 != iterator->next){
iterator = iterator->next;
}
iterator->next = new_node;
new_node->prev = iterator;
}
////////////////////////CALVIN TIMING DIAGRAM GENERATOR///////////////////////////
#ifdef TIMING_GENERATOR
uint32_t ii, jj;
for(ii=*end_subframe+(nprach_list+ce_level)->nprach_StartTime; ii<new_node->start_subframe; ++ii){
if(ii >= sim_end_time) break;
for(jj=0; jj<(nprach_list+ce_level)->nprach_NumSubcarriers; ++jj){
ul_scheduled(ii, 0, (nprach_list+ce_level)->nprach_SubcarrierOffset + jj, _NPRACH, 0, (char *)0);
}
}
for(ii=*end_subframe+(nprach_list+ce_level)->nprach_StartTime; ii<new_node->start_subframe; ++ii){
if(ii >= sim_end_time) break;
for(jj=0; jj<(nprach_list+ce_level)->nprach_NumSubcarriers; ++jj){
ul_scheduled(ii, 0, (nprach_list+ce_level)->nprach_SubcarrierOffset + jj, _NPRACH, 0, (char *)0);
}
}
#endif
////////////////////////CALVIN TIMING DIAGRAM GENERATOR///////////////////////////
......@@ -248,12 +229,12 @@ void add_UL_Resource_node(available_resource_UL_t **head, uint32_t *end_subframe
/// Use to extend the UL resource grid (5 list) at the end of nprach peroid time
void add_UL_Resource(void)
{
add_UL_Resource_node(&available_resource_UL->sixtone_Head, &available_resource_UL->sixtone_end_subframe, 2);
add_UL_Resource_node(&available_resource_UL->threetone_Head, &available_resource_UL->threetone_end_subframe, 1);
add_UL_Resource_node(&available_resource_UL->singletone1_Head, &available_resource_UL->singletone1_end_subframe, 0);
add_UL_Resource_node(&available_resource_UL->singletone2_Head, &available_resource_UL->singletone2_end_subframe, 0);
add_UL_Resource_node(&available_resource_UL->singletone3_Head, &available_resource_UL->singletone3_end_subframe, 0);
{
add_UL_Resource_node(&available_resource_UL->sixtone_Head, &available_resource_UL->sixtone_end_subframe, 2);
add_UL_Resource_node(&available_resource_UL->threetone_Head, &available_resource_UL->threetone_end_subframe, 1);
add_UL_Resource_node(&available_resource_UL->singletone1_Head, &available_resource_UL->singletone1_end_subframe, 0);
add_UL_Resource_node(&available_resource_UL->singletone2_Head, &available_resource_UL->singletone2_end_subframe, 0);
add_UL_Resource_node(&available_resource_UL->singletone3_Head, &available_resource_UL->singletone3_end_subframe, 0);
}
int get_I_TBS_NB_IoT(int x,int y)
......@@ -528,8 +509,8 @@ int Check_UL_resource(uint32_t uplink_time, int total_ru, sched_temp_UL_NB_IoT_t
}
void insert_schedule_result(schedule_result_t **list, int subframe, schedule_result_t *node){
schedule_result_t *tmp, *tmp1;
if((schedule_result_t *)0 == *list){
schedule_result_t *tmp, *tmp1;
if((schedule_result_t *)0 == *list){
*list = node;
}else{
tmp = *list;
......@@ -544,12 +525,12 @@ void insert_schedule_result(schedule_result_t **list, int subframe, schedule_res
if((schedule_result_t *)0 == tmp){
tmp1->next = node;
}else{
node->next = tmp;
if(tmp1){
tmp1->next = node;
}else{
*list = node;
}
node->next = tmp;
if(tmp1){
tmp1->next = node;
}else{
*list = node;
}
}
}
}
......@@ -561,17 +542,17 @@ void generate_scheduling_result_UL(int32_t DCI_subframe, int32_t DCI_end_subfram
schedule_result_t *DL_result;
schedule_result_t *tmp1, *tmp;
UL_result->direction = UL;
UL_result->direction = UL;
UL_result->output_subframe = UL_subframe;
UL_result->end_subframe = UL_end_subframe;
UL_result->end_subframe = UL_end_subframe;
UL_result->DCI_pdu = DCI_inst;
UL_result->npusch_format = 0;
UL_result->DCI_release = 1;
UL_result->channel = NPUSCH;
UL_result->rnti = rnti;
UL_result->next = NULL;
//UL_result->printf_str = ul_printf_str;
//UL_result->printf_str = ul_printf_str;
if(-1 == DCI_subframe){
LOG_D(MAC,"[UL scheduler][UE:%05d] UL_result = output subframe : %d\n", rnti, UL_result->output_subframe);
......@@ -580,15 +561,15 @@ void generate_scheduling_result_UL(int32_t DCI_subframe, int32_t DCI_end_subfram
DL_result->output_subframe = DCI_subframe;
DL_result->end_subframe = DCI_end_subframe;
DL_result->DCI_pdu = DCI_inst;
DL_result->DCI_pdu = DCI_inst;
DL_result->DCI_release = 0;
DL_result->direction = DL;
DL_result->channel = NPDCCH;
DL_result->rnti = rnti;
DL_result->next = NULL;
//DL_result->printf_str = dl_printf_str;
insert_schedule_result(&schedule_result_list_DL, DCI_subframe, DL_result);
//DL_result->printf_str = dl_printf_str;
insert_schedule_result(&schedule_result_list_DL, DCI_subframe, DL_result);
LOG_D(MAC,"[UL scheduler][UE:%05d] DL_result = output subframe : %d UL_result = output subframe : %d\n", rnti, DL_result->output_subframe,UL_result->output_subframe);
}
......@@ -602,28 +583,28 @@ void generate_scheduling_result_UL(int32_t DCI_subframe, int32_t DCI_end_subfram
}else
{
tmp = schedule_result_list_UL;
while(tmp!=NULL)
{
if(UL_subframe < tmp->output_subframe)
{
break;
}
tmp1 = tmp;
tmp = tmp->next;
}
if(tmp==NULL)
{
tmp1->next = UL_result;
}
else
{
UL_result->next = tmp;
if(tmp1){
tmp1->next = UL_result;
}else{
schedule_result_list_UL = UL_result;
}
}
while(tmp!=NULL)
{
if(UL_subframe < tmp->output_subframe)
{
break;
}
tmp1 = tmp;
tmp = tmp->next;
}
if(tmp==NULL)
{
tmp1->next = UL_result;
}
else
{
UL_result->next = tmp;
if(tmp1){
tmp1->next = UL_result;
}else{
schedule_result_list_UL = UL_result;
}
}
}
......@@ -631,43 +612,43 @@ void generate_scheduling_result_UL(int32_t DCI_subframe, int32_t DCI_end_subfram
void adjust_UL_resource_list(sched_temp_UL_NB_IoT_t *NPUSCH_info)
{
available_resource_UL_t *temp;
available_resource_UL_t *node = NPUSCH_info->node;
// divided into two node
// keep one node(align left or right)
// delete node
int align_left = (node->start_subframe==NPUSCH_info->sf_start);
int align_right = (node->end_subframe==NPUSCH_info->sf_end);
switch(align_left+align_right){
case 0:
// divided into two node
temp = (available_resource_UL_t *)malloc(sizeof(available_resource_UL_t));
temp->next = node->next;
node->next = temp;
available_resource_UL_t *temp;
available_resource_UL_t *node = NPUSCH_info->node;
// divided into two node
// keep one node(align left or right)
// delete node
int align_left = (node->start_subframe==NPUSCH_info->sf_start);
int align_right = (node->end_subframe==NPUSCH_info->sf_end);
switch(align_left+align_right){
case 0:
// divided into two node
temp = (available_resource_UL_t *)malloc(sizeof(available_resource_UL_t));
temp->next = node->next;
node->next = temp;
temp->prev = node;
temp->start_subframe = NPUSCH_info->sf_end +1;
temp->end_subframe = node->end_subframe;
temp->start_subframe = NPUSCH_info->sf_end +1;
temp->end_subframe = node->end_subframe;
node->end_subframe = NPUSCH_info->sf_start - 1;
node->end_subframe = NPUSCH_info->sf_start - 1;
break;
case 1:
// keep one node
if(align_left){
node->start_subframe = NPUSCH_info->sf_end +1;
}else{
node->end_subframe = NPUSCH_info->sf_start - 1 ;
}
break;
case 2:
break;
case 1:
// keep one node
if(align_left){
node->start_subframe = NPUSCH_info->sf_end +1;
}else{
node->end_subframe = NPUSCH_info->sf_start - 1 ;
}
break;
case 2:
if(node!=NULL)
{
// delete
// delete
if(node->prev==(available_resource_UL_t *)0)
{
if(NPUSCH_info->tone==sixtone)
......@@ -692,25 +673,25 @@ void adjust_UL_resource_list(sched_temp_UL_NB_IoT_t *NPUSCH_info)
node->prev->next = (available_resource_UL_t *)0;
}
free(node);
break;
free(node);
break;
}
default:
//error
break;
}
default:
//error
break;
}
}
void add_ue_NB_IoT(eNB_MAC_INST_NB_IoT *mac_inst, uint16_t rnti, ce_level_t ce, uint32_t PHR, uint32_t ul_total_buffer){
int32_t i;
UE_list_NB_IoT_t *UE_list = (mac_inst->UE_list_spec + (uint32_t)ce);
for(i=0; i<MAX_NUMBER_OF_UE_MAX_NB_IoT; ++i){
if(UE_list->UE_template_NB_IoT[i].active == 0){
UE_list->UE_template_NB_IoT[i].active = 1;
UE_list->UE_template_NB_IoT[i].rnti = rnti;
UE_list->UE_template_NB_IoT[i].PHR = PHR;
UE_list->UE_template_NB_IoT[i].ul_total_buffer = ul_total_buffer;
//New UE setting start
int32_t i;
UE_list_NB_IoT_t *UE_list = (mac_inst->UE_list_spec + (uint32_t)ce);
for(i=0; i<MAX_NUMBER_OF_UE_MAX_NB_IoT; ++i){
if(UE_list->UE_template_NB_IoT[i].active == 0){
UE_list->UE_template_NB_IoT[i].active = 1;
UE_list->UE_template_NB_IoT[i].rnti = rnti;
UE_list->UE_template_NB_IoT[i].PHR = PHR;
UE_list->UE_template_NB_IoT[i].ul_total_buffer = ul_total_buffer;
//New UE setting start
UE_list->UE_template_NB_IoT[i].R_dl = dl_rep[(uint32_t)ce];;
UE_list->UE_template_NB_IoT[i].I_mcs_dl = 0;
UE_list->UE_template_NB_IoT[i].CE_level = (uint32_t)ce;
......@@ -725,45 +706,45 @@ void add_ue_NB_IoT(eNB_MAC_INST_NB_IoT *mac_inst, uint16_t rnti, ce_level_t ce,
UE_list->UE_template_NB_IoT[i].multi_tone = 1;
//New UE setting ending
UE_list->UE_template_NB_IoT[i].prev = -1;
if(-1 == UE_list->head){
UE_list->UE_template_NB_IoT[i].next = -1;
}else{
UE_list->UE_template_NB_IoT[i].next = UE_list->head;
}
UE_list->head = i;
return ;
}
}
if(-1 == UE_list->head){
UE_list->UE_template_NB_IoT[i].next = -1;
}else{
UE_list->UE_template_NB_IoT[i].next = UE_list->head;
}
UE_list->head = i;
return ;
}
}
}
void remove_ue(eNB_MAC_INST_NB_IoT *mac_inst, uint16_t rnti, ce_level_t ce){
int32_t i;
UE_list_NB_IoT_t *UE_list = (mac_inst->UE_list_spec + (uint32_t)ce);
for(i=0; i<MAX_NUMBER_OF_UE_MAX_NB_IoT; ++i){
if(UE_list->UE_template_NB_IoT[i].active == 1 && UE_list->UE_template_NB_IoT[i].rnti == rnti){
UE_list->UE_template_NB_IoT[i].active = 0;
return ;
}
}
int32_t i;
UE_list_NB_IoT_t *UE_list = (mac_inst->UE_list_spec + (uint32_t)ce);
for(i=0; i<MAX_NUMBER_OF_UE_MAX_NB_IoT; ++i){
if(UE_list->UE_template_NB_IoT[i].active == 1 && UE_list->UE_template_NB_IoT[i].rnti == rnti){
UE_list->UE_template_NB_IoT[i].active = 0;
return ;
}
}
}
//Transfrom source into hyperSF, Frame, Subframe format
void convert_system_number(uint32_t source_sf,uint32_t *hyperSF, uint32_t *frame, uint32_t *subframe)
{
if(source_sf>=1024*1024*10)
if(source_sf>=1024*1024*10)
{
source_sf=source_sf%(1024*1024*10);
}
*hyperSF = (source_sf/10)/1024;
*frame = (source_sf/10)%1024;
*subframe = (source_sf%10240)%10;
*frame = (source_sf/10)%1024;
*subframe = (source_sf%10240)%10;
}
//Trnasform hyperSF, Frame, Subframe format into subframe unit
uint32_t convert_system_number_sf(uint32_t hyperSF, uint32_t frame, uint32_t subframe)
{
return hyperSF*1024*10+frame*10+subframe;
return hyperSF*1024*10+frame*10+subframe;
}
/*input start position amd num_dlsf DL subframe, caculate the last subframe number*/
......@@ -865,147 +846,143 @@ void init_dlsf_info(eNB_MAC_INST_NB_IoT *mac_inst, DLSF_INFO_t *DLSF_info)
}
void init_tool_sib1(eNB_MAC_INST_NB_IoT *mac_inst){
int i, j;
int i, j;
//int repetition_pattern = 1;// 1:every2frame, 2:every4frame, 3:every8frame, 4:every16frame
for(i=0;i<8;++i){
mac_inst->sib1_flag[(i<<1)+mac_inst->rrc_config.sib1_NB_IoT_sched_config.starting_rf] = 1;
}
//int repetition_pattern = 1;// 1:every2frame, 2:every4frame, 3:every8frame, 4:every16frame
for(i=0;i<8;++i){
mac_inst->sib1_flag[(i<<1)+mac_inst->rrc_config.sib1_NB_IoT_sched_config.starting_rf] = 1;
}
for(i=0, j=0;i<64;++i){
if(mac_inst->sib1_flag[i]==1){
++j;
}
mac_inst->sib1_count[i]=j;
}
for(i=0, j=0;i<64;++i){
if(mac_inst->sib1_flag[i]==1){
++j;
}
mac_inst->sib1_count[i]=j;
}
mac_inst->sib1_period = 256 / mac_inst->rrc_config.sib1_NB_IoT_sched_config.repetitions;
mac_inst->sib1_period = 256 / mac_inst->rrc_config.sib1_NB_IoT_sched_config.repetitions;
return ;
return ;
}
uint32_t calculate_DLSF(eNB_MAC_INST_NB_IoT *mac_inst, int abs_start_subframe, int abs_end_subframe){ //LOG_D(MAC,"calcu %p %d %d\n", mac_inst, abs_start_subframe, abs_end_subframe);
int i;
int num_dlsf=0;
//int diff_subframe = abs_end_subframe - abs_start_subframe;
int start_frame = abs_start_subframe / 10;
int end_frame = abs_end_subframe / 10;
int start_subframe = abs_start_subframe % 10;
int end_subframe = abs_end_subframe % 10;
int start_frame_mod_64 = start_frame & 0x0000003f;
int end_frame_mod_64 = end_frame & 0x0000003f;
int start_frame_div_64 = (start_frame & 0xffffffc0)>>6;
int end_frame_div_64 = (end_frame & 0xffffffc0)>>6;
if(abs_start_subframe > abs_end_subframe){
return calculate_DLSF(mac_inst, abs_start_subframe, (MAX_FRAME*10)+9) + calculate_DLSF(mac_inst, 0, abs_end_subframe);
}
if(start_frame_div_64==end_frame_div_64 && start_frame==end_frame){
for(i=abs_start_subframe;i<=abs_end_subframe;++i){
num_dlsf += is_dlsf(mac_inst, i);
}
}else{
num_dlsf = mac_inst->dlsf_table[end_frame_mod_64];
num_dlsf -= (start_frame_mod_64==0)?0:mac_inst->dlsf_table[start_frame_mod_64-1];
for(i=0;i<start_subframe;++i, --abs_start_subframe){
num_dlsf -= is_dlsf(mac_inst, abs_start_subframe-1);
}
for(i=end_subframe;i<9;++i, ++abs_end_subframe){
num_dlsf -= is_dlsf(mac_inst, abs_end_subframe+1);
}
if(start_frame_div_64!=end_frame_div_64){
num_dlsf+= (472+(end_frame_div_64-start_frame_div_64-1)*472);
uint32_t calculate_DLSF(eNB_MAC_INST_NB_IoT *mac_inst, int abs_start_subframe, int abs_end_subframe){ //LOG_D(MAC,"calcu %p %d %d\n", mac_inst, abs_start_subframe, abs_end_subframe);
int i;
int num_dlsf=0;
//int diff_subframe = abs_end_subframe - abs_start_subframe;
int start_frame = abs_start_subframe / 10;
int end_frame = abs_end_subframe / 10;
int start_subframe = abs_start_subframe % 10;
int end_subframe = abs_end_subframe % 10;
int start_frame_mod_64 = start_frame & 0x0000003f;
int end_frame_mod_64 = end_frame & 0x0000003f;
int start_frame_div_64 = (start_frame & 0xffffffc0)>>6;
int end_frame_div_64 = (end_frame & 0xffffffc0)>>6;
if(abs_start_subframe > abs_end_subframe){
return calculate_DLSF(mac_inst, abs_start_subframe, (MAX_FRAME*10)+9) + calculate_DLSF(mac_inst, 0, abs_end_subframe);
}
if(start_frame_div_64==end_frame_div_64 && start_frame==end_frame){
for(i=abs_start_subframe;i<=abs_end_subframe;++i){
num_dlsf += is_dlsf(mac_inst, i);
}
}else{
num_dlsf = mac_inst->dlsf_table[end_frame_mod_64];
num_dlsf -= (start_frame_mod_64==0)?0:mac_inst->dlsf_table[start_frame_mod_64-1];
for(i=0;i<start_subframe;++i, --abs_start_subframe){
num_dlsf -= is_dlsf(mac_inst, abs_start_subframe-1);
}
for(i=end_subframe;i<9;++i, ++abs_end_subframe){
num_dlsf -= is_dlsf(mac_inst, abs_end_subframe+1);
}
if(start_frame_div_64!=end_frame_div_64){
num_dlsf+= (472+(end_frame_div_64-start_frame_div_64-1)*472);
}
}
return num_dlsf;
return num_dlsf;
}
int is_dlsf(eNB_MAC_INST_NB_IoT *mac_inst, int abs_subframe){
int frame = abs_subframe/10;
int subframe = abs_subframe%10;
int frame = abs_subframe/10;
int subframe = abs_subframe%10;
return !(subframe==0||subframe==5||((frame&0x1)==0&&subframe==9)||(mac_inst->sib1_flag[frame%mac_inst->sib1_period]==1&&subframe==4));
return !(subframe==0||subframe==5||((frame&0x1)==0&&subframe==9)||(mac_inst->sib1_flag[frame%mac_inst->sib1_period]==1&&subframe==4));
}
void init_dl_list(eNB_MAC_INST_NB_IoT *mac_inst){
available_resource_DL_t *node;
available_resource_DL_t *node;
node = (available_resource_DL_t *)malloc(sizeof(available_resource_DL_t));
node->next = (available_resource_DL_t *)0;
node->prev = (available_resource_DL_t *)0;
node = (available_resource_DL_t *)malloc(sizeof(available_resource_DL_t));
node->next = (available_resource_DL_t *)0;
node->prev = (available_resource_DL_t *)0;
available_resource_DL = node;
available_resource_DL_last = node;
available_resource_DL = node;
available_resource_DL_last = node;
node->start_subframe = 0;
node->end_subframe = mac_inst->rrc_config.si_window_length;
mac_inst->schedule_subframe_DL = mac_inst->rrc_config.si_window_length;
node->start_subframe = 0;
node->end_subframe = 0;
mac_inst->schedule_subframe_DL = 0;
// init sibs for first si-window
schedule_sibs(mac_inst, 0, 0);
//node->end_subframe = mac_inst->rrc_config.si_window_length;
//mac_inst->schedule_subframe_DL = mac_inst->rrc_config.si_window_length;
// init sibs for first si-window
//schedule_sibs(mac_inst, 0, 0); // TODO, check init
}
// extend subframe align to si-period
void extend_available_resource_DL(eNB_MAC_INST_NB_IoT *mac_inst, int max_subframe){ // assume max_subframe is found.
//printf_FUNCTION_IN("[EXTEND DL]");
// extend subframe align to si-period
void extend_available_resource_DL(eNB_MAC_INST_NB_IoT *mac_inst, int max_subframe){
available_resource_DL_t *new_node;
//int temp;
uint32_t i, i_div_si_window;
//uint32_t si_period_div_window;
//pt = available_resource_DL;
available_resource_DL_t *new_node;
uint32_t i, i_div_si_window;
LOG_D(MAC,"[extend DL] max_subframe: %d, current schedule subframe: %d\n", max_subframe, mac_inst->schedule_subframe_DL);
print_available_resource_DL(mac_inst);
if(max_subframe > mac_inst->schedule_subframe_DL){
// align to si-period
max_subframe = ((max_subframe%mac_inst->rrc_config.si_window_length)==0)? max_subframe : (((max_subframe/mac_inst->rrc_config.si_window_length)+1)*mac_inst->rrc_config.si_window_length);
if(mac_inst->schedule_subframe_DL == available_resource_DL_last->end_subframe){
LOG_D(MAC,"[extend DL] last node is align to schedule_sf_dl\n");
available_resource_DL_last->end_subframe = max_subframe;
}else{
LOG_D(MAC,"[extend DL] add new node !\n");
new_node = (available_resource_DL_t *)malloc(sizeof(available_resource_DL_t));
available_resource_DL_last->next = new_node;
new_node->start_subframe = mac_inst->schedule_subframe_DL+1;
new_node->end_subframe = max_subframe;
new_node->next = (available_resource_DL_t *)0;
available_resource_DL_last = new_node;
}
// do schedule sibs after extend.
for(i=mac_inst->schedule_subframe_DL;i<max_subframe;i+=mac_inst->rrc_config.si_window_length){
i_div_si_window = (i / mac_inst->rrc_config.si_window_length)%256;
if(-1 != mac_inst->sibs_table[i_div_si_window]){
LOG_D(MAC,"[sibs%d] %d\n", mac_inst->sibs_table[i_div_si_window], i);
schedule_sibs(mac_inst, mac_inst->sibs_table[i_div_si_window], i);
}
}
mac_inst->schedule_subframe_DL = max_subframe;
}
//printf_FUNCTION_OUT("[EXTEND DL]");
return ;
if(max_subframe > mac_inst->schedule_subframe_DL){
// align to si-period
max_subframe = ((max_subframe%mac_inst->rrc_config.si_window_length)==0)? max_subframe : (((max_subframe/mac_inst->rrc_config.si_window_length)+1)*mac_inst->rrc_config.si_window_length);
if(mac_inst->schedule_subframe_DL == available_resource_DL_last->end_subframe){
LOG_D(MAC,"[extend DL] last node is align to schedule_sf_dl\n");
available_resource_DL_last->end_subframe = max_subframe;
}else{
LOG_D(MAC,"[extend DL] add new node !\n");
new_node = (available_resource_DL_t *)malloc(sizeof(available_resource_DL_t));
available_resource_DL_last->next = new_node;
new_node->start_subframe = mac_inst->schedule_subframe_DL+1;
new_node->end_subframe = max_subframe;
new_node->next = (available_resource_DL_t *)0;
available_resource_DL_last = new_node;
}
// do schedule sibs after extend.
for(i=mac_inst->schedule_subframe_DL; i<max_subframe; i+=mac_inst->rrc_config.si_window_length){
i_div_si_window = (i / mac_inst->rrc_config.si_window_length)%256;
if(-1 != mac_inst->sibs_table[i_div_si_window]){
LOG_D(MAC,"[sibs%d] %d\n", mac_inst->sibs_table[i_div_si_window], i + (mac_inst->rrc_config.si_radio_frame_offset*10));
schedule_sibs(mac_inst, mac_inst->sibs_table[i_div_si_window], i + (mac_inst->rrc_config.si_radio_frame_offset*10)); // add si-radio-frame-offset carried in SIB1
}
}
mac_inst->schedule_subframe_DL = max_subframe;
}
}
void maintain_available_resource(eNB_MAC_INST_NB_IoT *mac_inst){
//printf_FUNCTION_IN("[MAINTAIN]");
available_resource_DL_t *pfree, *iterator;
available_resource_UL_t *pfree2, *iterator2;
schedule_result_t *iterator1;
available_resource_DL_t *pfree, *iterator;
available_resource_UL_t *pfree2, *iterator2;
schedule_result_t *iterator1;
if(available_resource_DL != (available_resource_DL_t *)0){
if(mac_inst->current_subframe >= available_resource_DL->end_subframe){
if(mac_inst->current_subframe >= available_resource_DL->end_subframe){
pfree = available_resource_DL;
if(available_resource_DL->next == (available_resource_DL_t *)0){
......@@ -1018,14 +995,14 @@ void maintain_available_resource(eNB_MAC_INST_NB_IoT *mac_inst){
available_resource_DL->prev = (available_resource_DL_t *)0;
}
free((available_resource_DL_t *)pfree);
}else{
available_resource_DL->start_subframe = mac_inst->current_subframe;
}
// UL
iterator2 = available_resource_UL->singletone1_Head;
if(iterator2 != (available_resource_UL_t *)0){
}else{
available_resource_DL->start_subframe = mac_inst->current_subframe;
}
// UL
iterator2 = available_resource_UL->singletone1_Head;
if(iterator2 != (available_resource_UL_t *)0){
if(mac_inst->current_subframe >= iterator2->end_subframe){
pfree2 = iterator2;
......@@ -1033,13 +1010,13 @@ void maintain_available_resource(eNB_MAC_INST_NB_IoT *mac_inst){
available_resource_UL->singletone1_Head->prev = (available_resource_UL_t *)0;
free((available_resource_UL_t *)pfree2);
}else{
iterator2->start_subframe = mac_inst->current_subframe;
}
}else{
iterator2->start_subframe = mac_inst->current_subframe;
}
}
iterator2 = available_resource_UL->singletone2_Head;
if(iterator2 != (available_resource_UL_t *)0){
iterator2 = available_resource_UL->singletone2_Head;
if(iterator2 != (available_resource_UL_t *)0){
if(mac_inst->current_subframe >= iterator2->end_subframe){
pfree2 = iterator2;
......@@ -1047,13 +1024,13 @@ void maintain_available_resource(eNB_MAC_INST_NB_IoT *mac_inst){
available_resource_UL->singletone2_Head->prev = (available_resource_UL_t *)0;
free((available_resource_UL_t *)pfree2);
}else{
iterator2->start_subframe = mac_inst->current_subframe;
}
}else{
iterator2->start_subframe = mac_inst->current_subframe;
}
}
iterator2 = available_resource_UL->singletone3_Head;
if(iterator2 != (available_resource_UL_t *)0){
iterator2 = available_resource_UL->singletone3_Head;
if(iterator2 != (available_resource_UL_t *)0){
if(mac_inst->current_subframe >= iterator2->end_subframe){
pfree2 = iterator2;
......@@ -1061,13 +1038,13 @@ void maintain_available_resource(eNB_MAC_INST_NB_IoT *mac_inst){
available_resource_UL->singletone3_Head->prev = (available_resource_UL_t *)0;
free((available_resource_UL_t *)pfree2);
}else{
iterator2->start_subframe = mac_inst->current_subframe;
}
}else{
iterator2->start_subframe = mac_inst->current_subframe;
}
}
iterator2 = available_resource_UL->sixtone_Head;
if(iterator2 != (available_resource_UL_t *)0){
iterator2 = available_resource_UL->sixtone_Head;
if(iterator2 != (available_resource_UL_t *)0){
if(mac_inst->current_subframe >= iterator2->end_subframe){
pfree2 = iterator2;
......@@ -1075,13 +1052,13 @@ void maintain_available_resource(eNB_MAC_INST_NB_IoT *mac_inst){
available_resource_UL->sixtone_Head->prev = (available_resource_UL_t *)0;
free((available_resource_UL_t *)pfree2);
}else{
iterator2->start_subframe = mac_inst->current_subframe;
}
}else{
iterator2->start_subframe = mac_inst->current_subframe;
}
}
iterator2 = available_resource_UL->threetone_Head;
if(iterator2 != (available_resource_UL_t *)0){
iterator2 = available_resource_UL->threetone_Head;
if(iterator2 != (available_resource_UL_t *)0){
if(mac_inst->current_subframe >= iterator2->end_subframe){
pfree2 = iterator2;
......@@ -1089,443 +1066,443 @@ void maintain_available_resource(eNB_MAC_INST_NB_IoT *mac_inst){
available_resource_UL->threetone_Head->prev = (available_resource_UL_t *)0;
free((available_resource_UL_t *)pfree2);
}else{
iterator2->start_subframe = mac_inst->current_subframe;
}
}else{
iterator2->start_subframe = mac_inst->current_subframe;
}
}
if(mac_inst->current_subframe == 0){
// DL available cross zero
iterator = available_resource_DL;
while(iterator != (available_resource_DL_t *)0){
if(iterator->start_subframe >= MAX_SUBFRAME)
iterator->start_subframe -= MAX_SUBFRAME;
if(iterator->end_subframe >= MAX_SUBFRAME)
iterator->end_subframe -= MAX_SUBFRAME;
iterator = iterator->next;
}
if(mac_inst->schedule_subframe_DL >= MAX_SUBFRAME)
mac_inst->schedule_subframe_DL -= MAX_SUBFRAME;
// UL available cross zero
iterator2 = available_resource_UL->sixtone_Head;
while(iterator2 != (available_resource_UL_t *)0){
if(iterator2->start_subframe >= MAX_SUBFRAME)
iterator2->start_subframe -= MAX_SUBFRAME;
if(iterator2->end_subframe >= MAX_SUBFRAME)
iterator2->end_subframe -= MAX_SUBFRAME;
iterator2 = iterator2->next;
}
iterator2 = available_resource_UL->threetone_Head;
while(iterator2 != (available_resource_UL_t *)0){
if(iterator2->start_subframe >= MAX_SUBFRAME)
iterator2->start_subframe -= MAX_SUBFRAME;
if(iterator2->end_subframe >= MAX_SUBFRAME)
iterator2->end_subframe -= MAX_SUBFRAME;
iterator2 = iterator2->next;
}
iterator2 = available_resource_UL->singletone3_Head;
while(iterator2 != (available_resource_UL_t *)0){
if(iterator2->start_subframe >= MAX_SUBFRAME)
iterator2->start_subframe -= MAX_SUBFRAME;
if(iterator2->end_subframe >= MAX_SUBFRAME)
iterator2->end_subframe -= MAX_SUBFRAME;
iterator2 = iterator2->next;
}
iterator2 = available_resource_UL->singletone1_Head;
while(iterator2 != (available_resource_UL_t *)0){
if(iterator2->start_subframe >= MAX_SUBFRAME)
iterator2->start_subframe -= MAX_SUBFRAME;
if(iterator2->end_subframe >= MAX_SUBFRAME)
iterator2->end_subframe -= MAX_SUBFRAME;
iterator2 = iterator2->next;
}
iterator2 = available_resource_UL->singletone2_Head;
while(iterator2 != (available_resource_UL_t *)0){
if(iterator2->start_subframe >= MAX_SUBFRAME)
iterator2->start_subframe -= MAX_SUBFRAME;
if(iterator2->end_subframe >= MAX_SUBFRAME)
iterator2->end_subframe -= MAX_SUBFRAME;
iterator2 = iterator2->next;
}
if(available_resource_UL->singletone1_end_subframe >= MAX_SUBFRAME)
available_resource_UL->singletone1_end_subframe -= MAX_SUBFRAME;
if(available_resource_UL->singletone2_end_subframe >= MAX_SUBFRAME)
available_resource_UL->singletone2_end_subframe -= MAX_SUBFRAME;
if(available_resource_UL->singletone3_end_subframe >= MAX_SUBFRAME)
available_resource_UL->singletone3_end_subframe -= MAX_SUBFRAME;
if(available_resource_UL->sixtone_end_subframe >= MAX_SUBFRAME)
available_resource_UL->sixtone_end_subframe -= MAX_SUBFRAME;
if(available_resource_UL->threetone_end_subframe >= MAX_SUBFRAME)
available_resource_UL->threetone_end_subframe -= MAX_SUBFRAME;
// DL result cross zero
iterator1 = schedule_result_list_DL;
while(iterator1 != (schedule_result_t *)0){
if(iterator1->output_subframe >= MAX_SUBFRAME)
iterator1->output_subframe -= MAX_SUBFRAME;
if(iterator1->end_subframe >= MAX_SUBFRAME)
iterator1->end_subframe -= MAX_SUBFRAME;
iterator1 = iterator1->next;
}
// UL result cross zero
iterator1 = schedule_result_list_UL;
while(iterator1 != (schedule_result_t *)0){
if(iterator1->output_subframe >= MAX_SUBFRAME)
iterator1->output_subframe -= MAX_SUBFRAME;
if(iterator1->end_subframe >= MAX_SUBFRAME)
iterator1->end_subframe -= MAX_SUBFRAME;
iterator1 = iterator1->next;
}
}
if(mac_inst->current_subframe == 0){
// DL available cross zero
iterator = available_resource_DL;
while(iterator != (available_resource_DL_t *)0){
if(iterator->start_subframe >= MAX_SUBFRAME)
iterator->start_subframe -= MAX_SUBFRAME;
if(iterator->end_subframe >= MAX_SUBFRAME)
iterator->end_subframe -= MAX_SUBFRAME;
iterator = iterator->next;
}
if(mac_inst->schedule_subframe_DL >= MAX_SUBFRAME)
mac_inst->schedule_subframe_DL -= MAX_SUBFRAME;
// UL available cross zero
iterator2 = available_resource_UL->sixtone_Head;
while(iterator2 != (available_resource_UL_t *)0){
if(iterator2->start_subframe >= MAX_SUBFRAME)
iterator2->start_subframe -= MAX_SUBFRAME;
if(iterator2->end_subframe >= MAX_SUBFRAME)
iterator2->end_subframe -= MAX_SUBFRAME;
iterator2 = iterator2->next;
}
iterator2 = available_resource_UL->threetone_Head;
while(iterator2 != (available_resource_UL_t *)0){
if(iterator2->start_subframe >= MAX_SUBFRAME)
iterator2->start_subframe -= MAX_SUBFRAME;
if(iterator2->end_subframe >= MAX_SUBFRAME)
iterator2->end_subframe -= MAX_SUBFRAME;
iterator2 = iterator2->next;
}
iterator2 = available_resource_UL->singletone3_Head;
while(iterator2 != (available_resource_UL_t *)0){
if(iterator2->start_subframe >= MAX_SUBFRAME)
iterator2->start_subframe -= MAX_SUBFRAME;
if(iterator2->end_subframe >= MAX_SUBFRAME)
iterator2->end_subframe -= MAX_SUBFRAME;
iterator2 = iterator2->next;
}
iterator2 = available_resource_UL->singletone1_Head;
while(iterator2 != (available_resource_UL_t *)0){
if(iterator2->start_subframe >= MAX_SUBFRAME)
iterator2->start_subframe -= MAX_SUBFRAME;
if(iterator2->end_subframe >= MAX_SUBFRAME)
iterator2->end_subframe -= MAX_SUBFRAME;
iterator2 = iterator2->next;
}
iterator2 = available_resource_UL->singletone2_Head;
while(iterator2 != (available_resource_UL_t *)0){
if(iterator2->start_subframe >= MAX_SUBFRAME)
iterator2->start_subframe -= MAX_SUBFRAME;
if(iterator2->end_subframe >= MAX_SUBFRAME)
iterator2->end_subframe -= MAX_SUBFRAME;
iterator2 = iterator2->next;
}
if(available_resource_UL->singletone1_end_subframe >= MAX_SUBFRAME)
available_resource_UL->singletone1_end_subframe -= MAX_SUBFRAME;
if(available_resource_UL->singletone2_end_subframe >= MAX_SUBFRAME)
available_resource_UL->singletone2_end_subframe -= MAX_SUBFRAME;
if(available_resource_UL->singletone3_end_subframe >= MAX_SUBFRAME)
available_resource_UL->singletone3_end_subframe -= MAX_SUBFRAME;
if(available_resource_UL->sixtone_end_subframe >= MAX_SUBFRAME)
available_resource_UL->sixtone_end_subframe -= MAX_SUBFRAME;
if(available_resource_UL->threetone_end_subframe >= MAX_SUBFRAME)
available_resource_UL->threetone_end_subframe -= MAX_SUBFRAME;
// DL result cross zero
iterator1 = schedule_result_list_DL;
while(iterator1 != (schedule_result_t *)0){
if(iterator1->output_subframe >= MAX_SUBFRAME)
iterator1->output_subframe -= MAX_SUBFRAME;
if(iterator1->end_subframe >= MAX_SUBFRAME)
iterator1->end_subframe -= MAX_SUBFRAME;
iterator1 = iterator1->next;
}
// UL result cross zero
iterator1 = schedule_result_list_UL;
while(iterator1 != (schedule_result_t *)0){
if(iterator1->output_subframe >= MAX_SUBFRAME)
iterator1->output_subframe -= MAX_SUBFRAME;
if(iterator1->end_subframe >= MAX_SUBFRAME)
iterator1->end_subframe -= MAX_SUBFRAME;
iterator1 = iterator1->next;
}
}
}
//printf_FUNCTION_OUT("[MAINTAIN]");
return ;
//printf_FUNCTION_OUT("[MAINTAIN]");
return ;
}
void fill_resource_DL(eNB_MAC_INST_NB_IoT *mac_inst, available_resource_DL_t *node, int start_subframe, int end_subframe, schedule_result_t *new_node){
//printf_FUNCTION_IN("[FILL DL]");
available_resource_DL_t *temp;
schedule_result_t *iterator, *temp1;
// divided into two node
// keep one node(align left or right)
// delete node
//LOG_D(MAC,"fill dl test1\n");
int align_left = (node->start_subframe==start_subframe)||(calculate_DLSF(mac_inst, node->start_subframe, start_subframe-1) == 0);
int align_right = (end_subframe==node->end_subframe)||(calculate_DLSF(mac_inst, end_subframe+1, node->end_subframe) == 0);
available_resource_DL_t *temp;
schedule_result_t *iterator, *temp1;
// divided into two node
// keep one node(align left or right)
// delete node
//LOG_D(MAC,"fill dl test1\n");
int align_left = (node->start_subframe==start_subframe)||(calculate_DLSF(mac_inst, node->start_subframe, start_subframe-1) == 0);
int align_right = (end_subframe==node->end_subframe)||(calculate_DLSF(mac_inst, end_subframe+1, node->end_subframe) == 0);
//LOG_D(MAC,"fill dl test2\n");
switch(align_left+align_right){
case 0:
// divided into two node, always insert before original node, so won't happen that temp is the last node of the list.
// A | node | B
// A | temp | node | B
temp = (available_resource_DL_t *)malloc(sizeof(available_resource_DL_t));
if(node->prev){
node->prev->next = temp;
}else{
available_resource_DL = temp;
}
temp->prev = node->prev;
temp->next = node;
node->prev = temp;
temp->start_subframe = node->start_subframe;
temp->end_subframe = start_subframe - 1;
node->start_subframe = end_subframe + 1;
break;
case 1:
// keep one node
if(align_left){
node->start_subframe = end_subframe + 1 ;
}else{
node->end_subframe = start_subframe - 1 ;
}
break;
case 2:
// delete
if(node->next){
node->next->prev = node->prev;
switch(align_left+align_right){
case 0:
// divided into two node, always insert before original node, so won't happen that temp is the last node of the list.
// A | node | B
// A | temp | node | B
temp = (available_resource_DL_t *)malloc(sizeof(available_resource_DL_t));
if(node->prev){
node->prev->next = temp;
}else{
available_resource_DL = temp;
}
temp->prev = node->prev;
temp->next = node;
node->prev = temp;
temp->start_subframe = node->start_subframe;
temp->end_subframe = start_subframe - 1;
node->start_subframe = end_subframe + 1;
break;
case 1:
// keep one node
if(align_left){
node->start_subframe = end_subframe + 1 ;
}else{
node->end_subframe = start_subframe - 1 ;
}
break;
case 2:
// delete
if(node->next){
node->next->prev = node->prev;
}else{
available_resource_DL_last = node->prev;
}
if(node->prev){
node->prev->next = node->next;
}else{
available_resource_DL = node->next;
}
free(node);
break;
default:
//error
break;
}
// new node allocate from up-layer calling function.
iterator = schedule_result_list_DL;
if(node->prev){
node->prev->next = node->next;
}else{
available_resource_DL = node->next;
}
free(node);
break;
default:
//error
break;
}
// new node allocate from up-layer calling function.
iterator = schedule_result_list_DL;
temp1 = (schedule_result_t *)0;
if((schedule_result_t *)0 == schedule_result_list_DL){
schedule_result_list_DL = new_node;
}else{
while((schedule_result_t *)0 != iterator){
if(start_subframe < iterator->output_subframe){
break;
}
temp1 = iterator;
iterator = iterator->next;
}
if((schedule_result_t *)0 == iterator){
temp1->next = new_node;
}else{
new_node->next = iterator;
if(temp1){
temp1->next = new_node;
}else{
schedule_result_list_DL = new_node;
}
}
}
//printf_FUNCTION_OUT("[FILL DL]");
if((schedule_result_t *)0 == schedule_result_list_DL){
schedule_result_list_DL = new_node;
}else{
while((schedule_result_t *)0 != iterator){
if(start_subframe < iterator->output_subframe){
break;
}
temp1 = iterator;
iterator = iterator->next;
}
if((schedule_result_t *)0 == iterator){
temp1->next = new_node;
}else{
new_node->next = iterator;
if(temp1){
temp1->next = new_node;
}else{
schedule_result_list_DL = new_node;
}
}
}
//printf_FUNCTION_OUT("[FILL DL]");
}
// check_subframe must be DLSF, you can use is_dlsf() to check before call function
// check_subframe must be DLSF, you can use is_dlsf() to check before call function
available_resource_DL_t *check_resource_DL(eNB_MAC_INST_NB_IoT *mac_inst, int check_subframe, int num_subframes, int *out_last_subframe, int *out_first_subframe){
available_resource_DL_t *pt;
pt = available_resource_DL;
int end_subframe = check_subframe + num_subframes - 1;
int diff_gap;
while((available_resource_DL_t *)0 != pt){
if(pt->start_subframe <= check_subframe && pt->end_subframe >= check_subframe){
break;
}
pt = pt->next;
}
if((available_resource_DL_t *)0 == pt){
return (available_resource_DL_t *)0;
}else{
if(num_subframes <= calculate_DLSF(mac_inst, check_subframe, pt->end_subframe)){
diff_gap = num_subframes - calculate_DLSF(mac_inst, check_subframe, end_subframe);
while(diff_gap){
++end_subframe;
if(is_dlsf(mac_inst, end_subframe)){
--diff_gap;
}
}
*out_last_subframe = end_subframe;
while(!is_dlsf(mac_inst, check_subframe)){
++check_subframe;
}
*out_first_subframe = check_subframe;
return pt;
}else{
return (available_resource_DL_t *)0;
}
}
available_resource_DL_t *pt;
pt = available_resource_DL;
int end_subframe = check_subframe + num_subframes - 1;
int diff_gap;
while((available_resource_DL_t *)0 != pt){
if(pt->start_subframe <= check_subframe && pt->end_subframe >= check_subframe){
break;
}
pt = pt->next;
}
if((available_resource_DL_t *)0 == pt){
return (available_resource_DL_t *)0;
}else{
if(num_subframes <= calculate_DLSF(mac_inst, check_subframe, pt->end_subframe)){
diff_gap = num_subframes - calculate_DLSF(mac_inst, check_subframe, end_subframe);
while(diff_gap){
++end_subframe;
if(is_dlsf(mac_inst, end_subframe)){
--diff_gap;
}
}
*out_last_subframe = end_subframe;
while(!is_dlsf(mac_inst, check_subframe)){
++check_subframe;
}
*out_first_subframe = check_subframe;
return pt;
}else{
return (available_resource_DL_t *)0;
}
}
}
available_resource_DL_t *check_sibs_resource(eNB_MAC_INST_NB_IoT *mac_inst, int check_start_subframe, int check_end_subframe, int num_subframe, int *residual_subframe, int *out_last_subframe, int *out_first_subframe){
available_resource_DL_t *pt;
uint32_t num_dlsf;
uint8_t output = 0x0;
pt = available_resource_DL;
// TODO find the pt which can cover part of check_start_subframe, e.g. 1280-> 1281-1440
while((available_resource_DL_t *)0 != pt){
if(pt->start_subframe <= check_start_subframe && pt->end_subframe >= check_start_subframe){
break;
}
pt = pt->next;
}
if((available_resource_DL_t *)0 == pt){
return (available_resource_DL_t *)0;
}
num_dlsf = calculate_DLSF(mac_inst, check_start_subframe, pt->end_subframe);
if((available_resource_DL_t *)0 == pt){
return (available_resource_DL_t *)0;
}else{
if(num_subframe <= num_dlsf){
while(num_subframe>0){
if(is_dlsf(mac_inst, check_start_subframe)){
--num_subframe;
if(output == 0x0){
*out_first_subframe = check_start_subframe;
output = 0x1;
}
}
if(num_subframe==0||check_start_subframe>=check_end_subframe){
break;
}else{
++check_start_subframe;
}
}
*residual_subframe = num_subframe;
*out_last_subframe = check_start_subframe;
}else{
if(num_dlsf == 0){
return (available_resource_DL_t *)0;
}else{
while(!is_dlsf(mac_inst, check_start_subframe)){
++check_start_subframe;
}
*out_first_subframe = check_start_subframe;
}
*residual_subframe = num_subframe - num_dlsf;
*out_last_subframe = pt->end_subframe;
}
return pt;
}
available_resource_DL_t *pt;
uint32_t num_dlsf;
uint8_t output = 0x0;
pt = available_resource_DL;
// TODO find the pt which can cover part of check_start_subframe, e.g. 1280-> 1281-1440
while((available_resource_DL_t *)0 != pt){
if(pt->start_subframe <= check_start_subframe && pt->end_subframe >= check_start_subframe){
break;
}
pt = pt->next;
}
if((available_resource_DL_t *)0 == pt){
return (available_resource_DL_t *)0;
}
num_dlsf = calculate_DLSF(mac_inst, check_start_subframe, pt->end_subframe);
if((available_resource_DL_t *)0 == pt){
return (available_resource_DL_t *)0;
}else{
if(num_subframe <= num_dlsf){
while(num_subframe>0){
if(is_dlsf(mac_inst, check_start_subframe)){
--num_subframe;
if(output == 0x0){
*out_first_subframe = check_start_subframe;
output = 0x1;
}
}
if(num_subframe==0||check_start_subframe>=check_end_subframe){
break;
}else{
++check_start_subframe;
}
}
*residual_subframe = num_subframe;
*out_last_subframe = check_start_subframe;
}else{
if(num_dlsf == 0){
return (available_resource_DL_t *)0;
}else{
while(!is_dlsf(mac_inst, check_start_subframe)){
++check_start_subframe;
}
*out_first_subframe = check_start_subframe;
}
*residual_subframe = num_subframe - num_dlsf;
*out_last_subframe = pt->end_subframe;
}
return pt;
}
}
void print_available_resource_DL(eNB_MAC_INST_NB_IoT *mac_inst){
available_resource_DL_t *pt;
pt = available_resource_DL;
int i=0;
LOG_D(MAC,"=== print available resource === t=%d\nsched subframe: %d, list end: %d-%d\n", mac_inst->current_subframe, mac_inst->schedule_subframe_DL, available_resource_DL_last->start_subframe, available_resource_DL_last->end_subframe);
while(pt){
LOG_D(MAC,"[%2d] %p %3d-%3d\n", i, pt, pt->start_subframe, pt->end_subframe);
pt = pt->next;
}
LOG_D(MAC,"\n");
available_resource_DL_t *pt;
pt = available_resource_DL;
int i=0;
LOG_D(MAC,"=== print available resource === t=%d\nsched subframe: %d, list end: %d-%d\n", mac_inst->current_subframe, mac_inst->schedule_subframe_DL, available_resource_DL_last->start_subframe, available_resource_DL_last->end_subframe);
while(pt){
LOG_D(MAC,"[%2d] %p %3d-%3d\n", i, pt, pt->start_subframe, pt->end_subframe);
pt = pt->next;
}
LOG_D(MAC,"\n");
}
void print_schedule_result(void){
schedule_result_t *iterator_dl = schedule_result_list_DL;
schedule_result_t *iterator_ul = schedule_result_list_UL;
schedule_result_t *iterator;
int i = 0;
char str[20];
char str1[20];
char str2[20];
LOG_D(MAC,"=== print schedule result ===\n");
while((schedule_result_t *)0 != iterator_dl || (schedule_result_t *)0 != iterator_ul){
if((schedule_result_t *)0 == iterator_dl){
iterator = iterator_ul;
iterator_ul = iterator_ul->next;
}
else if((schedule_result_t *)0 == iterator_ul){
iterator = iterator_dl;
iterator_dl = iterator_dl->next;
}else{
if(iterator_ul->output_subframe < iterator_dl->output_subframe){
iterator = iterator_ul;
iterator_ul = iterator_ul->next;
}else{
iterator = iterator_dl;
iterator_dl = iterator_dl->next;
}
}
if(iterator->rnti == P_RNTI){
sprintf(str, " PAGING");
}
else if(iterator->rnti == SI_RNTI){
sprintf(str, "SI-RNTI");
}
else if(iterator->rnti <= RA_RNTI_HIGH && iterator->rnti >= RA_RNTI_LOW){
sprintf(str, "RA-RNTI");
}else{
sprintf(str, "UE%05d", iterator->rnti-C_RNTI_LOW);
}
if(iterator->direction == DL){
sprintf(str1, "DL");
}else{
sprintf(str1, "UL");
}
switch(iterator->channel){
case NPDCCH:
sprintf(str2, "NPDCCH");
break;
case NPDSCH:
sprintf(str2, "NPDSCH");
break;
case NPUSCH:
sprintf(str2, "NPUSCH");
break;
default:
break;
}
LOG_D(MAC,"[%2d][%s][%s][%s] output(%4d)\n", i++, str, str1, str2, iterator->output_subframe);
/* if((uint8_t *)0 != iterator->printf_str){
LOG_D(MAC," printf: %s\n", iterator->printf_str);
}else{
LOG_D(MAC,"\n");
}*/
}
schedule_result_t *iterator_dl = schedule_result_list_DL;
schedule_result_t *iterator_ul = schedule_result_list_UL;
schedule_result_t *iterator;
int i = 0;
char str[20];
char str1[20];
char str2[20];
LOG_D(MAC,"=== print schedule result ===\n");
while((schedule_result_t *)0 != iterator_dl || (schedule_result_t *)0 != iterator_ul){
if((schedule_result_t *)0 == iterator_dl){
iterator = iterator_ul;
iterator_ul = iterator_ul->next;
}
else if((schedule_result_t *)0 == iterator_ul){
iterator = iterator_dl;
iterator_dl = iterator_dl->next;
}else{
if(iterator_ul->output_subframe < iterator_dl->output_subframe){
iterator = iterator_ul;
iterator_ul = iterator_ul->next;
}else{
iterator = iterator_dl;
iterator_dl = iterator_dl->next;
}
}
if(iterator->rnti == P_RNTI){
sprintf(str, " PAGING");
}
else if(iterator->rnti == SI_RNTI){
sprintf(str, "SI-RNTI");
}
else if(iterator->rnti <= RA_RNTI_HIGH && iterator->rnti >= RA_RNTI_LOW){
sprintf(str, "RA-RNTI");
}else{
sprintf(str, "UE%05d", iterator->rnti-C_RNTI_LOW);
}
if(iterator->direction == DL){
sprintf(str1, "DL");
}else{
sprintf(str1, "UL");
}
switch(iterator->channel){
case NPDCCH:
sprintf(str2, "NPDCCH");
break;
case NPDSCH:
sprintf(str2, "NPDSCH");
break;
case NPUSCH:
sprintf(str2, "NPUSCH");
break;
default:
break;
}
LOG_D(MAC,"[%2d][%s][%s][%s] output(%4d)\n", i++, str, str1, str2, iterator->output_subframe);
/* if((uint8_t *)0 != iterator->printf_str){
LOG_D(MAC," printf: %s\n", iterator->printf_str);
}else{
LOG_D(MAC,"\n");
}*/
}
}
void print_schedule_result_DL(void){
schedule_result_t *iterator = schedule_result_list_DL;
int i=0;
char str[20];
LOG_D(MAC,"=== print schedule result DL ===\n");
while((schedule_result_t *)0 != iterator){
if(iterator->rnti == P_RNTI){
sprintf(str, " PAGE");
}
else if(iterator->rnti == SI_RNTI){
sprintf(str, " SI");
}
else if(iterator->rnti <= RA_RNTI_HIGH && iterator->rnti >= RA_RNTI_LOW){
sprintf(str, " RA");
}else{
sprintf(str, "UE%03d", iterator->rnti-C_RNTI_LOW);
}
LOG_D(MAC,"[%2d][%s][""DL""] output(%4d)\n", i++, str, iterator->output_subframe);
/*if((uint8_t *)0 != iterator->printf_str){
LOG_D(MAC," printf: %s\n", iterator->printf_str);
}else{
LOG_D(MAC,"\n");
}*/
iterator = iterator->next;
}
schedule_result_t *iterator = schedule_result_list_DL;
int i=0;
char str[20];
LOG_D(MAC,"=== print schedule result DL ===\n");
while((schedule_result_t *)0 != iterator){
if(iterator->rnti == P_RNTI){
sprintf(str, " PAGE");
}
else if(iterator->rnti == SI_RNTI){
sprintf(str, " SI");
}
else if(iterator->rnti <= RA_RNTI_HIGH && iterator->rnti >= RA_RNTI_LOW){
sprintf(str, " RA");
}else{
sprintf(str, "UE%03d", iterator->rnti-C_RNTI_LOW);
}
LOG_D(MAC,"[%2d][%s][""DL""] output(%4d)\n", i++, str, iterator->output_subframe);
/*if((uint8_t *)0 != iterator->printf_str){
LOG_D(MAC," printf: %s\n", iterator->printf_str);
}else{
LOG_D(MAC,"\n");
}*/
iterator = iterator->next;
}
}
void print_schedule_result_UL(void){
schedule_result_t *iterator = schedule_result_list_UL;
int i=0;
char str[20];
LOG_D(MAC,"=== print schedule result UL ===\n");
while((schedule_result_t *)0 != iterator){
sprintf(str, "UE%03d", iterator->rnti-C_RNTI_LOW);
LOG_D(MAC,"[%2d][%s][""UL""] output(%4d)\n", i++, str, iterator->output_subframe);
/*if((uint8_t *)0 != iterator->printf_str){
LOG_D(MAC," printf: %s\tnext %p\n", iterator->printf_str, iterator->next);
}else{
LOG_D(MAC,"\n");
}*/
iterator = iterator->next;
}
schedule_result_t *iterator = schedule_result_list_UL;
int i=0;
char str[20];
LOG_D(MAC,"=== print schedule result UL ===\n");
while((schedule_result_t *)0 != iterator){
sprintf(str, "UE%03d", iterator->rnti-C_RNTI_LOW);
LOG_D(MAC,"[%2d][%s][""UL""] output(%4d)\n", i++, str, iterator->output_subframe);
/*if((uint8_t *)0 != iterator->printf_str){
LOG_D(MAC," printf: %s\tnext %p\n", iterator->printf_str, iterator->next);
}else{
LOG_D(MAC,"\n");
}*/
iterator = iterator->next;
}
}
uint32_t get_scheduling_delay(uint32_t I_delay, uint32_t R_max)
{
if(I_delay==0)
{
return 0;
}
else
{
if(R_max<128)
{
if(I_delay<=4)
return 4*I_delay;
else
return (uint32_t)(2<<I_delay);
}
else
{
return (uint32_t)(16<<(I_delay-1));
}
}
if(I_delay==0)
{
return 0;
}
else
{
if(R_max<128)
{
if(I_delay<=4)
return 4*I_delay;
else
return (uint32_t)(2<<I_delay);
}
else
{
return (uint32_t)(16<<(I_delay-1));
}
}
}
#if 0
......@@ -1541,73 +1518,73 @@ uint8_t not_done=1, num_ces=0, num_sdus=0, lcid,num_sdu_cnt;
uint8_t *mac_header_ptr = mac_header;
uint16_t length, ce_len=0;
while(not_done==1){
if(((SCH_SUBHEADER_FIXED*)mac_header_ptr)->E == 0){
not_done = 0;
}
lcid = ((SCH_SUBHEADER_FIXED *)mac_header_ptr)->LCID;
if(lcid < EXTENDED_POWER_HEADROOM){
if (not_done==0) { // last MAC SDU, length is implicit
mac_header_ptr++;
length = tb_length-(mac_header_ptr-mac_header)-ce_len;
for(num_sdu_cnt=0; num_sdu_cnt < num_sdus ; num_sdu_cnt++){
length -= rx_lengths[num_sdu_cnt];
}
}else{
if(((SCH_SUBHEADER_SHORT *)mac_header_ptr)->F == 0){
length = ((SCH_SUBHEADER_SHORT *)mac_header_ptr)->L;
mac_header_ptr += 2;//sizeof(SCH_SUBHEADER_SHORT);
}else{ // F = 1
length = ((((SCH_SUBHEADER_LONG *)mac_header_ptr)->L_MSB & 0x7f ) << 8 ) | (((SCH_SUBHEADER_LONG *)mac_header_ptr)->L_LSB & 0xff);
mac_header_ptr += 3;//sizeof(SCH_SUBHEADER_LONG);
}
}
rx_lcids[num_sdus] = lcid;
rx_lengths[num_sdus] = length;
num_sdus++;
}else{ // This is a control element subheader POWER_HEADROOM, BSR and CRNTI
if(lcid == SHORT_PADDING){
mac_header_ptr++;
}else{
rx_ces[num_ces] = lcid;
num_ces++;
mac_header_ptr++;
if(lcid==LONG_BSR){
ce_len+=3;
}else if(lcid==CRNTI){
ce_len+=2;
}else if((lcid==POWER_HEADROOM) || (lcid==TRUNCATED_BSR)|| (lcid== SHORT_BSR)) {
ce_len++;
}else{
// wrong lcid
}
}
}
}
*num_ce = num_ces;
*num_sdu = num_sdus;
return(mac_header_ptr);
while(not_done==1){
if(((SCH_SUBHEADER_FIXED*)mac_header_ptr)->E == 0){
not_done = 0;
}
lcid = ((SCH_SUBHEADER_FIXED *)mac_header_ptr)->LCID;
if(lcid < EXTENDED_POWER_HEADROOM){
if (not_done==0) { // last MAC SDU, length is implicit
mac_header_ptr++;
length = tb_length-(mac_header_ptr-mac_header)-ce_len;
for(num_sdu_cnt=0; num_sdu_cnt < num_sdus ; num_sdu_cnt++){
length -= rx_lengths[num_sdu_cnt];
}
}else{
if(((SCH_SUBHEADER_SHORT *)mac_header_ptr)->F == 0){
length = ((SCH_SUBHEADER_SHORT *)mac_header_ptr)->L;
mac_header_ptr += 2;//sizeof(SCH_SUBHEADER_SHORT);
}else{ // F = 1
length = ((((SCH_SUBHEADER_LONG *)mac_header_ptr)->L_MSB & 0x7f ) << 8 ) | (((SCH_SUBHEADER_LONG *)mac_header_ptr)->L_LSB & 0xff);
mac_header_ptr += 3;//sizeof(SCH_SUBHEADER_LONG);
}
}
rx_lcids[num_sdus] = lcid;
rx_lengths[num_sdus] = length;
num_sdus++;
}else{ // This is a control element subheader POWER_HEADROOM, BSR and CRNTI
if(lcid == SHORT_PADDING){
mac_header_ptr++;
}else{
rx_ces[num_ces] = lcid;
num_ces++;
mac_header_ptr++;
if(lcid==LONG_BSR){
ce_len+=3;
}else if(lcid==CRNTI){
ce_len+=2;
}else if((lcid==POWER_HEADROOM) || (lcid==TRUNCATED_BSR)|| (lcid== SHORT_BSR)) {
ce_len++;
}else{
// wrong lcid
}
}
}
}
*num_ce = num_ces;
*num_sdu = num_sdus;
return(mac_header_ptr);
}
#endif
// calvin
// maybe we can try to use hash table to enhance searching time.
// calvin
// maybe we can try to use hash table to enhance searching time.
UE_TEMPLATE_NB_IoT *get_ue_from_rnti(eNB_MAC_INST_NB_IoT *inst, rnti_t rnti){
uint32_t i;
for(i=0; i<MAX_NUMBER_OF_UE_MAX_NB_IoT; ++i){
if(inst->UE_list_spec->UE_template_NB_IoT[i].active == 1){
if(inst->UE_list_spec->UE_template_NB_IoT[i].rnti == rnti){
return &inst->UE_list_spec->UE_template_NB_IoT[i];
}
}
}
return (UE_TEMPLATE_NB_IoT *)0;
uint32_t i;
for(i=0; i<MAX_NUMBER_OF_UE_MAX_NB_IoT; ++i){
if(inst->UE_list_spec->UE_template_NB_IoT[i].active == 1){
if(inst->UE_list_spec->UE_template_NB_IoT[i].rnti == rnti){
return &inst->UE_list_spec->UE_template_NB_IoT[i];
}
}
}
return (UE_TEMPLATE_NB_IoT *)0;
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment