Commit 5d1c0aaa authored by Robert Schmidt's avatar Robert Schmidt

Merge branch 'integration_2024_w46' into 'develop'

Integration: `2024.w46`

See merge request oai/openairinterface5g!3106

* !3095 UE: Set default SSB config
* !2991 fix BSR report malformed, add SHORT BSR when it can (instead of LONG BSR)...
* !3104 Trigger deregistration only in SA mode → small fixup?
* !3107 Clip the input for -32768 because this will make different result in...
* !3109 T tracer: support float types in traces
* !2777 NR UE trigger for re-establishment
* !3108 Prevent segfaults in gNB stack
* !3059 Test for init_RA
* CI: increase UE thread pool size
* !3036 Further improvements in analog beam management for CSI-RS
* !3093 Added NTN FDD FR1 bands defined in 3GPP TS 38.101-5
parents f54ca571 0c3a2c15
......@@ -1374,7 +1374,6 @@ set (MAC_NR_SRC_UE
${NR_UE_MAC_DIR}/nr_ue_scheduler.c
${NR_UE_MAC_DIR}/nr_ue_scheduler_sl.c
${NR_UE_MAC_DIR}/nr_ue_dci_configuration.c
${NR_UE_MAC_DIR}/nr_ra_procedures.c
)
set (ENB_APP_SRC
......@@ -1423,7 +1422,7 @@ endif()
add_library(MAC_UE_NR ${MAC_NR_SRC_UE})
target_link_libraries(MAC_UE_NR PRIVATE asn1_lte_rrc_hdrs asn1_nr_rrc_hdrs PUBLIC nr_ue_power_procedures)
target_link_libraries(MAC_UE_NR PRIVATE asn1_lte_rrc_hdrs asn1_nr_rrc_hdrs PUBLIC nr_ue_power_procedures nr_ue_ra_procedures)
add_library(L2_LTE ${L2_LTE_SRC})
target_link_libraries(L2_LTE PRIVATE asn1_lte_rrc_hdrs asn1_nr_rrc_hdrs)
......@@ -1478,7 +1477,7 @@ target_link_libraries(L2_UE PRIVATE asn1_lte_rrc_hdrs)
add_library( NR_L2_UE ${NR_L2_SRC_UE} ${MAC_NR_SRC_UE} )
target_link_libraries(NR_L2_UE PRIVATE f1ap nr_rlc)
target_link_libraries(NR_L2_UE PRIVATE asn1_nr_rrc_hdrs asn1_lte_rrc_hdrs nr_common nr_ue_power_procedures)
target_link_libraries(NR_L2_UE PRIVATE asn1_nr_rrc_hdrs asn1_lte_rrc_hdrs nr_common nr_ue_power_procedures nr_ue_ra_procedures)
add_library(MAC_NR_COMMON
${OPENAIR2_DIR}/LAYER2/NR_MAC_COMMON/nr_mac_common.c
......
......@@ -6,6 +6,8 @@ uicc0 = {
nssai_sst=1;
}
thread-pool = "-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1"
#/* configuration for channel modelisation */
#/* To be included in main config file when */
#/* channel modelisation is used (rfsimulator with chanmod options enabled) */
......
......@@ -5,6 +5,8 @@ uicc0:
dnn: oai
nssai_sst: 1
thread-pool: "-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1"
#/* configuration for channel modelisation */
#/* To be included in main config file when */
#/* channel modelisation is used (rfsimulator with chanmod options enabled) */
......
......@@ -6,3 +6,5 @@ uicc0 = {
nssai_sst=1;
nssai_sd=66051;
}
thread-pool = "-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1"
......@@ -34,6 +34,11 @@
030020
030021
030022
040001
020022
040002
030021
030022
100021
222222
</TestCaseRequestedList>
......@@ -117,11 +122,36 @@
<iperf_bitrate_threshold>90</iperf_bitrate_threshold>
</testCase>
<testCase id="040001">
<class>Custom_Command</class>
<desc>Trigger Reestablishment</desc>
<node>cacofonix</node>
<command>echo ci force_reestab | nc 192.168.71.171 9090 | grep -E 'Reset RLC counters of UE RNTI [0-9a-f]{4} to trigger reestablishment'</command>
<command_fail>yes</command_fail>
</testCase>
<testCase id="020022">
<class>Ping</class>
<desc>Ping ext-dn from all NR-UEs</desc>
<id>rfsim5g_ue</id>
<nodes>cacofonix</nodes>
<ping_args> -c 20 192.168.72.135 -i0.5 -w25</ping_args>
<ping_packetloss_threshold>80</ping_packetloss_threshold>
</testCase>
<testCase id="040002">
<class>Custom_Command</class>
<desc>Verify Reestablishment</desc>
<node>cacofonix</node>
<command>echo ci get_reestab_count | nc 192.168.71.150 9090 | grep -E 'UE RNTI [0-9a-f]{4} reestab 1'</command>
<command_fail>yes</command_fail>
</testCase>
<testCase id="040021">
<class>Custom_Command</class>
<desc>Simulate a disruption of DL radio channel (ploss 55)(5 sec)</desc>
<node>cacofonix</node>
<command>echo channelmod modify 0 ploss 55 | nc -N 192.168.71.181 8091 &amp;&amp; sleep 5</command>
<command>echo channelmod modify 0 ploss 55 | nc 192.168.71.181 8091 &amp;&amp; sleep 5</command>
<command_fail>yes</command_fail>
</testCase>
......@@ -129,7 +159,7 @@
<class>Custom_Command</class>
<desc>Get UE sync state (UE ID 0)</desc>
<node>cacofonix</node>
<command>echo ciUE sync_state 0 | nc -N 192.168.71.181 8091 | grep -E UE_NOT_SYNC</command>
<command>echo ciUE sync_state 0 | nc 192.168.71.181 8091 | grep -E UE_NOT_SYNC</command>
<command_fail>yes</command_fail>
</testCase>
......@@ -137,7 +167,7 @@
<class>Custom_Command</class>
<desc>Restoration of the original DL channel conditions (ploss 0)(5 sec)</desc>
<node>cacofonix</node>
<command>echo channelmod modify 0 ploss 0 | nc -N 192.168.71.181 8091 &amp;&amp; sleep 5</command>
<command>echo channelmod modify 0 ploss 0 | nc 192.168.71.181 8091 &amp;&amp; sleep 5</command>
<command_fail>yes</command_fail>
</testCase>
......@@ -145,7 +175,7 @@
<class>Custom_Command</class>
<desc>Get UE sync state (UE ID 0)</desc>
<node>cacofonix</node>
<command>echo ciUE sync_state 0 | nc -N 192.168.71.181 8091 | grep -E UE_CONNECTED &amp;&amp; sleep 10</command>
<command>echo ciUE sync_state 0 | nc 192.168.71.181 8091 | grep -E UE_CONNECTED &amp;&amp; sleep 10</command>
<command_fail>yes</command_fail>
</testCase>
......
......@@ -192,7 +192,7 @@
<desc>iperf (DL/TCP)(30 sec)(multi-ue profile)</desc>
<iperf_args>-t 30 -R</iperf_args>
<id>amarisoft_ue_1 amarisoft_ue_2 amarisoft_ue_3 amarisoft_ue_4 amarisoft_ue_5 amarisoft_ue_6 amarisoft_ue_7 amarisoft_ue_8 amarisoft_ue_9 amarisoft_ue_10 amarisoft_ue_11 amarisoft_ue_12 amarisoft_ue_13 amarisoft_ue_14 amarisoft_ue_15</id>
<iperf_tcp_rate_target>4</iperf_tcp_rate_target>
<iperf_tcp_rate_target>3.9</iperf_tcp_rate_target>
<svr_id>oc-cn5g</svr_id>
</testCase>
......
......@@ -87,9 +87,12 @@ services:
container_name: rfsim5g-oai-cu
cap_drop:
- ALL
environment:
environment:
USE_ADDITIONAL_OPTIONS: --log_config.global_log_options level,nocolor,time
ASAN_OPTIONS: detect_leaks=0
--rfsimulator.options chanmod
--telnetsrv --telnetsrv.listenaddr 192.168.71.150
--telnetsrv.shrmod ci
ASAN_OPTIONS: detect_leaks=0:detect_odr_violation=0
depends_on:
- oai-ext-dn
networks:
......@@ -113,6 +116,7 @@ services:
--log_config.global_log_options level,nocolor,time
--rfsimulator.options chanmod
--telnetsrv --telnetsrv.listenaddr 192.168.71.171
--telnetsrv.shrmod ci
ASAN_OPTIONS: detect_leaks=0:detect_odr_violation=0
depends_on:
- oai-cu
......
......@@ -94,6 +94,10 @@ event new_event(int type, int length, char *buffer, void *database)
e.e[i].type = EVENT_ULONG;
e.e[i].ul = *(unsigned long *)(&buffer[offset]);
offset += sizeof(unsigned long);
} else if (!strcmp(f.type[i], "float")) {
e.e[i].type = EVENT_FLOAT;
e.e[i].f = *(float *)(&buffer[offset]);
offset += sizeof(float);
} else if (!strcmp(f.type[i], "string")) {
e.e[i].type = EVENT_STRING;
e.e[i].s = &buffer[offset];
......
......@@ -13,6 +13,7 @@
enum event_arg_type {
EVENT_INT,
EVENT_ULONG,
EVENT_FLOAT,
EVENT_STRING,
EVENT_BUFFER
};
......@@ -23,6 +24,7 @@ typedef struct {
union {
int i;
unsigned long ul;
float f;
char *s;
struct {
int bsize;
......
......@@ -11,7 +11,7 @@
enum format_item_type {
INSTRING,
INT, ULONG, STRING, BUFFER };
INT, ULONG, FLOAT, STRING, BUFFER };
struct format_item {
enum format_item_type type;
......@@ -67,6 +67,7 @@ static void _event(void *p, event e)
case INSTRING: PUTS(&l->o, l->f[i].s); break;
case INT: PUTI(&l->o, e.e[l->f[i].event_arg].i); break;
case ULONG: PUTUL(&l->o, e.e[l->f[i].event_arg].ul); break;
case FLOAT: PUTF(&l->o, e.e[l->f[i].event_arg].f); break;
case STRING: PUTS_CLEAN(&l->o, e.e[l->f[i].event_arg].s); break;
case BUFFER:
PUTS(&l->o, "{buffer size:");
......@@ -106,6 +107,7 @@ static int find_argument(char *name, database_event_format f,
*event_arg = i;
if (!strcmp(f.type[i], "int")) *it = INT;
else if (!strcmp(f.type[i], "ulong")) *it = ULONG;
else if (!strcmp(f.type[i], "float")) *it = FLOAT;
else if (!strcmp(f.type[i], "string")) *it = STRING;
else if (!strcmp(f.type[i], "buffer")) *it = BUFFER;
else return 0;
......
......@@ -276,3 +276,9 @@ void PUTUL(OBUF *o, unsigned long l) {
sprintf(s, "%lu", l);
PUTS(o, s);
}
void PUTF(OBUF *o, float f) {
char s[256];
sprintf(s, "%g", f);
PUTS(o, s);
}
......@@ -50,5 +50,6 @@ void PUTS_CLEAN(OBUF *o, char *s);
void PUTI(OBUF *o, int i);
void PUTX2(OBUF *o, int i);
void PUTUL(OBUF *o, unsigned long i);
void PUTF(OBUF *o, float f);
#endif /* _UTILS_H_ */
This diff is collapsed.
......@@ -67,6 +67,12 @@ static telnetsrv_params_t telnetparams;
#define TELNETSRV_OPTNAME_STATICMOD "staticmod"
#define TELNETSRV_OPTNAME_SHRMOD "shrmod"
#define TELNET_LOG(fmt, ...) \
do { \
printf("[TELNETSRV] " fmt __VA_OPT__(, ) __VA_ARGS__); \
fflush(stdout); \
} while (0)
// clang-format off
paramdef_t telnetoptions[] = {
/*-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
......@@ -653,10 +659,10 @@ void run_telnetsrv(void) {
using_history();
int plen=sprintf(prompt,"%s_%s> ",TELNET_PROMPT_PREFIX,get_softmodem_function(NULL));
printf("\nInitializing telnet server...\n");
TELNET_LOG("\nInitializing telnet server...\n");
while( (telnetparams.new_socket = accept(sock, &cli_addr, &cli_len)) ) {
printf("[TELNETSRV] Telnet client connected....\n");
TELNET_LOG("Telnet client connected....\n");
read_history(telnetparams.histfile);
stifle_history(telnetparams.histsize);
......@@ -682,12 +688,12 @@ void run_telnetsrv(void) {
}
if(!readc) {
printf ("[TELNETSRV] Telnet Client disconnected.\n");
TELNET_LOG("Telnet Client disconnected.\n");
break;
}
if (telnetparams.telnetdbg > 0)
printf("[TELNETSRV] Command received: readc %i filled %i \"%s\"\n", readc, filled,buf);
TELNET_LOG("Command received: readc %i filled %i \"%s\"\n", readc, filled, buf);
if (buf[0] == '!') {
if (buf[1] == '!') {
......@@ -720,7 +726,7 @@ void run_telnetsrv(void) {
send(telnetparams.new_socket, prompt, strlen(prompt), MSG_NOSIGNAL);
} else {
printf ("[TELNETSRV] Closing telnet connection...\n");
TELNET_LOG("Closing telnet connection...\n");
break;
}
}
......@@ -728,7 +734,7 @@ void run_telnetsrv(void) {
write_history(telnetparams.histfile);
clear_history();
close(telnetparams.new_socket);
printf ("[TELNETSRV] Telnet server waitting for connection...\n");
TELNET_LOG("Telnet server waiting for connection...\n");
}
close(sock);
......@@ -927,7 +933,7 @@ int add_telnetcmd(char *modulename, telnetshell_vardef_t *var, telnetshell_cmdde
cmd[j].qptr = afifo;
}
}
printf("[TELNETSRV] Telnet server: module %i = %s added to shell\n", i, telnetparams.CmdParsers[i].module);
TELNET_LOG("Telnet server: module %i = %s added to shell\n", i, telnetparams.CmdParsers[i].module);
break;
}
}
......
......@@ -37,6 +37,7 @@
#include "openair2/LAYER2/nr_rlc/nr_rlc_oai_api.h"
#include "openair2/LAYER2/nr_rlc/nr_rlc_ue_manager.h"
#include "openair2/LAYER2/nr_rlc/nr_rlc_entity_am.h"
#include "openair2/LAYER2/NR_MAC_gNB/mac_proto.h"
#define TELNETSERVERCODE
#include "telnetsrv.h"
......@@ -115,10 +116,8 @@ int get_reestab_count(char *buf, int debug, telnet_printfunc_t prnt)
return 0;
}
int trigger_reestab(char *buf, int debug, telnet_printfunc_t prnt)
int fetch_rnti(char *buf, telnet_printfunc_t prnt)
{
if (!RC.nrmac)
ERROR_MSG_RET("no MAC/RLC present, cannot trigger reestablishment\n");
int rnti = -1;
if (!buf) {
rnti = get_single_ue_rnti_mac();
......@@ -129,9 +128,15 @@ int trigger_reestab(char *buf, int debug, telnet_printfunc_t prnt)
if (rnti < 1 || rnti >= 0xfffe)
ERROR_MSG_RET("RNTI needs to be [1,0xfffe]\n");
}
return rnti;
}
int trigger_reestab(char *buf, int debug, telnet_printfunc_t prnt)
{
if (!RC.nrmac)
ERROR_MSG_RET("no MAC/RLC present, cannot trigger reestablishment\n");
int rnti = fetch_rnti(buf, prnt);
nr_rlc_test_trigger_reestablishment(rnti);
prnt("Reset RLC counters of UE RNTI %04x to trigger reestablishment\n", rnti);
return 0;
}
......@@ -163,7 +168,27 @@ int rrc_gNB_trigger_f1_ho(char *buf, int debug, telnet_printfunc_t prnt)
gNB_RRC_UE_t *UE = &ue->ue_context;
nr_HO_F1_trigger_telnet(RC.nrrrc[0], UE->rrc_ue_id);
prnt("RRC F1 handover triggered for UE %u\n", UE->rrc_ue_id);
return 0;
}
int force_ul_failure(char *buf, int debug, telnet_printfunc_t prnt)
{
if (!RC.nrmac)
ERROR_MSG_RET("no MAC/RLC present, force_ul_failure failed\n");
int rnti = fetch_rnti(buf, prnt);
NR_UE_info_t *UE = find_nr_UE(&RC.nrmac[0]->UE_info, rnti);
nr_mac_trigger_ul_failure(&UE->UE_sched_ctrl, UE->current_UL_BWP.scs);
return 0;
}
int force_ue_release(char *buf, int debug, telnet_printfunc_t prnt)
{
force_ul_failure(buf, debug, prnt);
int rnti = fetch_rnti(buf, prnt);
NR_UE_info_t *UE = find_nr_UE(&RC.nrmac[0]->UE_info, rnti);
NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl;
sched_ctrl->ul_failure_timer = 2;
nr_mac_check_ul_failure(RC.nrmac[0], UE->rnti, sched_ctrl);
return 0;
}
......@@ -171,6 +196,8 @@ static telnetshell_cmddef_t cicmds[] = {
{"get_single_rnti", "", get_single_rnti},
{"force_reestab", "[rnti(hex,opt)]", trigger_reestab},
{"get_reestab_count", "[rnti(hex,opt)]", get_reestab_count},
{"force_ue_release", "[rnti(hex,opt)]", force_ue_release},
{"force_ul_failure", "[rnti(hex,opt)]", force_ul_failure},
{"trigger_f1_ho", "[rrc_ue_id(int,opt)]", rrc_gNB_trigger_f1_ho},
{"", "", NULL},
};
......
......@@ -36,6 +36,7 @@
#include <stdarg.h>
#include "openair2/LAYER2/NR_MAC_UE/mac_defs.h"
#include "openair2/LAYER2/NR_MAC_UE/mac_proto.h"
#include "openair2/RRC/NR_UE/rrc_proto.h"
#define TELNETSERVERCODE
#include "telnetsrv.h"
......@@ -73,9 +74,31 @@ int get_sync_state(char *buf, int debug, telnet_printfunc_t prnt)
return 0;
}
/**
* Force RLF on UE
*/
int force_rlf(char *buf, int debug, telnet_printfunc_t prnt)
{
NR_UE_RRC_INST_t *rrc = get_NR_UE_rrc_inst(0);
handle_rlf_detection(rrc);
return 0;
}
/**
* Send UE to RRC_IDLE
*/
int force_RRC_IDLE(char *buf, int debug, telnet_printfunc_t prnt)
{
NR_UE_RRC_INST_t *rrc = get_NR_UE_rrc_inst(0);
nr_rrc_going_to_IDLE(rrc, OTHER, NULL);
return 0;
}
/* Telnet shell command definitions */
static telnetshell_cmddef_t cicmds[] = {
{"sync_state", "[UE_ID(int,opt)]", get_sync_state},
{"force_rlf", "", force_rlf},
{"force_RRC_IDLE", "", force_RRC_IDLE},
{"", "", NULL},
};
......
......@@ -607,7 +607,13 @@ static int UE_dl_preprocessing(PHY_VARS_NR_UE *UE, const UE_nr_rxtx_proc_t *proc
if (UE->synch_request.received_synch_request == 1) {
fapi_nr_synch_request_t *synch_req = &UE->synch_request.synch_req;
UE->is_synchronized = 0;
UE->UE_scan_carrier = synch_req->ssb_bw_scan;
// if upper layers signal BW scan we do as instructed by command line parameter
// if upper layers disable BW scan we set it to false
if (UE->synch_request.synch_req.ssb_bw_scan)
UE->UE_scan_carrier = get_nrUE_params()->UE_scan_carrier;
else
UE->UE_scan_carrier = false;
UE->target_Nid_cell = UE->synch_request.synch_req.target_Nid_cell;
UE->target_Nid_cell = synch_req->target_Nid_cell;
uint64_t dl_bw = (12 * fp->N_RB_DL) * (15000 << fp->numerology_index);
......
......@@ -334,7 +334,7 @@ static void trigger_stop(int sig)
}
static void trigger_deregistration(int sig)
{
if (!stop_immediately) {
if (!stop_immediately && IS_SA_MODE(get_softmodem_params())) {
MessageDef *msg = itti_alloc_new_message(TASK_NAS_NRUE, 0, NAS_DEREGISTRATION_REQ);
NAS_DEREGISTRATION_REQ(msg).cause = AS_DETACH;
itti_send_msg_to_task(TASK_NAS_NRUE, 0, msg);
......
......@@ -979,6 +979,7 @@ typedef struct
uint16_t scramb_id; // ScramblingID of the CSI-RS [3GPP TS 38.214, sec 5.2.2.3.1], Value: 0->1023
uint8_t power_control_offset; // Ratio of PDSCH EPRE to NZP CSI-RSEPRE [3GPP TS 38.214, sec 5.2.2.3.1], Value: 0->23 representing -8 to 15 dB in 1dB steps; 255: L1 is configured with ProfileSSS
uint8_t power_control_offset_ss; // Ratio of NZP CSI-RS EPRE to SSB/PBCH block EPRE [3GPP TS 38.214, sec 5.2.2.3.1], Values: 0: -3dB; 1: 0dB; 2: 3dB; 3: 6dB; 255: L1 is configured with ProfileSSS
nfapi_nr_tx_precoding_and_beamforming_t precodingAndBeamforming;
} nfapi_nr_dl_tti_csi_rs_pdu_rel15_t;
......
......@@ -30,7 +30,7 @@ static const uint32_t nr_subcarrier_spacing[MAX_NUM_SUBCARRIER_SPACING] = {15e3,
static const uint16_t nr_slots_per_subframe[MAX_NUM_SUBCARRIER_SPACING] = {1, 2, 4, 8, 16};
// Table 5.4.3.3-1 38-101
static const int nr_ssb_table[54][3] = {
static const int nr_ssb_table[][3] = {
{1, 15, nr_ssb_type_A},
{2, 15, nr_ssb_type_A},
{3, 15, nr_ssb_type_A},
......@@ -84,7 +84,12 @@ static const int nr_ssb_table[54][3] = {
{92, 15, nr_ssb_type_A},
{93, 15, nr_ssb_type_A},
{94, 15, nr_ssb_type_A},
{96, 30, nr_ssb_type_C}};
{96, 30, nr_ssb_type_C},
{254, 15, nr_ssb_type_A},
{254, 30, nr_ssb_type_C},
{255, 15, nr_ssb_type_A},
{255, 30, nr_ssb_type_B},
{256, 15, nr_ssb_type_A}};
void set_Lmax(NR_DL_FRAME_PARMS *fp) {
// definition of Lmax according to ts 38.213 section 4.1
......
......@@ -80,12 +80,12 @@ static void nr_generate_dci(PHY_VARS_gNB *gNB,
uint32_t cset_nsymb = pdcch_pdu_rel15->DurationSymbols;
int dci_idx = 0;
// multi-beam number (for concurrent beams)
int bitmap = SL_to_bitmap(cset_start_symb, pdcch_pdu_rel15->DurationSymbols);
int beam_nb = beam_index_allocation(dci_pdu->precodingAndBeamforming.prgs_list[0].dig_bf_interface_list[0].beam_idx,
&gNB->common_vars,
slot,
frame_parms->symbols_per_slot,
cset_start_symb,
pdcch_pdu_rel15->DurationSymbols);
bitmap);
LOG_D(NR_PHY_DCI, "pdcch: Coreset rb_offset %d, nb_rb %d BWP Start %d\n", rb_offset, n_rb, pdcch_pdu_rel15->BWPStart);
LOG_D(NR_PHY_DCI,
......
......@@ -471,12 +471,12 @@ void nr_generate_pdsch(processingData_L1tx_t *msgTx, int frame, int slot)
start_meas(&gNB->dlsch_precoding_stats);
nfapi_nr_tx_precoding_and_beamforming_t *pb = &rel15->precodingAndBeamforming;
// beam number in multi-beam scenario (concurrent beams)
int bitmap = SL_to_bitmap(rel15->StartSymbolIndex, rel15->NrOfSymbols);
int beam_nb = beam_index_allocation(pb->prgs_list[0].dig_bf_interface_list[0].beam_idx,
&gNB->common_vars,
slot,
frame_parms->symbols_per_slot,
rel15->StartSymbolIndex,
rel15->NrOfSymbols);
bitmap);
c16_t **txdataF = gNB->common_vars.txdataF[beam_nb];
......
......@@ -85,12 +85,8 @@ void nr_fill_prach(PHY_VARS_gNB *gNB, int SFN, int Slot, nfapi_nr_prach_pdu_t *p
int fapi_beam_idx = prach_pdu->beamforming.prgs_list[0].dig_bf_interface_list[0].beam_idx;
// TODO no idea how to compute final prach symbol here so for now we go til the end of the slot
int temp_nb_symbols = NR_NUMBER_OF_SYMBOLS_PER_SLOT - prach_pdu->prach_start_symbol;
prach->beam_nb = beam_index_allocation(fapi_beam_idx,
&gNB->common_vars,
Slot,
NR_NUMBER_OF_SYMBOLS_PER_SLOT,
prach_pdu->prach_start_symbol,
temp_nb_symbols);
int bitmap = SL_to_bitmap(prach_pdu->prach_start_symbol, temp_nb_symbols);
prach->beam_nb = beam_index_allocation(fapi_beam_idx, &gNB->common_vars, Slot, NR_NUMBER_OF_SYMBOLS_PER_SLOT, bitmap);
}
LOG_D(NR_PHY,"Copying prach pdu %d bytes to index %d\n", (int)sizeof(*prach_pdu), prach_id);
memcpy(&prach->pdu, prach_pdu, sizeof(*prach_pdu));
......
......@@ -75,12 +75,8 @@ void nr_fill_ulsch(PHY_VARS_gNB *gNB, int frame, int slot, nfapi_nr_pusch_pdu_t
ulsch->beam_nb = 0;
if (gNB->common_vars.beam_id) {
int fapi_beam_idx = ulsch_pdu->beamforming.prgs_list[0].dig_bf_interface_list[0].beam_idx;
ulsch->beam_nb = beam_index_allocation(fapi_beam_idx,
&gNB->common_vars,
slot,
NR_NUMBER_OF_SYMBOLS_PER_SLOT,
ulsch_pdu->start_symbol_index,
ulsch_pdu->nr_of_symbols);
int bitmap = SL_to_bitmap(ulsch_pdu->start_symbol_index, ulsch_pdu->nr_of_symbols);
ulsch->beam_nb = beam_index_allocation(fapi_beam_idx, &gNB->common_vars, slot, NR_NUMBER_OF_SYMBOLS_PER_SLOT, bitmap);
}
ulsch->frame = frame;
ulsch->slot = slot;
......
......@@ -75,12 +75,8 @@ void nr_fill_pucch(PHY_VARS_gNB *gNB,
pucch->beam_nb = 0;
if (gNB->common_vars.beam_id) {
int fapi_beam_idx = pucch_pdu->beamforming.prgs_list[0].dig_bf_interface_list[0].beam_idx;
pucch->beam_nb = beam_index_allocation(fapi_beam_idx,
&gNB->common_vars,
slot,
NR_NUMBER_OF_SYMBOLS_PER_SLOT,
pucch_pdu->start_symbol_index,
pucch_pdu->nr_of_symbols);
int bitmap = SL_to_bitmap(pucch_pdu->start_symbol_index, pucch_pdu->nr_of_symbols);
pucch->beam_nb = beam_index_allocation(fapi_beam_idx, &gNB->common_vars, slot, NR_NUMBER_OF_SYMBOLS_PER_SLOT, bitmap);
}
memcpy((void *)&pucch->pucch_pdu, (void *)pucch_pdu, sizeof(nfapi_nr_pucch_pdu_t));
LOG_D(PHY,
......
......@@ -57,13 +57,9 @@ void nr_fill_srs(PHY_VARS_gNB *gNB, frame_t frame, slot_t slot, nfapi_nr_srs_pdu
srs->active = true;
srs->beam_nb = 0;
if (gNB->common_vars.beam_id) {
int bitmap = SL_to_bitmap(srs_pdu->time_start_position, 1 << srs_pdu->num_symbols);
int fapi_beam_idx = srs_pdu->beamforming.prgs_list[0].dig_bf_interface_list[0].beam_idx;
srs->beam_nb = beam_index_allocation(fapi_beam_idx,
&gNB->common_vars,
slot,
NR_NUMBER_OF_SYMBOLS_PER_SLOT,
srs_pdu->time_start_position,
1 << srs_pdu->num_symbols);
srs->beam_nb = beam_index_allocation(fapi_beam_idx, &gNB->common_vars, slot, NR_NUMBER_OF_SYMBOLS_PER_SLOT, bitmap);
}
memcpy((void *)&srs->srs_pdu, (void *)srs_pdu, sizeof(nfapi_nr_srs_pdu_t));
break;
......
......@@ -46,6 +46,30 @@ int main()
for (int vector_size = 1237; vector_size < 1237 + 8; vector_size++) {
auto input1 = generate_random_c16(vector_size);
auto input2 = generate_random_c16(vector_size);
// Clip the input for -32768 because this will make different result
// C version promote the int16 to int before doing the conjugate (so negate imaginary part)
// simd version do it on the int16, so the result overflows to -32768
// other overflows exist, but they make the same
// in C we do with int promotion, for real part:
// (int)x.r*(int)y.r - (int)x.i*(int)y.i
// that can overflow because each multiplication result is full int range
// so when we sum, it overflows
// _mm256_madd_epi16() overflows also, as do regular addition instruction
// so the result will be the same (the same wrong value)
for(auto it = input1.begin(); it != input1.end(); it++ ) {
if (it->r == -32768)
it->r=-32767;
if (it->i == -32768)
it->i=-32767;
}
for(auto it = input2.begin(); it != input2.end(); it++ ) {
if (it->r == -32768)
it->r=-32767;
if (it->i == -32768)
it->i=-32767;
}
AlignedVector512<c16_t> output;
output.resize(vector_size);
mult_complex_vectors(input1.data(), input2.data(), output.data(), vector_size, shift);
......
......@@ -487,16 +487,6 @@ typedef enum {
reserved = 7
} PUCCH_MaxCodeRate_t;
typedef struct {
pucch_format_nr_t format;
uint8_t startingSymbolIndex;
uint8_t nrofSymbols;
uint16_t PRB_offset;
uint8_t nb_CS_indexes;
uint8_t initial_CS_indexes[MAX_NB_CYCLIC_SHIFT];
} initial_pucch_resource_t;
/***********************************************************************
*
* FUNCTIONALITY : Scheduling Request Configuration (SR)
......
......@@ -43,19 +43,16 @@
//#define DEBUG_RXDATA
//#define SRS_IND_DEBUG
int beam_index_allocation(int fapi_beam_index,
NR_gNB_COMMON *common_vars,
int slot,
int symbols_per_slot,
int start_symbol,
int nb_symbols)
int beam_index_allocation(int fapi_beam_index, NR_gNB_COMMON *common_vars, int slot, int symbols_per_slot, int bitmap_symbols)
{
if (!common_vars->beam_id)
return 0;
int idx = -1;
for (int j = 0; j < common_vars->num_beams_period; j++) {
for (int i = start_symbol; i < start_symbol + nb_symbols; i++) {
for (int i = 0; i < symbols_per_slot; i++) {
if (((bitmap_symbols >> i) & 0x01) == 0)
continue;
int current_beam = common_vars->beam_id[j][slot * symbols_per_slot + i];
if (current_beam == -1 || current_beam == fapi_beam_index)
idx = j;
......@@ -68,8 +65,10 @@ int beam_index_allocation(int fapi_beam_index,
break;
}
AssertFatal(idx >= 0, "Couldn't allocate beam ID %d\n", fapi_beam_index);
for (int j = start_symbol; j < start_symbol + nb_symbols; j++)
common_vars->beam_id[idx][slot * symbols_per_slot + j] = fapi_beam_index;
for (int j = 0; j < symbols_per_slot; j++) {
if (((bitmap_symbols >> j) & 0x01))
common_vars->beam_id[idx][slot * symbols_per_slot + j] = fapi_beam_index;
}
LOG_D(PHY, "Allocating beam %d in slot %d\n", idx, slot);
return idx;
}
......@@ -129,12 +128,12 @@ void nr_common_signal_procedures(PHY_VARS_gNB *gNB, int frame, int slot, nfapi_n
c16_t ***txdataF = gNB->common_vars.txdataF;
int txdataF_offset = slot * fp->samples_per_slot_wCP;
// beam number in a scenario with multiple concurrent beams
int bitmap = SL_to_bitmap(ssb_start_symbol, 4); // 4 ssb symbols
int beam_nb = beam_index_allocation(pb->prgs_list[0].dig_bf_interface_list[0].beam_idx,
&gNB->common_vars,
slot,
fp->symbols_per_slot,
ssb_start_symbol,
4); // 4 ssb symbols
bitmap);
nr_generate_pss(&txdataF[beam_nb][0][txdataF_offset], gNB->TX_AMP, ssb_start_symbol, cfg, fp);
nr_generate_sss(&txdataF[beam_nb][0][txdataF_offset], gNB->TX_AMP, ssb_start_symbol, cfg, fp);
......@@ -253,7 +252,6 @@ void phy_procedures_gNB_TX(processingData_L1tx_t *msgTx,
for (int i = 0; i < NR_SYMBOLS_PER_SLOT; i++){
NR_gNB_CSIRS_t *csirs = &msgTx->csirs_pdu[i];
if (csirs->active == 1) {
AssertFatal(gNB->common_vars.beam_id == NULL, "Cannot handle CSI in the framework of beamforming yet\n");
LOG_D(PHY, "CSI-RS generation started in frame %d.%d\n",frame,slot);
nfapi_nr_dl_tti_csi_rs_pdu_rel15_t *csi_params = &csirs->csirs_pdu.csi_rs_pdu_rel15;
if (csi_params->csi_type == 2) { // ZP-CSI
......@@ -264,8 +262,19 @@ void phy_procedures_gNB_TX(processingData_L1tx_t *msgTx,
csi_params->freq_domain,
csi_params->symb_l0,
csi_params->symb_l1);
nfapi_nr_tx_precoding_and_beamforming_t *pb = &csi_params->precodingAndBeamforming;
int csi_bitmap = 0;
int lprime_num = mapping_parms.lprime + 1;
for (int j = 0; j < mapping_parms.size; j++)
csi_bitmap |= ((1 << lprime_num) - 1) << mapping_parms.loverline[j];
int beam_nb = beam_index_allocation(pb->prgs_list[0].dig_bf_interface_list[0].beam_idx,
&gNB->common_vars,
slot,
fp->symbols_per_slot,
csi_bitmap);
nr_generate_csi_rs(&gNB->frame_parms,
(int32_t **)gNB->common_vars.txdataF[0],
(int32_t **)gNB->common_vars.txdataF[beam_nb],
gNB->TX_AMP,
csi_params,
slot,
......
......@@ -47,10 +47,5 @@ void feptx_prec(RU_t *ru,int frame_tx,int tti_tx);
int nr_phy_init_RU(RU_t *ru);
void nr_phy_free_RU(RU_t *ru);
void clear_slot_beamid(PHY_VARS_gNB *gNB, int slot);
int beam_index_allocation(int fapi_beam_index,
NR_gNB_COMMON *common_vars,
int slot,
int symbols_per_slot,
int start_symbol,
int nb_symbols);
int beam_index_allocation(int fapi_beam_index, NR_gNB_COMMON *common_vars, int slot, int symbols_per_slot, int bitmap_symbols);
#endif
......@@ -409,13 +409,13 @@ static int nr_ue_pbch_procedures(PHY_VARS_NR_UE *ue,
if (ret==0) {
#ifdef DEBUG_PHY_PROC
uint16_t frame_tx;
LOG_D(PHY,"[UE %d] frame %d, nr_slot_rx %d, Received PBCH (MIB): frame_tx %d. N_RB_DL %d\n",
ue->Mod_id,
frame_rx,
nr_slot_rx,
frame_tx,
ue->frame_parms.N_RB_DL);
LOG_D(PHY,
"[UE %d] frame %d, nr_slot_rx %d, Received PBCH (MIB): ssb idx: %d, N_RB_DL %d\n",
ue->Mod_id,
frame_rx,
nr_slot_rx,
ssb_index,
ue->frame_parms.N_RB_DL);
#endif
} else {
......@@ -882,12 +882,21 @@ static bool nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue,
return dec;
}
static bool is_ssb_index_transmitted(const PHY_VARS_NR_UE *ue, const int index)
{
if (ue->received_config_request) {
const fapi_nr_config_request_t *cfg = &ue->nrUE_config;
const uint32_t curr_mask = cfg->ssb_table.ssb_mask_list[index / 32].ssb_mask;
return ((curr_mask >> (31 - (index % 32))) & 0x01);
} else
return ue->frame_parms.ssb_index == index;
}
int pbch_pdcch_processing(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, nr_phy_data_t *phy_data)
{
int frame_rx = proc->frame_rx;
int nr_slot_rx = proc->nr_slot_rx;
int gNB_id = proc->gNB_id;
fapi_nr_config_request_t *cfg = &ue->nrUE_config;
NR_DL_FRAME_PARMS *fp = &ue->frame_parms;
NR_UE_PDCCH_CONFIG *phy_pdcch_config = &phy_data->phy_pdcch_config;
int sampleShift = INT_MAX;
......@@ -901,16 +910,18 @@ int pbch_pdcch_processing(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, nr_
const uint32_t rxdataF_sz = ue->frame_parms.samples_per_slot_wCP;
__attribute__ ((aligned(32))) c16_t rxdataF[ue->frame_parms.nb_antennas_rx][rxdataF_sz];
// checking if current frame is compatible with SSB periodicity
if (cfg->ssb_table.ssb_period == 0 || !(frame_rx % (1 << (cfg->ssb_table.ssb_period - 1)))) {
const int default_ssb_period = 2;
const int ssb_period = ue->received_config_request ? ue->nrUE_config.ssb_table.ssb_period : default_ssb_period;
if (ssb_period == 0 || !(frame_rx % (1 << (ssb_period - 1)))) {
const int estimateSz = fp->symbols_per_slot * fp->ofdm_symbol_size;
// loop over SSB blocks
for(int ssb_index=0; ssb_index<fp->Lmax; ssb_index++) {
uint32_t curr_mask = cfg->ssb_table.ssb_mask_list[ssb_index/32].ssb_mask;
// check if if current SSB is transmitted
if ((curr_mask >> (31-(ssb_index%32))) &0x01) {
for (int ssb_index = 0; ssb_index < fp->Lmax; ssb_index++) {
// check if current SSB is transmitted
if (is_ssb_index_transmitted(ue, ssb_index)) {
int ssb_start_symbol = nr_get_ssb_start_symbol(fp, ssb_index);
int ssb_slot = ssb_start_symbol/fp->symbols_per_slot;
int ssb_slot_2 = (cfg->ssb_table.ssb_period == 0) ? ssb_slot+(fp->slots_per_frame>>1) : -1;
int ssb_slot_2 = (ssb_period == 0) ? ssb_slot + (fp->slots_per_frame >> 1) : -1;
if (ssb_slot == nr_slot_rx || ssb_slot_2 == nr_slot_rx) {
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SLOT_FEP_PBCH, VCD_FUNCTION_IN);
......
......@@ -85,3 +85,6 @@ MESSAGE_DEF(NRRRC_FRAME_PROCESS, MESSAGE_PRIORITY_MED, NRRrcFramePr
// eNB: RLC -> RRC messages
MESSAGE_DEF(RLC_SDU_INDICATION, MESSAGE_PRIORITY_MED, RlcSduIndication, rlc_sdu_indication)
MESSAGE_DEF(NAS_PDU_SESSION_REQ, MESSAGE_PRIORITY_MED, nas_pdu_session_req_t, nas_pdu_session_req)
// UE: RLC -> RRC messages
MESSAGE_DEF(NR_RRC_RLC_MAXRTX, MESSAGE_PRIORITY_MED, RlcMaxRtxIndication, nr_rlc_maxrtx_indication)
......@@ -97,6 +97,8 @@
#define NAS_OAI_TUN_NSA(mSGpTR) (mSGpTR)->ittiMsg.nas_oai_tun_nsa
#define NAS_PDU_SESSION_REQ(mSGpTR) (mSGpTR)->ittiMsg.nas_pdu_session_req
#define NR_RRC_RLC_MAXRTX(mSGpTR) (mSGpTR)->ittiMsg.nr_rlc_maxrtx_indication
//-------------------------------------------------------------------------------------------//
typedef struct RrcStateInd_s {
Rrc_State_t state;
......@@ -453,4 +455,8 @@ typedef struct rlc_sdu_indication_s {
int message_id;
} RlcSduIndication;
typedef struct {
int ue_id;
} RlcMaxRtxIndication;
#endif /* RRC_MESSAGES_TYPES_H_ */
......@@ -122,6 +122,11 @@ static inline int get_mac_len(uint8_t *pdu, uint32_t pdu_len, uint16_t *mac_ce_l
*mac_subheader_len = sizeof(*s);
*mac_ce_len = s->L;
}
if (*mac_ce_len > pdu_len) {
LOG_E(NR_MAC, "MAC sdu len impossible (%d)\n", *mac_ce_len);
return false;
}
return true;
}
......@@ -133,8 +138,6 @@ typedef struct {
uint8_t LcgID: 3; // octet 1 MSB
} __attribute__ ((__packed__)) NR_BSR_SHORT;
typedef NR_BSR_SHORT NR_BSR_SHORT_TRUNCATED;
// Long BSR for all logical channel group ID
typedef struct {
uint8_t LcgID0: 1; // octet 1 [0]
......@@ -144,19 +147,9 @@ typedef struct {
uint8_t LcgID4: 1; // octet 1 [4]
uint8_t LcgID5: 1; // octet 1 [5]
uint8_t LcgID6: 1; // octet 1 [6]
uint8_t LcgID7: 1; // octet 1 [7]
uint8_t Buffer_size0: 8; // octet 2 [7:0]
uint8_t Buffer_size1: 8; // octet 3 [7:0]
uint8_t Buffer_size2: 8; // octet 4 [7:0]
uint8_t Buffer_size3: 8; // octet 5 [7:0]
uint8_t Buffer_size4: 8; // octet 6 [7:0]
uint8_t Buffer_size5: 8; // octet 7 [7:0]
uint8_t Buffer_size6: 8; // octet 8 [7:0]
uint8_t Buffer_size7: 8; // octet 9 [7:0]
uint8_t LcgID7: 1; // octet 1 [7]
} __attribute__ ((__packed__)) NR_BSR_LONG;
typedef NR_BSR_LONG NR_BSR_LONG_TRUNCATED;
// 38.321 ch. 6.1.3.4
typedef struct {
uint8_t TA_COMMAND: 6; // octet 1 [5:0]
......
add_library(nr_ue_power_procedures nr_ue_power_procedures.c)
target_link_libraries(nr_ue_power_procedures PUBLIC asn1_nr_rrc ${T_LIB} MAC_NR_COMMON nr_common)
add_library(nr_ue_ra_procedures nr_ra_procedures.c)
target_link_libraries(nr_ue_ra_procedures PUBLIC asn1_nr_rrc asn1_lte_rrc_hdrs ${T_LIB} MAC_NR_COMMON nr_common)
if (ENABLE_TESTS)
add_subdirectory(tests)
endif()
......@@ -1611,8 +1611,7 @@ static void configure_timeAlignmentTimer(NR_timer_t *time_alignment_timer, NR_Ti
nr_timer_start(time_alignment_timer);
}
void nr_rrc_mac_config_req_reset(module_id_t module_id,
NR_UE_MAC_reset_cause_t cause)
void nr_rrc_mac_config_req_reset(module_id_t module_id, NR_UE_MAC_reset_cause_t cause)
{
NR_UE_MAC_INST_t *mac = get_mac_inst(module_id);
int ret = pthread_mutex_lock(&mac->if_mutex);
......@@ -1621,8 +1620,8 @@ void nr_rrc_mac_config_req_reset(module_id_t module_id,
switch (cause) {
case GO_TO_IDLE:
reset_ra(mac, true);
release_mac_configuration(mac, cause);
nr_ue_init_mac(mac);
release_mac_configuration(mac, cause);
nr_ue_mac_default_configs(mac);
// new sync but no target cell id -> -1
nr_ue_send_synch_request(mac, module_id, 0, &sync_req);
......
......@@ -70,8 +70,7 @@
#define NR_BSR_TRIGGER_NONE (0) /* No BSR Trigger */
#define NR_BSR_TRIGGER_REGULAR (1) /* For Regular and ReTxBSR Expiry Triggers */
#define NR_BSR_TRIGGER_PERIODIC (2) /* For BSR Periodic Timer Expiry Trigger */
#define NR_BSR_TRIGGER_PADDING (4) /* For Padding BSR Trigger */
#define NR_BSR_TRIGGER_PERIODIC (2) /* For BSR Periodic Timer Expiry Trigger */
#define NR_INVALID_LCGID (NR_MAX_NUM_LCGID)
......@@ -184,6 +183,15 @@ typedef enum {
#undef UE_STATE
} NR_UE_L2_STATE_t;
typedef struct {
pucch_format_nr_t format;
uint8_t startingSymbolIndex;
uint8_t nrofSymbols;
uint16_t PRB_offset;
uint8_t nb_CS_indexes;
uint8_t initial_CS_indexes[MAX_NB_CYCLIC_SHIFT];
} initial_pucch_resource_t;
typedef enum {
GO_TO_IDLE,
DETACH,
......@@ -194,8 +202,6 @@ typedef enum {
typedef struct {
// after multiplexing buffer remain for each lcid
int32_t LCID_buffer_remain;
// buffer status for each lcid
bool LCID_buffer_with_data;
// logical channel group id of this LCID
long LCGID;
// Bj bucket usage per lcid
......@@ -203,13 +209,6 @@ typedef struct {
NR_timer_t Bj_timer;
} NR_LC_SCHEDULING_INFO;
typedef struct {
// buffer status for each lcgid
uint8_t BSR; // should be more for mesh topology
// keep the number of bytes in rlc buffer for each lcgid
int32_t BSR_bytes;
} NR_LCG_SCHEDULING_INFO;
typedef struct {
bool active_SR_ID;
/// SR pending as defined in 38.321
......@@ -244,8 +243,6 @@ typedef struct {
typedef struct {
// lcs scheduling info
NR_LC_SCHEDULING_INFO lc_sched_info[NR_MAX_NUM_LCID];
// lcg scheduling info
NR_LCG_SCHEDULING_INFO lcg_sched_info[NR_MAX_NUM_LCGID];
// SR INFO
nr_sr_info_t sr_info[NR_MAX_SR_ID];
/// BSR report flag management
......
......@@ -172,13 +172,22 @@ void nr_ue_send_sdu(NR_UE_MAC_INST_t *mac, nr_downlink_indication_t *dl_info, in
void nr_ue_process_mac_pdu(NR_UE_MAC_INST_t *mac,nr_downlink_indication_t *dl_info, int pdu_id);
typedef struct {
union {
NR_BSR_SHORT s;
NR_BSR_LONG l;
uint8_t lcg_bsr[8];
} bsr;
enum { b_none, b_long, b_short, b_short_trunc, b_long_trunc } type_bsr;
} type_bsr_t;
int nr_write_ce_msg3_pdu(uint8_t *mac_ce, NR_UE_MAC_INST_t *mac, rnti_t crnti, uint8_t *mac_ce_end);
int nr_write_ce_ulsch_pdu(uint8_t *mac_ce,
NR_UE_MAC_INST_t *mac,
NR_SINGLE_ENTRY_PHR_MAC_CE *power_headroom,
uint16_t *crnti,
NR_BSR_SHORT *truncated_bsr,
NR_BSR_SHORT *short_bsr,
NR_BSR_LONG *long_bsr);
const type_bsr_t *bsr,
uint8_t *mac_ce_end);
void config_dci_pdu(NR_UE_MAC_INST_t *mac,
fapi_nr_dl_config_request_t *dl_config,
......@@ -188,16 +197,6 @@ void config_dci_pdu(NR_UE_MAC_INST_t *mac,
void ue_dci_configuration(NR_UE_MAC_INST_t *mac, fapi_nr_dl_config_request_t *dl_config, const frame_t frame, const int slot);
uint8_t nr_ue_get_sdu(NR_UE_MAC_INST_t *mac,
int cc_id,
frame_t frameP,
sub_frame_t subframe,
uint8_t gNB_index,
uint8_t *ulsch_buffer,
uint32_t buflen,
int16_t tx_power,
int16_t P_CMAX);
void set_harq_status(NR_UE_MAC_INST_t *mac,
uint8_t pucch_id,
uint8_t harq_id,
......@@ -210,7 +209,7 @@ void set_harq_status(NR_UE_MAC_INST_t *mac,
int slot);
bool get_downlink_ack(NR_UE_MAC_INST_t *mac, frame_t frame, int slot, PUCCH_sched_t *pucch);
initial_pucch_resource_t get_initial_pucch_resource(const int idx);
void multiplex_pucch_resource(NR_UE_MAC_INST_t *mac, PUCCH_sched_t *pucch, int num_res);
int16_t get_pucch_tx_power_ue(NR_UE_MAC_INST_t *mac,
......
......@@ -192,7 +192,6 @@ void reset_mac_inst(NR_UE_MAC_INST_t *nr_mac)
for (int i = 0; i < NR_MAX_NUM_LCID; i++) {
LOG_D(NR_MAC, "Applying default logical channel config for LCID %d\n", i);
nr_mac->scheduling_info.lc_sched_info[i].Bj = 0;
nr_mac->scheduling_info.lc_sched_info[i].LCID_buffer_with_data = false;
nr_mac->scheduling_info.lc_sched_info[i].LCID_buffer_remain = 0;
}
......@@ -326,27 +325,3 @@ void release_mac_configuration(NR_UE_MAC_INST_t *mac, NR_UE_MAC_reset_cause_t ca
for (int i = mac->TAG_list.count; i > 0 ; i--)
asn_sequence_del(&mac->TAG_list, i - 1, 1);
}
void free_rach_structures(NR_UE_MAC_INST_t *nr_mac, int bwp_id)
{
for (int j = 0; j < MAX_NB_PRACH_CONF_PERIOD_IN_ASSOCIATION_PATTERN_PERIOD; j++)
for (int k = 0; k < MAX_NB_FRAME_IN_PRACH_CONF_PERIOD; k++)
for (int l = 0; l < MAX_NB_SLOT_IN_FRAME; l++)
free(nr_mac->prach_assoc_pattern[bwp_id].prach_conf_period_list[j].prach_occasion_slot_map[k][l].prach_occasion);
free(nr_mac->ssb_list[bwp_id].tx_ssb);
}
void reset_ra(NR_UE_MAC_INST_t *nr_mac, bool free_prach)
{
RA_config_t *ra = &nr_mac->ra;
if(ra->rach_ConfigDedicated)
asn1cFreeStruc(asn_DEF_NR_RACH_ConfigDedicated, ra->rach_ConfigDedicated);
memset(ra, 0, sizeof(RA_config_t));
if (!free_prach)
return;
for (int i = 0; i < MAX_NUM_BWP_UE; i++)
free_rach_structures(nr_mac, i);
}
......@@ -785,7 +785,7 @@ void nr_ue_get_rach(NR_UE_MAC_INST_t *mac, int CC_id, frame_t frame, uint8_t gNB
} else if (!IS_SA_MODE(get_softmodem_params())) {
uint8_t temp_pdu[16] = {0};
size_sdu = nr_write_ce_ulsch_pdu(temp_pdu, mac, 0, &(mac->crnti), NULL, NULL, NULL);
size_sdu = nr_write_ce_msg3_pdu(temp_pdu, mac, mac->crnti, temp_pdu + sizeof(temp_pdu));
ra->Msg3_size = size_sdu;
}
} else if (ra->RA_window_cnt != -1) { // RACH is active
......@@ -1076,3 +1076,27 @@ void prepare_msg4_msgb_feedback(NR_UE_MAC_INST_t *mac, int pid, int ack_nack)
remove_ul_config_last_item(pdu);
release_ul_config(pdu, false);
}
void free_rach_structures(NR_UE_MAC_INST_t *nr_mac, int bwp_id)
{
for (int j = 0; j < MAX_NB_PRACH_CONF_PERIOD_IN_ASSOCIATION_PATTERN_PERIOD; j++)
for (int k = 0; k < MAX_NB_FRAME_IN_PRACH_CONF_PERIOD; k++)
for (int l = 0; l < MAX_NB_SLOT_IN_FRAME; l++)
free(nr_mac->prach_assoc_pattern[bwp_id].prach_conf_period_list[j].prach_occasion_slot_map[k][l].prach_occasion);
free(nr_mac->ssb_list[bwp_id].tx_ssb);
}
void reset_ra(NR_UE_MAC_INST_t *nr_mac, bool free_prach)
{
RA_config_t *ra = &nr_mac->ra;
if (ra->rach_ConfigDedicated)
asn1cFreeStruc(asn_DEF_NR_RACH_ConfigDedicated, ra->rach_ConfigDedicated);
memset(ra, 0, sizeof(RA_config_t));
if (!free_prach)
return;
for (int i = 0; i < MAX_NUM_BWP_UE; i++)
free_rach_structures(nr_mac, i);
}
This diff is collapsed.
......@@ -4,3 +4,9 @@ target_link_libraries(test_nr_ue_power_procedures PRIVATE nr_ue_power_procedures
add_dependencies(tests test_nr_ue_power_procedures)
add_test(NAME test_nr_ue_power_procedures
COMMAND ./test_nr_ue_power_procedures)
add_executable(test_nr_ue_ra_procedures test_nr_ue_ra_procedures.cpp)
target_link_libraries(test_nr_ue_ra_procedures PRIVATE nr_ue_ra_procedures nr_ue_power_procedures GTest::gtest minimal_lib)
add_dependencies(tests test_nr_ue_ra_procedures)
add_test(NAME test_nr_ue_ra_procedures
COMMAND ./test_nr_ue_ra_procedures)
/*
* 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.1 (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
*/
#include "gtest/gtest.h"
extern "C" {
#include "openair2/LAYER2/NR_MAC_UE/mac_proto.h"
#include "executables/softmodem-common.h"
uint64_t get_softmodem_optmask(void)
{
return 0;
}
static softmodem_params_t softmodem_params;
softmodem_params_t *get_softmodem_params(void)
{
return &softmodem_params;
}
void nr_mac_rrc_ra_ind(const module_id_t mod_id, int frame, bool success)
{
}
int nr_write_ce_ulsch_pdu(uint8_t *mac_ce,
NR_UE_MAC_INST_t *mac,
NR_SINGLE_ENTRY_PHR_MAC_CE *power_headroom,
const type_bsr_t *bsr,
uint8_t *mac_ce_end)
{
return 0;
}
int nr_write_ce_msg3_pdu(uint8_t *mac_ce, NR_UE_MAC_INST_t *mac, rnti_t crnti, uint8_t *mac_ce_end)
{
return 0;
}
tbs_size_t mac_rlc_data_req(const module_id_t module_idP,
const rnti_t rntiP,
const eNB_index_t eNB_index,
const frame_t frameP,
const eNB_flag_t enb_flagP,
const MBMS_flag_t MBMS_flagP,
const logical_chan_id_t channel_idP,
const tb_size_t tb_sizeP,
char *buffer_pP,
const uint32_t sourceL2Id,
const uint32_t destinationL2Id)
{
return 0;
}
fapi_nr_ul_config_request_pdu_t *lockGet_ul_config(NR_UE_MAC_INST_t *mac, frame_t frame_tx, int slot_tx, uint8_t pdu_type)
{
return nullptr;
}
void release_ul_config(fapi_nr_ul_config_request_pdu_t *configPerSlot, bool clearIt)
{
}
void remove_ul_config_last_item(fapi_nr_ul_config_request_pdu_t *pdu)
{
}
int nr_ue_configure_pucch(NR_UE_MAC_INST_t *mac,
int slot,
frame_t frame,
uint16_t rnti,
PUCCH_sched_t *pucch,
fapi_nr_ul_config_pucch_pdu *pucch_pdu)
{
return 0;
}
}
#include <cstdio>
#include "common/utils/LOG/log.h"
TEST(test_init_ra, four_step_cbra)
{
NR_UE_MAC_INST_t mac = {0};
NR_PRACH_RESOURCES_t prach_resources = {0};
NR_RACH_ConfigCommon_t nr_rach_ConfigCommon = {0};
NR_RACH_ConfigGeneric_t rach_ConfigGeneric = {0};
NR_RACH_ConfigDedicated_t *rach_ConfigDedicated = nullptr;
NR_UE_UL_BWP_t current_bwp;
mac.current_UL_BWP = &current_bwp;
long scs = 1;
current_bwp.scs = scs;
current_bwp.channel_bandwidth = 40;
nr_rach_ConfigCommon.msg1_SubcarrierSpacing = &scs;
mac.p_Max = 23;
mac.nr_band = 78;
mac.frame_type = TDD;
mac.frequency_range = FR1;
init_RA(&mac, &prach_resources, &nr_rach_ConfigCommon, &rach_ConfigGeneric, rach_ConfigDedicated);
EXPECT_EQ(mac.ra.ra_type, RA_4_STEP);
EXPECT_EQ(mac.state, UE_PERFORMING_RA);
EXPECT_EQ(mac.ra.RA_active, true);
EXPECT_EQ(mac.ra.cfra, 0);
}
TEST(test_init_ra, four_step_cfra)
{
NR_UE_MAC_INST_t mac = {0};
NR_PRACH_RESOURCES_t prach_resources = {0};
NR_RACH_ConfigCommon_t nr_rach_ConfigCommon = {0};
NR_RACH_ConfigGeneric_t rach_ConfigGeneric = {0};
NR_UE_UL_BWP_t current_bwp;
mac.current_UL_BWP = &current_bwp;
long scs = 1;
current_bwp.scs = scs;
current_bwp.channel_bandwidth = 40;
nr_rach_ConfigCommon.msg1_SubcarrierSpacing = &scs;
mac.p_Max = 23;
mac.nr_band = 78;
mac.frame_type = TDD;
mac.frequency_range = FR1;
NR_RACH_ConfigDedicated_t rach_ConfigDedicated = {0};
struct NR_CFRA cfra;
rach_ConfigDedicated.cfra = &cfra;
init_RA(&mac, &prach_resources, &nr_rach_ConfigCommon, &rach_ConfigGeneric, &rach_ConfigDedicated);
EXPECT_EQ(mac.ra.ra_type, RA_4_STEP);
EXPECT_EQ(mac.state, UE_PERFORMING_RA);
EXPECT_EQ(mac.ra.RA_active, true);
EXPECT_EQ(mac.ra.cfra, 1);
}
int main(int argc, char **argv)
{
logInit();
uniqCfg = load_configmodule(argc, argv, CONFIG_ENABLECMDLINEONLY);
g_log->log_component[MAC].level = OAILOG_DEBUG;
g_log->log_component[NR_MAC].level = OAILOG_DEBUG;
testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
......@@ -345,9 +345,6 @@ static void config_common(gNB_MAC_INST *nrmac,
}
}
uint32_t band = *frequencyInfoDL->frequencyBandList.list.array[0];
frequency_range = band < 100 ? FR1 : FR2;
frame_type_t frame_type = get_frame_type(*frequencyInfoDL->frequencyBandList.list.array[0], *scc->ssbSubcarrierSpacing);
nrmac->common_channels[0].frame_type = frame_type;
......
......@@ -778,11 +778,7 @@ static void nr_generate_Msg3_retransmission(module_id_t module_idP,
if (is_xlsch_in_slot(nr_mac->ulsch_slot_bitmap[sched_slot / 64], sched_slot)) {
const int n_slots_frame = nr_slots_per_frame[mu];
NR_beam_alloc_t beam_ul = beam_allocation_procedure(&nr_mac->beam_info,
sched_frame,
sched_slot,
ra->beam_id,
n_slots_frame);
NR_beam_alloc_t beam_ul = beam_allocation_procedure(&nr_mac->beam_info, sched_frame, sched_slot, ra->beam_id, n_slots_frame);
if (beam_ul.idx < 0)
return;
NR_beam_alloc_t beam_dci = beam_allocation_procedure(&nr_mac->beam_info, frame, slot, ra->beam_id, n_slots_frame);
......
......@@ -613,7 +613,7 @@ static void pf_dl(module_id_t module_id,
gNB_MAC_INST *mac = RC.nrmac[module_id];
NR_ServingCellConfigCommon_t *scc=mac->common_channels[0].ServingCellConfigCommon;
// UEs that could be scheduled
UEsched_t UE_sched[MAX_MOBILES_PER_GNB] = {0};
UEsched_t UE_sched[MAX_MOBILES_PER_GNB + 1] = {0};
int remainUEs = max_num_ue;
int curUE = 0;
int CC_id = 0;
......
......@@ -2729,10 +2729,6 @@ void nr_csirs_scheduling(int Mod_idP, frame_t frame, sub_frame_t slot, int n_slo
NR_SCHED_ENSURE_LOCKED(&gNB_mac->sched_lock);
// TODO implement beam procedures
int beam = 0;
uint16_t *vrb_map = gNB_mac->common_channels[CC_id].vrb_map[beam];
UE_info->sched_csirs = 0;
UE_iterator(UE_info->list, UE) {
......@@ -2764,8 +2760,7 @@ void nr_csirs_scheduling(int Mod_idP, frame_t frame, sub_frame_t slot, int n_slo
}
}
if (csi_measconfig->nzp_CSI_RS_ResourceToAddModList != NULL &&
nzp != NULL) {
if (csi_measconfig->nzp_CSI_RS_ResourceToAddModList != NULL && nzp != NULL) {
NR_NZP_CSI_RS_Resource_t *nzpcsi;
int period, offset;
......@@ -2779,12 +2774,14 @@ void nr_csirs_scheduling(int Mod_idP, frame_t frame, sub_frame_t slot, int n_slo
continue;
NR_CSI_RS_ResourceMapping_t resourceMapping = nzpcsi->resourceMapping;
csi_period_offset(NULL,nzpcsi->periodicityAndOffset,&period,&offset);
csi_period_offset(NULL, nzpcsi->periodicityAndOffset, &period, &offset);
if((frame*n_slots_frame+slot-offset)%period == 0) {
if((frame * n_slots_frame + slot - offset) % period == 0) {
LOG_D(NR_MAC,"Scheduling CSI-RS in frame %d slot %d Resource ID %ld\n",
frame, slot, nzpcsi->nzp_CSI_RS_ResourceId);
LOG_D(NR_MAC,"Scheduling CSI-RS in frame %d slot %d Resource ID %ld\n", frame, slot, nzpcsi->nzp_CSI_RS_ResourceId);
NR_beam_alloc_t beam_csi = beam_allocation_procedure(&gNB_mac->beam_info, frame, slot, UE->UE_beam_index, n_slots_frame);
AssertFatal(beam_csi.idx >= 0, "Cannot allocate CSI-RS in any available beam\n");
uint16_t *vrb_map = gNB_mac->common_channels[CC_id].vrb_map[beam_csi.idx];
UE_info->sched_csirs |= (1 << dl_bwp->bwp_id);
nfapi_nr_dl_tti_request_pdu_t *dl_tti_csirs_pdu = &dl_req->dl_tti_pdu_list[dl_req->nPDUs];
......@@ -2793,6 +2790,11 @@ void nr_csirs_scheduling(int Mod_idP, frame_t frame, sub_frame_t slot, int n_slo
dl_tti_csirs_pdu->PDUSize = (uint8_t)(2+sizeof(nfapi_nr_dl_tti_csi_rs_pdu));
nfapi_nr_dl_tti_csi_rs_pdu_rel15_t *csirs_pdu_rel15 = &dl_tti_csirs_pdu->csi_rs_pdu.csi_rs_pdu_rel15;
csirs_pdu_rel15->precodingAndBeamforming.num_prgs = 1;
csirs_pdu_rel15->precodingAndBeamforming.prg_size = resourceMapping.freqBand.nrofRBs; //1 PRG of max size
csirs_pdu_rel15->precodingAndBeamforming.dig_bf_interfaces = 1;
csirs_pdu_rel15->precodingAndBeamforming.prgs_list[0].pm_idx = 0;
csirs_pdu_rel15->precodingAndBeamforming.prgs_list[0].dig_bf_interface_list[0].beam_idx = UE->UE_beam_index;
csirs_pdu_rel15->bwp_size = dl_bwp->BWPSize;
csirs_pdu_rel15->bwp_start = dl_bwp->BWPStart;
csirs_pdu_rel15->subcarrier_spacing = dl_bwp->scs;
......@@ -2962,8 +2964,9 @@ void nr_csirs_scheduling(int Mod_idP, frame_t frame, sub_frame_t slot, int n_slo
static void nr_mac_clean_cellgroup(NR_CellGroupConfig_t *cell_group)
{
DevAssert(cell_group != NULL);
/* remove a reconfigurationWithSync, we don't need it anymore */
if (cell_group->spCellConfig->reconfigurationWithSync != NULL) {
if (cell_group->spCellConfig && cell_group->spCellConfig->reconfigurationWithSync != NULL) {
ASN_STRUCT_FREE(asn_DEF_NR_ReconfigurationWithSync, cell_group->spCellConfig->reconfigurationWithSync);
cell_group->spCellConfig->reconfigurationWithSync = NULL;
}
......
......@@ -1790,7 +1790,7 @@ static void pf_ul(module_id_t module_id,
const int min_rb = nrmac->min_grant_prb;
// UEs that could be scheduled
UEsched_t UE_sched[MAX_MOBILES_PER_GNB] = {0};
UEsched_t UE_sched[MAX_MOBILES_PER_GNB + 1] = {0};
int remainUEs = max_num_ue;
int curUE = 0;
......
......@@ -114,14 +114,19 @@ logical_chan_id_t nr_rlc_get_lcid_from_rb(int ue_id, bool is_srb, int rb_id)
for (logical_chan_id_t id = 1; id <= 32; id++) {
nr_rlc_rb_t *rb = &ue->lcid2rb[id - 1];
if (is_srb) {
if (rb->type == NR_RLC_SRB && rb->choice.srb_id == rb_id)
if (rb->type == NR_RLC_SRB && rb->choice.srb_id == rb_id) {
nr_rlc_manager_unlock(nr_rlc_ue_manager);
return id;
}
} else {
if (rb->type == NR_RLC_DRB && rb->choice.drb_id == rb_id)
if (rb->type == NR_RLC_DRB && rb->choice.drb_id == rb_id) {
nr_rlc_manager_unlock(nr_rlc_ue_manager);
return id;
}
}
}
LOG_E(RLC, "Couldn't find LCID corresponding to %s %d\n", is_srb ? "SRB" : "DRB", rb_id);
nr_rlc_manager_unlock(nr_rlc_ue_manager);
return 0;
}
......@@ -614,10 +619,6 @@ static void max_retx_reached(void *_ue, nr_rlc_entity_t *entity)
int i;
int is_srb;
int rb_id;
#if 0
MessageDef *msg;
#endif
int is_enb;
/* is it SRB? */
for (i = 0; i < 2; i++) {
......@@ -645,23 +646,18 @@ rb_found:
is_srb ? "SRB" : "DRB",
rb_id);
/* TODO: do something for DRBs? */
if (is_srb == 0)
return;
is_enb = nr_rlc_manager_get_enb_flag(nr_rlc_ue_manager);
if (!is_enb)
return;
if (ue->rlf_handler)
ue->rlf_handler(ue->ue_id);
else
LOG_W(RLC, "UE %04x: RLF detected, but no callable RLF handler registered\n", ue->ue_id);
}
#if 0
msg = itti_alloc_new_message(TASK_RLC_ENB, RLC_SDU_INDICATION);
RLC_SDU_INDICATION(msg).rnti = ue->rnti;
RLC_SDU_INDICATION(msg).is_successful = 0;
RLC_SDU_INDICATION(msg).srb_id = rb_id;
RLC_SDU_INDICATION(msg).message_id = -1;
/* TODO: accept more than 1 instance? here we send to instance id 0 */
itti_send_msg_to_task(TASK_RRC_ENB, 0, msg);
#endif
void nr_rlc_set_rlf_handler(int ue_id, rlf_handler_t rlf_h)
{
nr_rlc_manager_lock(nr_rlc_ue_manager);
nr_rlc_ue_t *ue = nr_rlc_manager_get_ue(nr_rlc_ue_manager, ue_id);
ue->rlf_handler = rlf_h;
nr_rlc_manager_unlock(nr_rlc_ue_manager);
}
void nr_rlc_reestablish_entity(int ue_id, int lc_id)
......@@ -671,6 +667,7 @@ void nr_rlc_reestablish_entity(int ue_id, int lc_id)
if (ue == NULL) {
LOG_E(RLC, "RLC instance for the given UE was not found \n");
nr_rlc_manager_unlock(nr_rlc_ue_manager);
return;
}
nr_rlc_entity_t *rb = get_rlc_entity_from_lcid(ue, lc_id);
......@@ -1099,8 +1096,14 @@ bool nr_rlc_update_id(int from_id, int to_id)
return true;
}
/* This function is for testing purposes. At least on a COTS UE, it will
* trigger a reestablishment. */
/**
* @brief This function is for testing purposes.
* Re-establishment is triggered by resetting RLC counters of the bearer,
* which leads to UE reaching maximum RLC retransmissions, RLF detection
* and RRC triggering re-sync. It is assumed that there is ongoing traffic on the bearer.
* - With COTS UEs, triggers re-establishment on SRB 1, where periodical measurement reports are sent.
* - With OAI UE, triggers re-establishment on DRB 1, assuming there is ongoing data traffic.
*/
void nr_rlc_test_trigger_reestablishment(int ue_id)
{
nr_rlc_manager_lock(nr_rlc_ue_manager);
......@@ -1114,6 +1117,9 @@ void nr_rlc_test_trigger_reestablishment(int ue_id)
* as the UE context is created. */
nr_rlc_entity_t *ent = ue->srb[0];
ent->reestablishment(ent);
/* Trigger re-establishment on OAI UE */
nr_rlc_entity_t *drb = ue->drb[0];
drb->reestablishment(drb);
nr_rlc_manager_unlock(nr_rlc_ue_manager);
}
......
......@@ -44,6 +44,8 @@ struct NR_LogicalChannelConfig;
void nr_rlc_add_srb(int ue_id, int srb_id, const NR_RLC_BearerConfig_t *rlc_BearerConfig);
void nr_rlc_add_drb(int ue_id, int drb_id, const NR_RLC_BearerConfig_t *rlc_BearerConfig);
void nr_rlc_set_rlf_handler(int ue_id, rlf_handler_t rlf_h);
logical_chan_id_t nr_rlc_get_lcid_from_rb(int ue_id, bool is_srb, int rb_id);
void nr_rlc_reestablish_entity(int ue_id, int lc_id);
void nr_rlc_remove_ue(int ue_id);
......
......@@ -37,12 +37,15 @@ typedef struct nr_rlc_rb_t {
} choice;
} nr_rlc_rb_t;
typedef void (*rlf_handler_t)(int rnti);
typedef struct nr_rlc_ue_t {
int ue_id;
nr_rlc_entity_t *srb0;
nr_rlc_entity_t *srb[3];
nr_rlc_entity_t *drb[MAX_DRBS_PER_UE];
nr_rlc_rb_t lcid2rb[32];
rlf_handler_t rlf_handler;
} nr_rlc_ue_t;
/***********************************************************************/
......
......@@ -542,7 +542,7 @@ void set_dl_maxmimolayers(NR_PDSCH_ServingCellConfig_t *pdsch_servingcellconfig,
NR_SCS_SpecificCarrier_t *scs_carrier = scc->downlinkConfigCommon->frequencyInfoDL->scs_SpecificCarrierList.list.array[0];
int band = *scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0];
const frequency_range_t freq_range = band < 100 ? FR1 : FR2;
const frequency_range_t freq_range = band < 257 ? FR1 : FR2;
const int scs = scs_carrier->subcarrierSpacing;
const int bw_size = scs_carrier->carrierBandwidth;
......@@ -2302,7 +2302,7 @@ NR_BCCH_DL_SCH_Message_t *get_SIB1_NR(const NR_ServingCellConfigCommon_t *scc,
}
const NR_FreqBandIndicatorNR_t band = *scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0];
frequency_range_t frequency_range = band < 100 ? FR1 : FR2;
frequency_range_t frequency_range = band > 256 ? FR2 : FR1;
sib1->servingCellConfigCommon->downlinkConfigCommon.frequencyInfoDL.offsetToPointA = get_ssb_offset_to_pointA(*scc->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencySSB,
scc->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencyPointA,
scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters.subcarrierSpacing,
......
......@@ -915,7 +915,7 @@ static void rrc_gNB_process_RRCReestablishmentComplete(gNB_RRC_INST *rrc, gNB_RR
* reestablishment, instead of re-requesting the CellGroupConfig from the DU.
* Hence, add below hack; the solution would be to request the
* CellGroupConfig from the DU when doing reestablishment. */
if (cellGroupConfig->spCellConfig->reconfigurationWithSync != NULL) {
if (cellGroupConfig->spCellConfig && cellGroupConfig->spCellConfig->reconfigurationWithSync) {
ASN_STRUCT_FREE(asn_DEF_NR_ReconfigurationWithSync, cellGroupConfig->spCellConfig->reconfigurationWithSync);
cellGroupConfig->spCellConfig->reconfigurationWithSync = NULL;
}
......
......@@ -151,6 +151,11 @@ static void nr_rrc_ue_process_masterCellGroup(NR_UE_RRC_INST_t *rrc,
static void nr_rrc_ue_process_measConfig(rrcPerNB_t *rrc, NR_MeasConfig_t *const measConfig, NR_UE_Timers_Constants_t *timers);
NR_UE_RRC_INST_t* get_NR_UE_rrc_inst(int instance)
{
return &NR_UE_rrc_inst[instance];
}
static NR_RB_status_t get_DRB_status(const NR_UE_RRC_INST_t *rrc, NR_DRB_Identity_t drb_id)
{
AssertFatal(drb_id > 0 && drb_id < 33, "Invalid DRB ID %ld\n", drb_id);
......@@ -873,6 +878,13 @@ static int8_t nr_rrc_ue_decode_NR_BCCH_DL_SCH_Message(NR_UE_RRC_INST_t *rrc,
return 0;
}
static void nr_rrc_signal_maxrtxindication(int ue_id)
{
MessageDef *msg = itti_alloc_new_message(TASK_RLC_UE, ue_id, NR_RRC_RLC_MAXRTX);
NR_RRC_RLC_MAXRTX(msg).ue_id = ue_id;
itti_send_msg_to_task(TASK_RRC_NRUE, ue_id, msg);
}
static void nr_rrc_manage_rlc_bearers(NR_UE_RRC_INST_t *rrc,
const NR_CellGroupConfig_t *cellGroupConfig)
{
......@@ -901,9 +913,11 @@ static void nr_rrc_manage_rlc_bearers(NR_UE_RRC_INST_t *rrc,
if (rlc_bearer->servedRadioBearer->present == NR_RLC_BearerConfig__servedRadioBearer_PR_srb_Identity) {
NR_SRB_Identity_t srb_id = rlc_bearer->servedRadioBearer->choice.srb_Identity;
nr_rlc_add_srb(rrc->ue_id, srb_id, rlc_bearer);
nr_rlc_set_rlf_handler(rrc->ue_id, nr_rrc_signal_maxrtxindication);
} else { // DRB
NR_DRB_Identity_t drb_id = rlc_bearer->servedRadioBearer->choice.drb_Identity;
nr_rlc_add_drb(rrc->ue_id, drb_id, rlc_bearer);
nr_rlc_set_rlf_handler(rrc->ue_id, nr_rrc_signal_maxrtxindication);
}
}
}
......@@ -1843,6 +1857,15 @@ void *rrc_nrue(void *notUsed)
nr_rrc_going_to_IDLE(rrc, release_cause, NULL);
break;
case NR_RRC_RLC_MAXRTX:
// detection of RLF upon indication from RLC that the maximum number of retransmissions has been reached
LOG_W(NR_RRC,
"[UE %ld ID %d] Received indication that RLC reached max retransmissions\n",
instance,
NR_RRC_RLC_MAXRTX(msg_p).ue_id);
handle_rlf_detection(rrc);
break;
case NR_RRC_MAC_MSG3_IND:
nr_rrc_handle_msg3_indication(rrc, NR_RRC_MAC_MSG3_IND(msg_p).rnti);
break;
......@@ -2285,6 +2308,26 @@ void handle_RRCRelease(NR_UE_RRC_INST_t *rrc)
asn1cFreeStruc(asn_DEF_NR_RRCRelease, rrc->RRCRelease);
}
void handle_rlf_detection(NR_UE_RRC_INST_t *rrc)
{
// 5.3.10.3 in 38.331
bool srb2 = rrc->Srb[2] != RB_NOT_PRESENT;
bool any_drb = false;
for (int i = 0; i < MAX_DRBS_PER_UE; i++) {
if (rrc->status_DRBs[i] != RB_NOT_PRESENT) {
any_drb = true;
break;
}
}
if (rrc->as_security_activated && srb2 && any_drb) // initiate the connection re-establishment procedure
nr_rrc_initiate_rrcReestablishment(rrc, NR_ReestablishmentCause_otherFailure, 0);
else {
NR_Release_Cause_t cause = rrc->as_security_activated ? RRC_CONNECTION_FAILURE : OTHER;
nr_rrc_going_to_IDLE(rrc, cause, NULL);
}
}
void nr_rrc_going_to_IDLE(NR_UE_RRC_INST_t *rrc,
NR_Release_Cause_t release_cause,
NR_RRCRelease_t *RRCRelease)
......
......@@ -42,7 +42,7 @@
#include "common/utils/ocp_itti/intertask_interface.h"
NR_UE_RRC_INST_t *nr_rrc_init_ue(char* uecap_file, int nb_inst, int num_ant_tx);
NR_UE_RRC_INST_t* get_NR_UE_rrc_inst(int instance);
void init_nsa_message (NR_UE_RRC_INST_t *rrc, char* reconfig_file, char* rbconfig_file);
void process_nsa_message(NR_UE_RRC_INST_t *rrc, nsa_message_t nsa_message_type, void *message, int msg_len);
......@@ -63,6 +63,7 @@ void *rrc_nrue_task(void *args_p);
void *rrc_nrue(void *args_p);
void nr_rrc_handle_timers(NR_UE_RRC_INST_t *rrc);
void handle_rlf_detection(NR_UE_RRC_INST_t *rrc);
/**\brief RRC NSA UE task.
\param void *args_p Pointer on arguments to start the task. */
......
......@@ -157,10 +157,9 @@ void nr_rrc_handle_timers(NR_UE_RRC_INST_t *rrc)
bool t310_expired = nr_timer_tick(&timers->T310);
if(t310_expired) {
LOG_W(NR_RRC, "Timer T310 expired\n");
// TODO
// handle detection of radio link failure
// as described in 5.3.10.3 of 38.331
AssertFatal(false, "Radio link failure! Not handled yet!\n");
handle_rlf_detection(rrc);
}
bool t311_expired = nr_timer_tick(&timers->T311);
......
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