Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
O
OpenXG-RAN
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
ZhouShuya
OpenXG-RAN
Commits
7a1d8e30
Commit
7a1d8e30
authored
Aug 11, 2018
by
AlanLi
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Fixed bugs for SIB23
parent
0daeb68d
Changes
7
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
838 additions
and
1080 deletions
+838
-1080
openair1/SCHED/phy_procedures_lte_eNb_NB_IoT.c
openair1/SCHED/phy_procedures_lte_eNb_NB_IoT.c
+19
-2
openair2/LAYER2/MAC/config_NB_IoT.h
openair2/LAYER2/MAC/config_NB_IoT.h
+1
-1
openair2/LAYER2/MAC/eNB_scheduler_NB_IoT.c
openair2/LAYER2/MAC/eNB_scheduler_NB_IoT.c
+18
-54
openair2/LAYER2/MAC/eNB_scheduler_RA_NB_IoT.c
openair2/LAYER2/MAC/eNB_scheduler_RA_NB_IoT.c
+5
-156
openair2/LAYER2/MAC/main.c
openair2/LAYER2/MAC/main.c
+2
-2
openair2/LAYER2/MAC/main_NB_IoT.c
openair2/LAYER2/MAC/main_NB_IoT.c
+8
-57
openair2/LAYER2/MAC/schedule_tool_NB_IoT.c
openair2/LAYER2/MAC/schedule_tool_NB_IoT.c
+785
-808
No files found.
openair1/SCHED/phy_procedures_lte_eNb_NB_IoT.c
View file @
7a1d8e30
...
...
@@ -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
,
...
...
openair2/LAYER2/MAC/config_NB_IoT.h
View file @
7a1d8e30
...
...
@@ -298,4 +298,4 @@ typedef struct rrc_config_NB_IoT_s{
}
rrc_config_NB_IoT_t
;
#endif
\ No newline at end of file
#endif
openair2/LAYER2/MAC/eNB_scheduler_NB_IoT.c
View file @
7a1d8e30
/*
* 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]");
}
openair2/LAYER2/MAC/eNB_scheduler_RA_NB_IoT.c
View file @
7a1d8e30
/*
* 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
);
}
openair2/LAYER2/MAC/main.c
View file @
7a1d8e30
...
...
@@ -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
;
...
...
openair2/LAYER2/MAC/main_NB_IoT.c
View file @
7a1d8e30
/*
* 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
);
}
...
...
openair2/LAYER2/MAC/schedule_tool_NB_IoT.c
View file @
7a1d8e30
/*
* 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
\n
sched 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
\n
sched 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
;
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment