Integration 2021 wk18 a
MR !1145 NR_FR2_initsync_fixes -bug fixes that caused failure in PBCH detection after initial sync in FR2 MR !1100 NR_scheduling_request -per-UE PUCCH F0 resource, CSI, Preamble -Scheduling Request -MAC scheduler fixes MR !1150 rh_ci_phy_test_improve -beautified HTML report for 5G NR phy test MR !1113 hack-exit-gnb-when-no-enb-nsa -Exit gNB if connection to eNB failed - to be modified if needed. We may want to try to connect over and over again until we succeed but the modifications to the code to get this behavior are complex
This commit is contained in:
@@ -0,0 +1,7 @@
|
||||
#!/bin/bash
|
||||
while true
|
||||
do
|
||||
echo "gNB will be started automatically..."
|
||||
sleep 1
|
||||
sudo .././cmake_targets/ran_build/build/nr-softmodem -E -O ../targets/PROJECTS/GENERIC-LTE-EPC/CONF/testing_gnb.conf
|
||||
done
|
||||
@@ -230,6 +230,7 @@ MACRLCs = (
|
||||
num_cc = 1;
|
||||
tr_s_preference = "local_L1";
|
||||
tr_n_preference = "local_RRC";
|
||||
ulsch_max_slots_inactivity = 1;
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
@@ -211,6 +211,7 @@ MACRLCs = (
|
||||
num_cc = 1;
|
||||
tr_s_preference = "local_L1";
|
||||
tr_n_preference = "local_RRC";
|
||||
ulsch_max_slots_inactivity = 1;
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
#this is a configuration file
|
||||
#used to build real time processing statistics
|
||||
#for 5G NR phy test (gNB terminate)
|
||||
Title : Processing Time (us)
|
||||
ColNames :
|
||||
- Metric
|
||||
- Average
|
||||
- Max
|
||||
- Average vs Reference Deviation (Reference Value ; Acceptability Threshold)
|
||||
Ref :
|
||||
feprx : 60.0
|
||||
feptx_prec : 8.0
|
||||
feptx_ofdm : 85.0
|
||||
feptx_total : 75.0
|
||||
L1 Tx processing : 300.0
|
||||
DLSCH encoding : 230.0
|
||||
L1 Rx processing : 175.0
|
||||
PUSCH inner-receiver : 100.0
|
||||
PUSCH decoding : 140.0
|
||||
DL & UL scheduling timing stats : 15.0
|
||||
UL Indication : 20.0
|
||||
Threshold :
|
||||
feprx : 1.25
|
||||
feptx_prec : 1.25
|
||||
feptx_ofdm : 1.25
|
||||
feptx_total : 1.25
|
||||
L1 Tx processing : 1.25
|
||||
DLSCH encoding : 1.25
|
||||
L1 Rx processing : 1.25
|
||||
PUSCH inner-receiver : 1.25
|
||||
PUSCH decoding : 1.25
|
||||
DL & UL scheduling timing stats : 1.25
|
||||
UL Indication : 1.25
|
||||
@@ -453,6 +453,37 @@ class HTMLManagement():
|
||||
self.htmlFile.write(' </tr>\n')
|
||||
self.htmlFile.close()
|
||||
|
||||
#for the moment it is limited to 4 columns, to be made generic later
|
||||
def CreateHtmlDataLogTable(self, DataLog):
|
||||
if (self.htmlFooterCreated or (not self.htmlHeaderCreated)):
|
||||
return
|
||||
self.htmlFile = open('test_results.html', 'a')
|
||||
|
||||
# TabHeader
|
||||
self.htmlFile.write(' <tr bgcolor = "#F0F0F0" >\n')
|
||||
self.htmlFile.write(' <td colspan=' + str(5+self.htmlUEConnected) + '><b> ---- ' + DataLog['Title'] + ' ---- </b></td>\n')
|
||||
self.htmlFile.write(' </tr>\n')
|
||||
self.htmlFile.write(' <tr bgcolor = "#33CCFF" >\n')
|
||||
self.htmlFile.write(' <th colspan="3">'+ DataLog['ColNames'][0] +'</th>\n')
|
||||
self.htmlFile.write(' <th>' + DataLog['ColNames'][1] + '</th>\n')
|
||||
self.htmlFile.write(' <th>' + DataLog['ColNames'][2] + '</th>\n')
|
||||
self.htmlFile.write(' <th colspan=' + str(1+self.htmlUEConnected) + '>'+ DataLog['ColNames'][3] +'</th>\n')
|
||||
self.htmlFile.write(' </tr>\n')
|
||||
|
||||
for k in DataLog['Data']:
|
||||
# TestRow
|
||||
self.htmlFile.write(' <tr>\n')
|
||||
self.htmlFile.write(' <td colspan="3" bgcolor = "lightcyan" >' + k + ' </td>\n')
|
||||
self.htmlFile.write(' <td bgcolor = "lightcyan" >' + DataLog['Data'][k][0] + ' </td>\n')
|
||||
self.htmlFile.write(' <td bgcolor = "lightcyan" >' + DataLog['Data'][k][1] + ' </td>\n')
|
||||
if float(DataLog['Data'][k][2])> DataLog['Threshold'][k]:
|
||||
self.htmlFile.write(' <th bgcolor = "red" >' + DataLog['Data'][k][2] + ' (Ref = ' + str(DataLog['Ref'][k]) + ' ; Thres = ' +str(DataLog['Threshold'][k])+') ' + '</th>\n')
|
||||
else:
|
||||
self.htmlFile.write(' <th bgcolor = "green" ><font color="white">' + DataLog['Data'][k][2] + ' (Ref = ' + str(DataLog['Ref'][k]) + ' ; Thres = ' +str(DataLog['Threshold'][k])+') ' + '</th>\n')
|
||||
self.htmlFile.write(' </tr>\n')
|
||||
self.htmlFile.close()
|
||||
|
||||
|
||||
def CreateHtmlTestRowQueue(self, options, status, ue_status, ue_queue):
|
||||
if ((not self.htmlFooterCreated) and (self.htmlHeaderCreated)):
|
||||
self.htmlFile = open('test_results.html', 'a')
|
||||
|
||||
+41
-11
@@ -37,6 +37,8 @@ import logging
|
||||
import os
|
||||
import time
|
||||
from multiprocessing import Process, Lock, SimpleQueue
|
||||
import yaml
|
||||
|
||||
|
||||
#-----------------------------------------------------------
|
||||
# OAI Testing modules
|
||||
@@ -90,6 +92,7 @@ class RANManagement():
|
||||
self.testCase_id = ''
|
||||
self.epcPcapFile = ''
|
||||
self.runtime_stats= ''
|
||||
self.datalog_rt_stats={}
|
||||
|
||||
|
||||
|
||||
@@ -633,6 +636,8 @@ class RANManagement():
|
||||
HTML.CreateHtmlTestRow(self.runtime_stats, 'OK', CONST.ALL_PROCESSES_OK)
|
||||
else:
|
||||
HTML.CreateHtmlTestRow(self.runtime_stats, 'OK', CONST.ALL_PROCESSES_OK)
|
||||
if len(self.datalog_rt_stats)!=0:
|
||||
HTML.CreateHtmlDataLogTable(self.datalog_rt_stats)
|
||||
self.eNBmbmsEnables[int(self.eNB_instance)] = False
|
||||
self.eNBstatuses[int(self.eNB_instance)] = -1
|
||||
|
||||
@@ -699,6 +704,21 @@ class RANManagement():
|
||||
#count "problem receiving samples" msg
|
||||
pb_receiving_samples_cnt = 0
|
||||
|
||||
#the datalog config file has to be loaded
|
||||
datalog_rt_stats_file='datalog_rt_stats.yaml'
|
||||
if (os.path.isfile(datalog_rt_stats_file)):
|
||||
yaml_file=datalog_rt_stats_file
|
||||
elif (os.path.isfile('ci-scripts/'+datalog_rt_stats_file)):
|
||||
yaml_file='ci-scripts/'+datalog_rt_stats_file
|
||||
else:
|
||||
logging.error("Datalog RT stats yaml file cannot be found")
|
||||
sys.exit("Datalog RT stats yaml file cannot be found")
|
||||
|
||||
with open(yaml_file,'r') as f:
|
||||
datalog_rt_stats = yaml.load(f,Loader=yaml.FullLoader)
|
||||
rt_keys = datalog_rt_stats['Ref'] #we use the keys from the Ref field
|
||||
|
||||
|
||||
for line in enb_log_file.readlines():
|
||||
# Runtime statistics
|
||||
result = re.search('Run time:' ,str(line))
|
||||
@@ -857,21 +877,21 @@ class RANManagement():
|
||||
#keys below are the markers we are loooking for, loop over this keys list
|
||||
#everytime these markers are found in the log file, the previous ones are overwritten in the dict
|
||||
#eventually we record and print only the last occurence
|
||||
keys = {'UE ID','dlsch_rounds','dlsch_total_bytes','ulsch_rounds','ulsch_total_bytes_scheduled', 'scheduling timing stats'}
|
||||
keys = {'UE ID','dlsch_rounds','dlsch_total_bytes','ulsch_rounds','ulsch_total_bytes_scheduled'}
|
||||
for k in keys:
|
||||
result = re.search(k, line)
|
||||
if result is not None:
|
||||
#remove 1- all useless char before relevant info (ulsch or dlsch) 2- trailing char
|
||||
dlsch_ulsch_stats[k]=re.sub(r'^.*\]\s+', r'' , line.rstrip())
|
||||
#real time statistics
|
||||
#same method as above
|
||||
keys = {'feprx','feptx_prec','feptx_ofdm','feptx_total','L1 Tx processing','DLSCH encoding','L1 Rx processing','PUSCH inner-receiver','PUSCH decoding'}
|
||||
for k in keys:
|
||||
#real time statistics for gNB
|
||||
for k in rt_keys:
|
||||
result = re.search(k, line)
|
||||
if result is not None:
|
||||
#remove 1- all useless char before relevant info 2- trailing char
|
||||
line=line.replace('[0m','')
|
||||
tmp=re.match(rf'^.*?(\b{k}\b.*)',line.rstrip()) #from python 3.6 we can use literal string interpolation for the variable k, using rf' in the regex
|
||||
real_time_stats[k]=tmp.group(1)
|
||||
|
||||
#count "problem receiving samples" msg
|
||||
result = re.search('\[PHY\]\s+problem receiving samples', str(line))
|
||||
if result is not None:
|
||||
@@ -920,13 +940,23 @@ class RANManagement():
|
||||
logging.debug(dlsch_ulsch_stats[key])
|
||||
htmleNBFailureMsg += statMsg
|
||||
|
||||
#real time statistics statistics
|
||||
#real time statistics
|
||||
datalog_rt_stats['Data']={}
|
||||
if len(real_time_stats)!=0: #check if dictionary is not empty
|
||||
statMsg=''
|
||||
for key in real_time_stats: #for each dictionary key
|
||||
statMsg += real_time_stats[key] + '\n'
|
||||
logging.debug(real_time_stats[key])
|
||||
htmleNBFailureMsg += statMsg
|
||||
for k in real_time_stats:
|
||||
tmp=re.match(r'^(?P<metric>.*):\s+(?P<avg>\d+\.\d+) us;\s+\d+;\s+(?P<max>\d+\.\d+) us;',real_time_stats[k])
|
||||
if tmp is not None:
|
||||
metric=tmp.group('metric')
|
||||
avg=float(tmp.group('avg'))
|
||||
max=float(tmp.group('max'))
|
||||
datalog_rt_stats['Data'][metric]=["{:.0f}".format(avg),"{:.0f}".format(max),"{:.2f}".format(avg/datalog_rt_stats['Ref'][metric])]
|
||||
#once all metrics are collected, store the data as a class attribute to build a dedicated HTML table afterward
|
||||
self.datalog_rt_stats=datalog_rt_stats
|
||||
#check if there is a fail => will render the test as failed
|
||||
for k in datalog_rt_stats['Data']:
|
||||
if float(datalog_rt_stats['Data'][k][2])> datalog_rt_stats['Threshold'][k]: #condition for fail : avg/ref is greater than the fixed threshold
|
||||
#setting prematureExit is ok although not the best option
|
||||
self.prematureExit=True
|
||||
else:
|
||||
statMsg = 'No real time stats found in the log file\n'
|
||||
logging.debug('No real time stats found in the log file')
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
<htmlTabRef>gNB-PHY-Test</htmlTabRef>
|
||||
<htmlTabName>Run-gNB-PHY-Test</htmlTabName>
|
||||
<htmlTabIcon>tasks</htmlTabIcon>
|
||||
<repeatCount>2</repeatCount>
|
||||
<repeatCount>3</repeatCount>
|
||||
<TestCaseRequestedList>
|
||||
090101 000001 090109
|
||||
</TestCaseRequestedList>
|
||||
@@ -40,7 +40,7 @@
|
||||
<testCase id="000001">
|
||||
<class>IdleSleep</class>
|
||||
<desc>Sleep</desc>
|
||||
<idle_sleep_time_in_sec>180</idle_sleep_time_in_sec>
|
||||
<idle_sleep_time_in_sec>300</idle_sleep_time_in_sec>
|
||||
</testCase>
|
||||
|
||||
|
||||
|
||||
+3
-3
@@ -552,7 +552,7 @@ void *UE_thread(void *arg) {
|
||||
if (UE->is_synchronized) {
|
||||
decoded_frame_rx=(((mac->mib->systemFrameNumber.buf[0] >> mac->mib->systemFrameNumber.bits_unused)<<4) | tmp->proc.decoded_frame_rx);
|
||||
// shift the frame index with all the frames we trashed meanwhile we perform the synch search
|
||||
decoded_frame_rx=(decoded_frame_rx + (!UE->init_sync_frame) + trashed_frames) % MAX_FRAME_NUMBER;
|
||||
decoded_frame_rx=(decoded_frame_rx + UE->init_sync_frame + trashed_frames) % MAX_FRAME_NUMBER;
|
||||
}
|
||||
delNotifiedFIFO_elt(res);
|
||||
start_rx_stream=0;
|
||||
@@ -692,9 +692,9 @@ void *UE_thread(void *arg) {
|
||||
pushNotifiedFIFO_nothreadSafe(&freeBlocks,res);
|
||||
}
|
||||
|
||||
if ( decoded_frame_rx>0 && decoded_frame_rx != curMsg->proc.frame_rx)
|
||||
if (decoded_frame_rx>0 && decoded_frame_rx != curMsg->proc.frame_rx)
|
||||
LOG_E(PHY,"Decoded frame index (%d) is not compatible with current context (%d), UE should go back to synch mode\n",
|
||||
decoded_frame_rx, curMsg->proc.frame_rx );
|
||||
decoded_frame_rx, curMsg->proc.frame_rx);
|
||||
|
||||
// use previous timing_advance value to compute writeTimestamp
|
||||
writeTimestamp = timestamp+
|
||||
|
||||
@@ -308,12 +308,15 @@ int nr_initial_sync(UE_nr_rxtx_proc_t *proc, PHY_VARS_NR_UE *ue, int n_frames)
|
||||
// every 7*(1<<mu) symbols there is a different prefix length (38.211 5.3.1)
|
||||
int n_symb_prefix0 = (ue->symbol_offset/(7*(1<<mu)))+1;
|
||||
sync_pos_frame = n_symb_prefix0*(fp->ofdm_symbol_size + fp->nb_prefix_samples0)+(ue->symbol_offset-n_symb_prefix0)*(fp->ofdm_symbol_size + fp->nb_prefix_samples);
|
||||
if (ue->ssb_offset < sync_pos_frame)
|
||||
// for a correct computation of frame number to sync with the one decoded at MIB we need to take into account in which of the n_frames we got sync
|
||||
ue->init_sync_frame = n_frames - 1 - is;
|
||||
// we also need to take into account the shift by samples_per_frame in case the if is true
|
||||
if (ue->ssb_offset < sync_pos_frame){
|
||||
ue->rx_offset = fp->samples_per_frame - sync_pos_frame + ue->ssb_offset;
|
||||
ue->init_sync_frame += 1;
|
||||
}
|
||||
else
|
||||
ue->rx_offset = ue->ssb_offset - sync_pos_frame;
|
||||
|
||||
ue->init_sync_frame = is;
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -589,7 +589,7 @@ int nr_rx_pbch( PHY_VARS_NR_UE *ue,
|
||||
frame_parms->ssb_index += (((nr_ue_pbch_vars->xtra_byte>>(7-i))&0x01)<<(3+i));
|
||||
}
|
||||
|
||||
ue->symbol_offset = nr_get_ssb_start_symbol(frame_parms,i_ssb);
|
||||
ue->symbol_offset = nr_get_ssb_start_symbol(frame_parms,frame_parms->ssb_index);
|
||||
if (frame_parms->half_frame_bit)
|
||||
ue->symbol_offset += (frame_parms->slots_per_frame>>1)*frame_parms->symbols_per_slot;
|
||||
|
||||
|
||||
@@ -142,7 +142,7 @@ void nr_fill_rx_indication(fapi_nr_rx_indication_t *rx_ind,
|
||||
case FAPI_NR_RX_PDU_TYPE_MIB:
|
||||
rx_ind->rx_indication_body[n_pdus - 1].mib_pdu.pdu = ue->pbch_vars[gNB_id]->decoded_output;
|
||||
rx_ind->rx_indication_body[n_pdus - 1].mib_pdu.additional_bits = ue->pbch_vars[gNB_id]->xtra_byte;
|
||||
rx_ind->rx_indication_body[n_pdus - 1].mib_pdu.ssb_index = frame_parms->ssb_index;
|
||||
rx_ind->rx_indication_body[n_pdus - 1].mib_pdu.ssb_index = (frame_parms->ssb_index)&0x7;
|
||||
rx_ind->rx_indication_body[n_pdus - 1].mib_pdu.ssb_length = frame_parms->Lmax;
|
||||
rx_ind->rx_indication_body[n_pdus - 1].mib_pdu.cell_id = frame_parms->Nid_cell;
|
||||
break;
|
||||
@@ -350,7 +350,7 @@ void nr_ue_pbch_procedures(uint8_t gNB_id,
|
||||
|
||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_PBCH_PROCEDURES, VCD_FUNCTION_IN);
|
||||
|
||||
LOG_D(PHY,"[UE %d] Frame %d, Trying PBCH (NidCell %d, gNB_id %d)\n",ue->Mod_id,frame_rx,ue->frame_parms.Nid_cell,gNB_id);
|
||||
LOG_D(PHY,"[UE %d] Frame %d Slot %d, Trying PBCH (NidCell %d, gNB_id %d)\n",ue->Mod_id,frame_rx,nr_slot_rx,ue->frame_parms.Nid_cell,gNB_id);
|
||||
|
||||
ret = nr_rx_pbch(ue, proc,
|
||||
ue->pbch_vars[gNB_id],
|
||||
|
||||
@@ -733,13 +733,7 @@ int main(int argc, char **argv)
|
||||
|
||||
prepare_scd(scd);
|
||||
|
||||
fill_default_secondaryCellGroup(scc,
|
||||
scd,
|
||||
secondaryCellGroup,
|
||||
0,
|
||||
1,
|
||||
n_tx,
|
||||
0);
|
||||
fill_default_secondaryCellGroup(scc, scd, secondaryCellGroup, 0, 1, n_tx, 0, 0);
|
||||
|
||||
/* RRC parameter validation for secondaryCellGroup */
|
||||
fix_scd(scd);
|
||||
|
||||
@@ -676,13 +676,7 @@ int main(int argc, char **argv)
|
||||
|
||||
prepare_scd(scd);
|
||||
|
||||
fill_default_secondaryCellGroup(scc,
|
||||
scd,
|
||||
secondaryCellGroup,
|
||||
0,
|
||||
1,
|
||||
n_tx,
|
||||
0);
|
||||
fill_default_secondaryCellGroup(scc, scd, secondaryCellGroup, 0, 1, n_tx, 0, 0);
|
||||
|
||||
// xer_fprint(stdout, &asn_DEF_NR_CellGroupConfig, (const void*)secondaryCellGroup);
|
||||
|
||||
|
||||
@@ -55,7 +55,7 @@
|
||||
#define CONFIG_STRING_MACRLC_REMOTE_S_PORTC "remote_s_portc"
|
||||
#define CONFIG_STRING_MACRLC_LOCAL_S_PORTD "local_s_portd"
|
||||
#define CONFIG_STRING_MACRLC_REMOTE_S_PORTD "remote_s_portd"
|
||||
|
||||
#define CONFIG_STRING_MACRLC_ULSCH_MAX_SLOTS_INACTIVITY "ulsch_max_slots_inactivity"
|
||||
|
||||
/*-------------------------------------------------------------------------------------------------------------------------------------------------------*/
|
||||
/* MacRLC configuration parameters */
|
||||
@@ -79,6 +79,7 @@
|
||||
{CONFIG_STRING_MACRLC_REMOTE_S_PORTC, NULL, 0, uptr:NULL, defintval:50020, TYPE_UINT, 0}, \
|
||||
{CONFIG_STRING_MACRLC_LOCAL_S_PORTD, NULL, 0, uptr:NULL, defintval:50021, TYPE_UINT, 0}, \
|
||||
{CONFIG_STRING_MACRLC_REMOTE_S_PORTD, NULL, 0, uptr:NULL, defintval:50021, TYPE_UINT, 0}, \
|
||||
{CONFIG_STRING_MACRLC_ULSCH_MAX_SLOTS_INACTIVITY, "Maximum number of slots before a UE is scheduled ULSCH due to inactivity", 0, uptr:NULL, defintval:200, TYPE_UINT, 0}, \
|
||||
}
|
||||
#define MACRLC_CC_IDX 0
|
||||
#define MACRLC_TRANSPORT_N_PREFERENCE_IDX 1
|
||||
@@ -97,5 +98,6 @@
|
||||
#define MACRLC_REMOTE_S_PORTC_IDX 14
|
||||
#define MACRLC_LOCAL_S_PORTD_IDX 15
|
||||
#define MACRLC_REMOTE_S_PORTD_IDX 16
|
||||
#define MACRLC_ULSCH_MAX_SLOTS_INACTIVITY 17
|
||||
/*---------------------------------------------------------------------------------------------------------------------------------------------------------*/
|
||||
#endif
|
||||
|
||||
@@ -53,7 +53,7 @@
|
||||
|
||||
//#include "L1_paramdef.h"
|
||||
#include "L1_nr_paramdef.h"
|
||||
#include "MACRLC_paramdef.h"
|
||||
#include "MACRLC_nr_paramdef.h"
|
||||
#include "common/config/config_userapi.h"
|
||||
//#include "RRC_config_tools.h"
|
||||
#include "gnb_paramdef.h"
|
||||
@@ -698,6 +698,7 @@ void RCconfig_nr_macrlc() {
|
||||
}else { // other midhaul
|
||||
AssertFatal(1==0,"MACRLC %d: %s unknown southbound midhaul\n",j,*(MacRLC_ParamList.paramarray[j][MACRLC_TRANSPORT_S_PREFERENCE_IDX].strptr));
|
||||
}
|
||||
RC.nrmac[j]->ulsch_max_slots_inactivity = *(MacRLC_ParamList.paramarray[j][MACRLC_ULSCH_MAX_SLOTS_INACTIVITY].uptr);
|
||||
}// for (j=0;j<RC.nb_nr_macrlc_inst;j++)
|
||||
}else {// MacRLC_ParamList.numelt > 0
|
||||
AssertFatal (0,"No " CONFIG_STRING_MACRLC_LIST " configuration found");
|
||||
|
||||
@@ -372,14 +372,6 @@ int rrc_mac_config_req_gNB(module_id_t Mod_idP,
|
||||
AssertFatal(RC.nrmac[Mod_idP]->common_channels[0].vrb_map_UL,
|
||||
"could not allocate memory for RC.nrmac[]->common_channels[0].vrb_map_UL\n");
|
||||
|
||||
for (int i = 0; i < MAX_NUM_BWP; ++i) {
|
||||
RC.nrmac[Mod_idP]->pucch_index_used[i] =
|
||||
calloc(n, sizeof(*RC.nrmac[Mod_idP]->pucch_index_used));
|
||||
AssertFatal(RC.nrmac[Mod_idP]->pucch_index_used[i],
|
||||
"could not allocate memory for RC.nrmac[]->pucch_index_used[%d]\n",
|
||||
i);
|
||||
}
|
||||
|
||||
LOG_I(MAC,"Configuring common parameters from NR ServingCellConfig\n");
|
||||
|
||||
config_common(Mod_idP,
|
||||
|
||||
@@ -402,7 +402,7 @@ void gNB_dlsch_ulsch_scheduler(module_id_t module_idP,
|
||||
}
|
||||
|
||||
// This schedule SR
|
||||
// TODO
|
||||
nr_sr_reporting(module_idP, frame, slot);
|
||||
|
||||
// Schedule CSI measurement reporting: check in slot 0 for the whole frame
|
||||
if (slot == 0)
|
||||
|
||||
@@ -253,8 +253,8 @@ void schedule_nr_mib(module_id_t module_idP, frame_t frameP, sub_frame_t slotP)
|
||||
case 3:
|
||||
// long bitmap FR2 max 64 SSBs
|
||||
num_ssb = 0;
|
||||
for (int i_ssb=0; i_ssb<63; i_ssb++) {
|
||||
if ((longBitmap->buf[i_ssb/8]>>(7-i_ssb))&0x01) {
|
||||
for (int i_ssb=0; i_ssb<64; i_ssb++) {
|
||||
if ((longBitmap->buf[i_ssb/8]>>(7-(i_ssb%8)))&0x01) {
|
||||
ssb_start_symbol = get_ssb_start_symbol(band,scs,i_ssb);
|
||||
// if start symbol is in current slot, schedule current SSB, fill VRB map and call get_type0_PDCCH_CSS_config_parameters
|
||||
if ((ssb_start_symbol/14) == rel_slot){
|
||||
|
||||
@@ -118,8 +118,13 @@ int diff_rsrp_ssb_csi_meas_10_1_6_1_2[16] = {
|
||||
|
||||
void nr_schedule_pucch(int Mod_idP,
|
||||
frame_t frameP,
|
||||
sub_frame_t slotP) {
|
||||
NR_UE_info_t *UE_info = &RC.nrmac[Mod_idP]->UE_info;
|
||||
sub_frame_t slotP)
|
||||
{
|
||||
gNB_MAC_INST *nrmac = RC.nrmac[Mod_idP];
|
||||
if (!is_xlsch_in_slot(nrmac->ulsch_slot_bitmap[slotP / 64], slotP))
|
||||
return;
|
||||
|
||||
NR_UE_info_t *UE_info = &nrmac->UE_info;
|
||||
const NR_list_t *UE_list = &UE_info->list;
|
||||
|
||||
for (int UE_id = UE_list->head; UE_id >= 0; UE_id = UE_list->next[UE_id]) {
|
||||
@@ -504,11 +509,11 @@ void nr_csi_meas_reporting(int Mod_idP,
|
||||
|
||||
// find free PUCCH that is in order with possibly existing PUCCH
|
||||
// schedulings (other CSI, SR)
|
||||
NR_sched_pucch_t *curr_pucch = &sched_ctrl->sched_pucch[2];
|
||||
NR_sched_pucch_t *curr_pucch = &sched_ctrl->sched_pucch[1];
|
||||
AssertFatal(curr_pucch->csi_bits == 0
|
||||
&& !curr_pucch->sr_flag
|
||||
&& curr_pucch->dai_c == 0,
|
||||
"PUCCH not free at index 2 for UE %04x\n",
|
||||
"PUCCH not free at index 1 for UE %04x\n",
|
||||
UE_info->rnti[UE_id]);
|
||||
curr_pucch->frame = frame;
|
||||
curr_pucch->ul_slot = sched_slot;
|
||||
@@ -1007,14 +1012,6 @@ void handle_nr_uci_pucch_0_1(module_id_t mod_id,
|
||||
NR_UE_info_t *UE_info = &RC.nrmac[mod_id]->UE_info;
|
||||
NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id];
|
||||
|
||||
// tpc (power control)
|
||||
sched_ctrl->tpc1 = nr_get_tpc(RC.nrmac[mod_id]->pucch_target_snrx10,
|
||||
uci_01->ul_cqi,
|
||||
30);
|
||||
sched_ctrl->pucch_snrx10 = uci_01->ul_cqi * 5 - 640;
|
||||
|
||||
NR_ServingCellConfigCommon_t *scc = RC.nrmac[mod_id]->common_channels->ServingCellConfigCommon;
|
||||
const int num_slots = nr_slots_per_frame[*scc->ssbSubcarrierSpacing];
|
||||
if (((uci_01->pduBitmap >> 1) & 0x01)) {
|
||||
// iterate over received harq bits
|
||||
for (int harq_bit = 0; harq_bit < uci_01->harq->num_harq; harq_bit++) {
|
||||
@@ -1029,6 +1026,20 @@ void handle_nr_uci_pucch_0_1(module_id_t mod_id,
|
||||
handle_dl_harq(mod_id, UE_id, pid, harq_value == 1 && harq_confidence == 0);
|
||||
}
|
||||
}
|
||||
|
||||
// check scheduling request result, confidence_level == 0 is good
|
||||
if (uci_01->pduBitmap & 0x1 && uci_01->sr->sr_indication && uci_01->sr->sr_confidence_level == 0 && uci_01->ul_cqi >= 148) {
|
||||
// SR detected with SNR >= 10dB
|
||||
sched_ctrl->SR |= true;
|
||||
LOG_D(MAC, "SR UE %04x ul_cqi %d\n", uci_01->rnti, uci_01->ul_cqi);
|
||||
}
|
||||
|
||||
// tpc (power control) only if we received AckNack or positive SR. For a
|
||||
// negative SR, the UE won't have sent anything, and the SNR is not valid
|
||||
if (((uci_01->pduBitmap >> 1) & 0x1) || sched_ctrl->SR) {
|
||||
sched_ctrl->tpc1 = nr_get_tpc(RC.nrmac[mod_id]->pucch_target_snrx10, uci_01->ul_cqi, 30);
|
||||
sched_ctrl->pucch_snrx10 = uci_01->ul_cqi * 5 - 640;
|
||||
}
|
||||
}
|
||||
|
||||
void handle_nr_uci_pucch_2_3_4(module_id_t mod_id,
|
||||
@@ -1051,8 +1062,6 @@ void handle_nr_uci_pucch_2_3_4(module_id_t mod_id,
|
||||
30);
|
||||
sched_ctrl->pucch_snrx10 = uci_234->ul_cqi * 5 - 640;
|
||||
|
||||
NR_ServingCellConfigCommon_t *scc = RC.nrmac[mod_id]->common_channels->ServingCellConfigCommon;
|
||||
const int num_slots = nr_slots_per_frame[*scc->ssbSubcarrierSpacing];
|
||||
if ((uci_234->pduBitmap >> 1) & 0x01) {
|
||||
// iterate over received harq bits
|
||||
for (int harq_bit = 0; harq_bit < uci_234->harq.harq_bit_len; harq_bit++) {
|
||||
@@ -1104,10 +1113,7 @@ bool nr_acknack_scheduling(int mod_id,
|
||||
* * we do not multiplex with CSI, which is always in pucch_sched[2]
|
||||
* * SR uses format 0 and is allocated in the first UL (mixed) slot (and not
|
||||
* later)
|
||||
* * that the PUCCH resource set 0 (for up to 2 bits) points to the first N
|
||||
* PUCCH resources, where N is the number of resources in the PUCCH
|
||||
* resource set. This is used in pucch_index_used, which counts the used
|
||||
* resources by index, and not by their ID! */
|
||||
* * each UE has dedicated PUCCH Format 0 resources, and we use index 0! */
|
||||
NR_UE_sched_ctrl_t *sched_ctrl = &RC.nrmac[mod_id]->UE_info.UE_sched_ctrl[UE_id];
|
||||
NR_sched_pucch_t *pucch = &sched_ctrl->sched_pucch[0];
|
||||
AssertFatal(pucch->csi_bits == 0,
|
||||
@@ -1115,12 +1121,8 @@ bool nr_acknack_scheduling(int mod_id,
|
||||
__func__,
|
||||
pucch->csi_bits);
|
||||
|
||||
const int max_acknacks = 2;
|
||||
AssertFatal(pucch->dai_c + pucch->sr_flag <= max_acknacks,
|
||||
"illegal number of bits in PUCCH of UE %d\n",
|
||||
UE_id);
|
||||
/* if the currently allocated PUCCH of this UE is full, allocate it */
|
||||
if (pucch->sr_flag + pucch->dai_c == max_acknacks) {
|
||||
if (pucch->dai_c == 2) {
|
||||
/* advance the UL slot information in PUCCH by one so we won't schedule in
|
||||
* the same slot again */
|
||||
const int f = pucch->frame;
|
||||
@@ -1130,7 +1132,7 @@ bool nr_acknack_scheduling(int mod_id,
|
||||
pucch->frame = s == n_slots_frame - 1 ? (f + 1) % 1024 : f;
|
||||
pucch->ul_slot = (s + 1) % n_slots_frame;
|
||||
// we assume that only two indices over the array sched_pucch exist
|
||||
const NR_sched_pucch_t *csi_pucch = &sched_ctrl->sched_pucch[2];
|
||||
NR_sched_pucch_t *csi_pucch = &sched_ctrl->sched_pucch[1];
|
||||
// skip the CSI PUCCH if it is present and if in the next frame/slot
|
||||
if (csi_pucch->csi_bits > 0
|
||||
&& csi_pucch->frame == pucch->frame
|
||||
@@ -1142,6 +1144,7 @@ bool nr_acknack_scheduling(int mod_id,
|
||||
pucch->ul_slot,
|
||||
UE_id);
|
||||
nr_fill_nfapi_pucch(mod_id, frame, slot, csi_pucch, UE_id);
|
||||
memset(csi_pucch, 0, sizeof(*csi_pucch));
|
||||
pucch->frame = s >= n_slots_frame - 2 ? (f + 1) % 1024 : f;
|
||||
pucch->ul_slot = (s + 2) % n_slots_frame;
|
||||
}
|
||||
@@ -1160,9 +1163,8 @@ bool nr_acknack_scheduling(int mod_id,
|
||||
uint8_t pdsch_to_harq_feedback[8];
|
||||
get_pdsch_to_harq_feedback(mod_id, UE_id, ss_type, pdsch_to_harq_feedback);
|
||||
|
||||
/* there is a scheduled SR or HARQ. Check whether we can use it for this
|
||||
* ACKNACK */
|
||||
if (pucch->sr_flag + pucch->dai_c > 0) {
|
||||
/* there is a HARQ. Check whether we can use it for this ACKNACK */
|
||||
if (pucch->dai_c > 0) {
|
||||
/* this UE already has a PUCCH occasion */
|
||||
DevAssert(pucch->frame == frame);
|
||||
|
||||
@@ -1193,18 +1195,14 @@ bool nr_acknack_scheduling(int mod_id,
|
||||
|
||||
/* we need to find a new PUCCH occasion */
|
||||
|
||||
NR_PUCCH_Config_t *pucch_Config = sched_ctrl->active_ubwp->bwp_Dedicated->pucch_Config->choice.setup;
|
||||
DevAssert(pucch_Config->resourceToAddModList->list.count > 0);
|
||||
DevAssert(pucch_Config->resourceSetToAddModList->list.count > 0);
|
||||
const int n_res = pucch_Config->resourceSetToAddModList->list.array[0]->resourceList.list.count;
|
||||
int *pucch_index_used = RC.nrmac[mod_id]->pucch_index_used[sched_ctrl->active_ubwp->bwp_Id];
|
||||
|
||||
/* if time information is outdated (e.g., last PUCCH occasion in last frame),
|
||||
* set to first possible UL occasion in this frame. Note that if such UE is
|
||||
* scheduled a lot and used all AckNacks, pucch->frame might have been
|
||||
* wrapped around to next frame */
|
||||
if (frame != pucch->frame || pucch->ul_slot < first_ul_slot_tdd) {
|
||||
DevAssert(pucch->sr_flag + pucch->dai_c == 0);
|
||||
AssertFatal(pucch->sr_flag + pucch->dai_c == 0,
|
||||
"expected no SR/AckNack for UE %d in %4d.%2d, but has %d/%d for %4d.%2d\n",
|
||||
UE_id, frame, slot, pucch->sr_flag, pucch->dai_c, pucch->frame, pucch->ul_slot);
|
||||
AssertFatal(frame + 1 != pucch->frame,
|
||||
"frame wrap around not handled in %s() yet\n",
|
||||
__func__);
|
||||
@@ -1212,27 +1210,11 @@ bool nr_acknack_scheduling(int mod_id,
|
||||
pucch->ul_slot = first_ul_slot_tdd;
|
||||
}
|
||||
|
||||
// increase to first slot in which PUCCH resources are available
|
||||
while (pucch_index_used[pucch->ul_slot] >= n_res) {
|
||||
pucch->ul_slot++;
|
||||
/* if there is no free resource anymore, abort search */
|
||||
if ((pucch->frame == frame
|
||||
&& pucch->ul_slot >= first_ul_slot_tdd + nr_ulmix_slots)
|
||||
|| (pucch->frame == frame + 1)) {
|
||||
LOG_E(MAC,
|
||||
"%4d.%2d no free PUCCH resources anymore while searching for UE %d\n",
|
||||
frame,
|
||||
slot,
|
||||
UE_id);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// advance ul_slot if it is not reachable by UE
|
||||
pucch->ul_slot = max(pucch->ul_slot, slot + pdsch_to_harq_feedback[0]);
|
||||
|
||||
// is there already CSI in this slot?
|
||||
const NR_sched_pucch_t *csi_pucch = &sched_ctrl->sched_pucch[2];
|
||||
NR_sched_pucch_t *csi_pucch = &sched_ctrl->sched_pucch[1];
|
||||
// skip the CSI PUCCH if it is present and if in the next frame/slot
|
||||
if (csi_pucch->csi_bits > 0
|
||||
&& csi_pucch->frame == pucch->frame
|
||||
@@ -1244,6 +1226,7 @@ bool nr_acknack_scheduling(int mod_id,
|
||||
pucch->ul_slot,
|
||||
UE_id);
|
||||
nr_fill_nfapi_pucch(mod_id, frame, slot, csi_pucch, UE_id);
|
||||
memset(csi_pucch, 0, sizeof(*csi_pucch));
|
||||
/* advance the UL slot information in PUCCH by one so we won't schedule in
|
||||
* the same slot again */
|
||||
const int f = pucch->frame;
|
||||
@@ -1274,29 +1257,19 @@ bool nr_acknack_scheduling(int mod_id,
|
||||
pucch->timing_indicator = i; // index in the list of timing indicators
|
||||
|
||||
pucch->dai_c++;
|
||||
const int pucch_res = pucch_index_used[pucch->ul_slot];
|
||||
pucch->resource_indicator = pucch_res;
|
||||
pucch_index_used[pucch->ul_slot] += 1;
|
||||
AssertFatal(pucch_index_used[pucch->ul_slot] <= n_res,
|
||||
"UE %d in %4d.%2d: pucch_index_used is %d (%d available)\n",
|
||||
UE_id,
|
||||
pucch->frame,
|
||||
pucch->ul_slot,
|
||||
pucch_index_used[pucch->ul_slot],
|
||||
n_res);
|
||||
pucch->resource_indicator = 0; // each UE has dedicated PUCCH resources
|
||||
|
||||
/* verify that at that slot and symbol, resources are free. We only do this
|
||||
* for initialCyclicShift 0 (we assume it always has that one), so other
|
||||
* initialCyclicShifts can overlap with ICS 0!*/
|
||||
const NR_PUCCH_Resource_t *resource =
|
||||
pucch_Config->resourceToAddModList->list.array[pucch_res];
|
||||
const NR_PUCCH_Config_t *pucch_Config = sched_ctrl->active_ubwp->bwp_Dedicated->pucch_Config->choice.setup;
|
||||
const NR_PUCCH_Resource_t *resource = pucch_Config->resourceToAddModList->list.array[pucch->resource_indicator];
|
||||
DevAssert(resource->format.present == NR_PUCCH_Resource__format_PR_format0);
|
||||
if (resource->format.choice.format0->initialCyclicShift == 0) {
|
||||
uint16_t *vrb_map_UL = &RC.nrmac[mod_id]->common_channels[CC_id].vrb_map_UL[pucch->ul_slot * MAX_BWP_SIZE];
|
||||
const uint16_t symb = 1 << resource->format.choice.format0->startingSymbolIndex;
|
||||
AssertFatal((vrb_map_UL[resource->startingPRB] & symb) == 0,
|
||||
"symbol %x is not free for PUCCH alloc in vrb_map_UL at RB %ld and slot %d\n",
|
||||
symb, resource->startingPRB, pucch->ul_slot);
|
||||
if ((vrb_map_UL[resource->startingPRB] & symb) != 0)
|
||||
LOG_W(MAC, "symbol 0x%x is not free for PUCCH alloc in vrb_map_UL at RB %ld and slot %d.%d\n", symb, resource->startingPRB, pucch->frame, pucch->ul_slot);
|
||||
vrb_map_UL[resource->startingPRB] |= symb;
|
||||
}
|
||||
return true;
|
||||
@@ -1429,3 +1402,154 @@ uint16_t compute_pucch_prb_size(uint8_t format,
|
||||
AssertFatal(1==0,"Not yet implemented");
|
||||
}
|
||||
}
|
||||
|
||||
void nr_sr_reporting(int Mod_idP, frame_t SFN, sub_frame_t slot)
|
||||
{
|
||||
gNB_MAC_INST *nrmac = RC.nrmac[Mod_idP];
|
||||
if (!is_xlsch_in_slot(nrmac->ulsch_slot_bitmap[slot / 64], slot))
|
||||
return;
|
||||
NR_ServingCellConfigCommon_t *scc = nrmac->common_channels->ServingCellConfigCommon;
|
||||
const int n_slots_frame = nr_slots_per_frame[*scc->ssbSubcarrierSpacing];
|
||||
NR_UE_info_t *UE_info = &nrmac->UE_info;
|
||||
NR_list_t *UE_list = &UE_info->list;
|
||||
for (int UE_id = UE_list->head; UE_id >= 0; UE_id = UE_list->next[UE_id]) {
|
||||
NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id];
|
||||
NR_PUCCH_Config_t *pucch_Config = sched_ctrl->active_ubwp->bwp_Dedicated->pucch_Config->choice.setup;
|
||||
AssertFatal(pucch_Config->schedulingRequestResourceToAddModList->list.count>0,"NO SR configuration available");
|
||||
|
||||
for (int SR_resource_id =0; SR_resource_id < pucch_Config->schedulingRequestResourceToAddModList->list.count;SR_resource_id++) {
|
||||
NR_SchedulingRequestResourceConfig_t *SchedulingRequestResourceConfig = pucch_Config->schedulingRequestResourceToAddModList->list.array[SR_resource_id];
|
||||
|
||||
int SR_period; int SR_offset;
|
||||
|
||||
periodicity__SRR(SchedulingRequestResourceConfig,&SR_period,&SR_offset);
|
||||
// convert to int to avoid underflow of uint
|
||||
int sfn_sf = SFN * n_slots_frame + slot;
|
||||
if ((sfn_sf - SR_offset) % SR_period != 0)
|
||||
continue;
|
||||
LOG_D(MAC, "%4d.%2d Scheduling Request identified\n", SFN, slot);
|
||||
NR_PUCCH_ResourceId_t *PucchResourceId = SchedulingRequestResourceConfig->resource;
|
||||
|
||||
int found = -1;
|
||||
NR_PUCCH_ResourceSet_t *pucchresset = pucch_Config->resourceSetToAddModList->list.array[0]; // set with formats 0,1
|
||||
int n_list = pucchresset->resourceList.list.count;
|
||||
for (int i=0; i<n_list; i++) {
|
||||
if (*pucchresset->resourceList.list.array[i] == *PucchResourceId )
|
||||
found = i;
|
||||
}
|
||||
AssertFatal(found>-1,"SR resource not found among PUCCH resources");
|
||||
|
||||
/* loop through nFAPI PUCCH messages: if the UEs is in there in this slot
|
||||
* with the resource_indicator, it means we already allocated that PUCCH
|
||||
* resource for AckNack (e.g., the UE has been scheduled often), and we
|
||||
* just need to add the SR_flag. Otherwise, just allocate in the internal
|
||||
* PUCCH resource, and nr_schedule_pucch() will handle the rest */
|
||||
NR_PUCCH_Resource_t *pucch_res = pucch_Config->resourceToAddModList->list.array[found];
|
||||
/* for the moment, can only handle SR on PUCCH Format 0 */
|
||||
DevAssert(pucch_res->format.present == NR_PUCCH_Resource__format_PR_format0);
|
||||
nfapi_nr_ul_tti_request_t *ul_tti_req = &nrmac->UL_tti_req_ahead[0][slot];
|
||||
bool nfapi_allocated = false;
|
||||
for (int i = 0; i < ul_tti_req->n_pdus; ++i) {
|
||||
if (ul_tti_req->pdus_list[i].pdu_type != NFAPI_NR_UL_CONFIG_PUCCH_PDU_TYPE)
|
||||
continue;
|
||||
nfapi_nr_pucch_pdu_t *pdu = &ul_tti_req->pdus_list[i].pucch_pdu;
|
||||
/* check that it is our PUCCH F0. Assuming there can be only one */
|
||||
if (pdu->rnti == UE_info->rnti[UE_id]
|
||||
&& pdu->format_type == 0 // does not use NR_PUCCH_Resource__format_PR_format0
|
||||
&& pdu->initial_cyclic_shift == pucch_res->format.choice.format0->initialCyclicShift
|
||||
&& pdu->nr_of_symbols == pucch_res->format.choice.format0->nrofSymbols
|
||||
&& pdu->start_symbol_index == pucch_res->format.choice.format0->startingSymbolIndex) {
|
||||
LOG_D(MAC,"%4d.%2d adding SR_flag 1 to PUCCH nFAPI SR for RNTI %04x\n", SFN, slot, pdu->rnti);
|
||||
pdu->sr_flag = 1;
|
||||
nfapi_allocated = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (nfapi_allocated) // break scheduling resource loop, continue next UE
|
||||
break;
|
||||
|
||||
/* we did not find it: check if current PUCCH is for the current slot, in
|
||||
* which case we add the SR to it; otherwise, allocate SR separately */
|
||||
NR_sched_pucch_t *curr_pucch = &sched_ctrl->sched_pucch[0];
|
||||
if (curr_pucch->frame == SFN && curr_pucch->ul_slot == slot) {
|
||||
if (curr_pucch->resource_indicator != found) {
|
||||
LOG_W(MAC, "%4d.%2d expected PUCCH in this slot to have resource indicator of SR (%d), skipping SR\n", SFN, slot, found);
|
||||
continue;
|
||||
}
|
||||
curr_pucch->sr_flag = true;
|
||||
} else {
|
||||
NR_sched_pucch_t sched_sr;
|
||||
memset(&sched_sr, 0, sizeof(sched_sr));
|
||||
sched_sr.frame = SFN;
|
||||
sched_sr.ul_slot = slot;
|
||||
sched_sr.resource_indicator = found;
|
||||
sched_sr.sr_flag = true;
|
||||
nr_fill_nfapi_pucch(Mod_idP, SFN, slot, &sched_sr, UE_id);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void periodicity__SRR (NR_SchedulingRequestResourceConfig_t *SchedulingReqRec, int *period, int *offset)
|
||||
{
|
||||
NR_SchedulingRequestResourceConfig__periodicityAndOffset_PR P_O = SchedulingReqRec->periodicityAndOffset->present;
|
||||
switch (P_O){
|
||||
case NR_SchedulingRequestResourceConfig__periodicityAndOffset_PR_sl1:
|
||||
*period = 1;
|
||||
*offset = SchedulingReqRec->periodicityAndOffset->choice.sl1;
|
||||
break;
|
||||
case NR_SchedulingRequestResourceConfig__periodicityAndOffset_PR_sl2:
|
||||
*period = 2;
|
||||
*offset = SchedulingReqRec->periodicityAndOffset->choice.sl2;
|
||||
break;
|
||||
case NR_SchedulingRequestResourceConfig__periodicityAndOffset_PR_sl4:
|
||||
*period = 4;
|
||||
*offset = SchedulingReqRec->periodicityAndOffset->choice.sl4;
|
||||
break;
|
||||
case NR_SchedulingRequestResourceConfig__periodicityAndOffset_PR_sl5:
|
||||
*period = 5;
|
||||
*offset = SchedulingReqRec->periodicityAndOffset->choice.sl5;
|
||||
break;
|
||||
case NR_SchedulingRequestResourceConfig__periodicityAndOffset_PR_sl8:
|
||||
*period = 8;
|
||||
*offset = SchedulingReqRec->periodicityAndOffset->choice.sl8;
|
||||
break;
|
||||
case NR_SchedulingRequestResourceConfig__periodicityAndOffset_PR_sl10:
|
||||
*period = 10;
|
||||
*offset = SchedulingReqRec->periodicityAndOffset->choice.sl10;
|
||||
break;
|
||||
case NR_SchedulingRequestResourceConfig__periodicityAndOffset_PR_sl16:
|
||||
*period = 16;
|
||||
*offset = SchedulingReqRec->periodicityAndOffset->choice.sl16;
|
||||
break;
|
||||
case NR_SchedulingRequestResourceConfig__periodicityAndOffset_PR_sl20:
|
||||
*period = 20;
|
||||
*offset = SchedulingReqRec->periodicityAndOffset->choice.sl20;
|
||||
break;
|
||||
case NR_SchedulingRequestResourceConfig__periodicityAndOffset_PR_sl40:
|
||||
*period = 40;
|
||||
*offset = SchedulingReqRec->periodicityAndOffset->choice.sl40;
|
||||
break;
|
||||
case NR_SchedulingRequestResourceConfig__periodicityAndOffset_PR_sl80:
|
||||
*period = 80;
|
||||
*offset = SchedulingReqRec->periodicityAndOffset->choice.sl80;
|
||||
break;
|
||||
case NR_SchedulingRequestResourceConfig__periodicityAndOffset_PR_sl160:
|
||||
*period = 160;
|
||||
*offset = SchedulingReqRec->periodicityAndOffset->choice.sl160;
|
||||
break;
|
||||
case NR_SchedulingRequestResourceConfig__periodicityAndOffset_PR_sl320:
|
||||
*period = 320;
|
||||
*offset = SchedulingReqRec->periodicityAndOffset->choice.sl320;
|
||||
break;
|
||||
case NR_SchedulingRequestResourceConfig__periodicityAndOffset_PR_sl640:
|
||||
*period = 640;
|
||||
*offset = SchedulingReqRec->periodicityAndOffset->choice.sl640;
|
||||
break;
|
||||
default:
|
||||
AssertFatal(1==0,"No periodicityAndOffset resources found in schedulingrequestresourceconfig");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -745,6 +745,34 @@ long get_K2(const NR_BWP_Uplink_t *ubwp, int time_domain_assignment, int mu) {
|
||||
return 3;
|
||||
}
|
||||
|
||||
bool nr_UE_is_to_be_scheduled(module_id_t mod_id, int CC_id, int UE_id, frame_t frame, sub_frame_t slot)
|
||||
{
|
||||
const NR_ServingCellConfigCommon_t *scc = RC.nrmac[mod_id]->common_channels->ServingCellConfigCommon;
|
||||
const uint8_t slots_per_frame[5] = {10, 20, 40, 80, 160};
|
||||
const int n = slots_per_frame[*scc->ssbSubcarrierSpacing];
|
||||
const int now = frame * n + slot;
|
||||
|
||||
const struct gNB_MAC_INST_s *nrmac = RC.nrmac[mod_id];
|
||||
const NR_UE_sched_ctrl_t *sched_ctrl = &nrmac->UE_info.UE_sched_ctrl[UE_id];
|
||||
const int last_ul_sched = sched_ctrl->last_ul_frame * n + sched_ctrl->last_ul_slot;
|
||||
|
||||
const int diff = (now - last_ul_sched + 1024 * n) % (1024 * n);
|
||||
/* UE is to be scheduled if
|
||||
* (1) we think the UE has more bytes awaiting than what we scheduled
|
||||
* (2) there is a scheduling request
|
||||
* (3) or we did not schedule it in more than 10 frames */
|
||||
const bool has_data = sched_ctrl->estimated_ul_buffer > sched_ctrl->sched_ul_bytes;
|
||||
const bool high_inactivity = diff >= nrmac->ulsch_max_slots_inactivity;
|
||||
LOG_D(MAC,
|
||||
"%4d.%2d UL inactivity %d slots has_data %d SR %d\n",
|
||||
frame,
|
||||
slot,
|
||||
diff,
|
||||
has_data,
|
||||
sched_ctrl->SR);
|
||||
return has_data || sched_ctrl->SR || high_inactivity;
|
||||
}
|
||||
|
||||
int next_list_entry_looped(NR_list_t *list, int UE_id)
|
||||
{
|
||||
if (UE_id < 0)
|
||||
@@ -874,7 +902,6 @@ void update_ul_ue_R_Qm(NR_sched_pusch_t *sched_pusch, const NR_pusch_semi_static
|
||||
|
||||
float ul_thr_ue[MAX_MOBILES_PER_GNB];
|
||||
uint32_t ul_pf_tbs[3][28]; // pre-computed, approximate TBS values for PF coefficient
|
||||
int bsr0ue = -1;
|
||||
void pf_ul(module_id_t module_id,
|
||||
frame_t frame,
|
||||
sub_frame_t slot,
|
||||
@@ -894,12 +921,6 @@ void pf_ul(module_id_t module_id,
|
||||
int ue_array[MAX_MOBILES_PER_GNB];
|
||||
NR_list_t UE_sched = { .head = -1, .next = ue_array, .tail = -1, .len = MAX_MOBILES_PER_GNB };
|
||||
|
||||
/* Hack: currently, we do not have SR, and need to schedule UEs continuously.
|
||||
* To keep the wasted resources low, we switch UEs to be scheduled in a
|
||||
* round-robin fashion below, and only schedule a UE with BSR=0 if it is the
|
||||
* selected one */
|
||||
bsr0ue = next_list_entry_looped(UE_list, bsr0ue);
|
||||
|
||||
/* Loop UE_list to calculate throughput and coeff */
|
||||
for (int UE_id = UE_list->head; UE_id >= 0; UE_id = UE_list->next[UE_id]) {
|
||||
NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id];
|
||||
@@ -931,11 +952,16 @@ void pf_ul(module_id_t module_id,
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Check BSR and schedule UE if it is zero to avoid starvation, since we do
|
||||
* not have SR (yet) */
|
||||
if (sched_ctrl->estimated_ul_buffer - sched_ctrl->sched_ul_bytes <= 0) {
|
||||
if (UE_id != bsr0ue)
|
||||
continue;
|
||||
const int B = max(0, sched_ctrl->estimated_ul_buffer - sched_ctrl->sched_ul_bytes);
|
||||
/* preprocessor computed sched_frame/sched_slot */
|
||||
const bool do_sched = nr_UE_is_to_be_scheduled(module_id, 0, UE_id, sched_pusch->frame, sched_pusch->slot);
|
||||
|
||||
if (B == 0 && !do_sched)
|
||||
continue;
|
||||
|
||||
/* Schedule UE on SR or UL inactivity and no data (otherwise, will be scheduled
|
||||
* based on data to transmit) */
|
||||
if (B == 0 && do_sched) {
|
||||
/* if no data, pre-allocate 5RB */
|
||||
bool freeCCE = find_free_CCE(module_id, slot, UE_id);
|
||||
if (!freeCCE) {
|
||||
@@ -1106,7 +1132,7 @@ bool nr_fr1_ulsch_preprocessor(module_id_t module_id, frame_t frame, sub_frame_t
|
||||
int K2 = get_K2(sched_ctrl->active_ubwp, tda, mu);
|
||||
const int sched_frame = frame + (slot + K2 >= nr_slots_per_frame[mu]);
|
||||
const int sched_slot = (slot + K2) % nr_slots_per_frame[mu];
|
||||
if (!is_xlsch_in_slot(nr_mac->ulsch_slot_bitmap[slot / 64], sched_slot))
|
||||
if (!is_xlsch_in_slot(nr_mac->ulsch_slot_bitmap[sched_slot / 64], sched_slot))
|
||||
return false;
|
||||
|
||||
sched_ctrl->sched_pusch.slot = sched_slot;
|
||||
@@ -1218,6 +1244,7 @@ void nr_schedule_ulsch(module_id_t module_id, frame_t frame, sub_frame_t slot)
|
||||
for (int UE_id = UE_list->head; UE_id >= 0; UE_id = UE_list->next[UE_id]) {
|
||||
NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id];
|
||||
UE_info->mac_stats[UE_id].ulsch_current_bytes = 0;
|
||||
|
||||
/* dynamic PUSCH values (RB alloc, MCS, hence R, Qm, TBS) that change in
|
||||
* every TTI are pre-populated by the preprocessor and used below */
|
||||
NR_sched_pusch_t *sched_pusch = &sched_ctrl->sched_pusch;
|
||||
@@ -1225,6 +1252,7 @@ void nr_schedule_ulsch(module_id_t module_id, frame_t frame, sub_frame_t slot)
|
||||
continue;
|
||||
|
||||
uint16_t rnti = UE_info->rnti[UE_id];
|
||||
sched_ctrl->SR = false;
|
||||
|
||||
int8_t harq_id = sched_pusch->ul_harq_pid;
|
||||
if (harq_id < 0) {
|
||||
@@ -1281,6 +1309,8 @@ void nr_schedule_ulsch(module_id_t module_id, frame_t frame, sub_frame_t slot)
|
||||
cur_harq->ndi);
|
||||
}
|
||||
UE_info->mac_stats[UE_id].ulsch_current_bytes = sched_pusch->tb_size;
|
||||
sched_ctrl->last_ul_frame = sched_pusch->frame;
|
||||
sched_ctrl->last_ul_slot = sched_pusch->slot;
|
||||
|
||||
LOG_D(MAC,
|
||||
"%4d.%2d RNTI %04x UL sched %4d.%2d start %2d RBS %3d startSymbol %2d nb_symbol %2d MCS %2d TBS %4d HARQ PID %2d round %d NDI %d est %6d sched %6d est BSR %6d\n",
|
||||
|
||||
@@ -414,4 +414,10 @@ bool nr_find_nb_rb(uint16_t Qm,
|
||||
uint32_t *tbs,
|
||||
uint16_t *nb_rb);
|
||||
|
||||
void nr_sr_reporting(int Mod_idP, frame_t frameP, sub_frame_t slotP);
|
||||
|
||||
void periodicity__SRR (NR_SchedulingRequestResourceConfig_t *SchedulingReqRecconf,
|
||||
int *period,
|
||||
int *offset);
|
||||
|
||||
#endif /*__LAYER2_NR_MAC_PROTO_H__*/
|
||||
|
||||
@@ -522,11 +522,9 @@ typedef struct {
|
||||
int cce_index;
|
||||
uint8_t aggregation_level;
|
||||
|
||||
/// PUCCH scheduling information. Array of three, we assume for the moment:
|
||||
/// HARQ in the first field, SR in second, CSI in third (as fixed by RRC
|
||||
/// conf., i.e. if actually present). The order is important for
|
||||
/// nr_acknack_scheduling()!
|
||||
NR_sched_pucch_t sched_pucch[3];
|
||||
/// PUCCH scheduling information. Array of two: HARQ+SR in the first field,
|
||||
/// CSI in second. This order is important for nr_acknack_scheduling()!
|
||||
NR_sched_pucch_t sched_pucch[2];
|
||||
|
||||
/// PUSCH semi-static configuration: is not cleared across TTIs
|
||||
NR_pusch_semi_static_t pusch_semi_static;
|
||||
@@ -547,6 +545,9 @@ typedef struct {
|
||||
NR_pdsch_semi_static_t pdsch_semi_static;
|
||||
/// Sched PDSCH: scheduling decisions, copied into HARQ and cleared every TTI
|
||||
NR_sched_pdsch_t sched_pdsch;
|
||||
/// For UL synchronization: store last UL scheduling grant
|
||||
frame_t last_ul_frame;
|
||||
sub_frame_t last_ul_slot;
|
||||
|
||||
/// total amount of data awaiting for this UE
|
||||
uint32_t num_total_bytes;
|
||||
@@ -563,6 +564,8 @@ typedef struct {
|
||||
int pucch_snrx10;
|
||||
|
||||
struct CSI_Report CSI_report[MAX_CSI_REPORTS];
|
||||
bool SR;
|
||||
|
||||
/// information about every HARQ process
|
||||
NR_UE_harq_t harq_processes[NR_MAX_NB_HARQ_PROCESSES];
|
||||
/// HARQ processes that are free
|
||||
@@ -705,10 +708,6 @@ typedef struct gNB_MAC_INST_s {
|
||||
int cce_list[MAX_NUM_BWP][MAX_NUM_CORESET][MAX_NUM_CCE];
|
||||
/// list of allocated beams per period
|
||||
int16_t *tdd_beam_association;
|
||||
/// PUCCH: keep track of the resources has already been used by saving the
|
||||
/// highest index not yet been used in a given slot. Dynamically allocated
|
||||
/// so we can have it for every slot as a function of the numerology
|
||||
int *pucch_index_used[MAX_NUM_BWP];
|
||||
|
||||
/// bitmap of DLSCH slots, can hold up to 160 slots
|
||||
uint64_t dlsch_slot_bitmap[3];
|
||||
@@ -722,6 +721,9 @@ typedef struct gNB_MAC_INST_s {
|
||||
/// points to the right UL slot
|
||||
int *preferred_ul_tda[MAX_NUM_BWP];
|
||||
|
||||
/// maximum number of slots before a UE will be scheduled ULSCH automatically
|
||||
uint32_t ulsch_max_slots_inactivity;
|
||||
|
||||
/// DL preprocessor for differentiated scheduling
|
||||
nr_pp_impl_dl pre_processor_dl;
|
||||
/// UL preprocessor for differentiated scheduling
|
||||
|
||||
@@ -73,7 +73,8 @@ void nr_rlc_bearer_init_ul_spec(struct NR_LogicalChannelConfig *mac_LogicalChann
|
||||
|
||||
mac_LogicalChannelConfig->ul_SpecificParameters->logicalChannelGroup = calloc(1,sizeof(*mac_LogicalChannelConfig->ul_SpecificParameters->logicalChannelGroup));
|
||||
*mac_LogicalChannelConfig->ul_SpecificParameters->logicalChannelGroup = 1;
|
||||
mac_LogicalChannelConfig->ul_SpecificParameters->schedulingRequestID = NULL;
|
||||
mac_LogicalChannelConfig->ul_SpecificParameters->schedulingRequestID = calloc(1,sizeof(*mac_LogicalChannelConfig->ul_SpecificParameters->schedulingRequestID));
|
||||
*mac_LogicalChannelConfig->ul_SpecificParameters->schedulingRequestID = 0;
|
||||
mac_LogicalChannelConfig->ul_SpecificParameters->logicalChannelSR_Mask = false;
|
||||
mac_LogicalChannelConfig->ul_SpecificParameters->logicalChannelSR_DelayTimerApplied = false;
|
||||
mac_LogicalChannelConfig->ul_SpecificParameters->bitRateQueryProhibitTimer = NULL;
|
||||
|
||||
@@ -105,10 +105,6 @@ void handle_nr_uci(NR_UL_IND_t *UL_info)
|
||||
}
|
||||
|
||||
UL_info->uci_ind.num_ucis = 0;
|
||||
|
||||
// mark corresponding PUCCH resources as free
|
||||
// NOTE: we just assume it is BWP ID 1, to be revised for multiple BWPs
|
||||
RC.nrmac[mod_id]->pucch_index_used[1][slot] = 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1287,7 +1287,8 @@ uint16_t do_RRCReconfiguration(
|
||||
// 1,
|
||||
// 1,
|
||||
// carrier->pdsch_AntennaPorts,
|
||||
// carrier->initial_csi_index[gnb_rrc_inst->Nb_ue]);
|
||||
// carrier->initial_csi_index[ue_context_p->local_uid + 1],
|
||||
// ue_context_pP->local_uid);
|
||||
|
||||
/******************** Meas Config ********************/
|
||||
// measConfig
|
||||
|
||||
@@ -85,14 +85,16 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco
|
||||
int scg_id,
|
||||
int servCellIndex,
|
||||
int n_physical_antenna_ports,
|
||||
int initial_csi_index);
|
||||
int initial_csi_index,
|
||||
int uid);
|
||||
|
||||
void fill_default_reconfig(NR_ServingCellConfigCommon_t *servingcellconfigcommon,
|
||||
NR_ServingCellConfig_t *servingcellconfigdedicated,
|
||||
NR_RRCReconfiguration_IEs_t *reconfig,
|
||||
NR_CellGroupConfig_t *secondaryCellGroup,
|
||||
int n_physical_antenna_ports,
|
||||
int initial_csi_index);
|
||||
int initial_csi_index,
|
||||
int uid);
|
||||
|
||||
void fill_default_rbconfig(NR_RadioBearerConfig_t *rbconfig,
|
||||
int eps_bearer_id, int rb_id,
|
||||
|
||||
@@ -152,7 +152,7 @@ void rrc_add_nsa_user(gNB_RRC_INST *rrc,struct rrc_gNB_ue_context_s *ue_context_
|
||||
ue_context_p->ue_context.reconfig->criticalExtensions.present = NR_RRCReconfiguration__criticalExtensions_PR_rrcReconfiguration;
|
||||
NR_RRCReconfiguration_IEs_t *reconfig_ies=calloc(1,sizeof(NR_RRCReconfiguration_IEs_t));
|
||||
ue_context_p->ue_context.reconfig->criticalExtensions.choice.rrcReconfiguration = reconfig_ies;
|
||||
carrier->initial_csi_index[rrc->Nb_ue] = 0;
|
||||
carrier->initial_csi_index[ue_context_p->local_uid + 1] = 0;
|
||||
ue_context_p->ue_context.rb_config = calloc(1,sizeof(NR_RRCReconfiguration_t));
|
||||
if (get_softmodem_params()->phy_test == 1 || get_softmodem_params()->do_ra == 1 || get_softmodem_params()->sa == 1){
|
||||
fill_default_rbconfig(ue_context_p->ue_context.rb_config,
|
||||
@@ -245,14 +245,16 @@ void rrc_add_nsa_user(gNB_RRC_INST *rrc,struct rrc_gNB_ue_context_s *ue_context_
|
||||
reconfig_ies,
|
||||
ue_context_p->ue_context.secondaryCellGroup,
|
||||
carrier->pdsch_AntennaPorts,
|
||||
carrier->initial_csi_index[rrc->Nb_ue]);
|
||||
carrier->initial_csi_index[ue_context_p->local_uid + 1],
|
||||
ue_context_p->local_uid);
|
||||
} else {
|
||||
fill_default_reconfig(carrier->servingcellconfigcommon,
|
||||
NULL,
|
||||
reconfig_ies,
|
||||
ue_context_p->ue_context.secondaryCellGroup,
|
||||
carrier->pdsch_AntennaPorts,
|
||||
carrier->initial_csi_index[rrc->Nb_ue]);
|
||||
carrier->initial_csi_index[ue_context_p->local_uid + 1],
|
||||
ue_context_p->local_uid);
|
||||
}
|
||||
ue_context_p->ue_id_rnti = ue_context_p->ue_context.secondaryCellGroup->spCellConfig->reconfigurationWithSync->newUE_Identity;
|
||||
NR_CG_Config_t *CG_Config = calloc(1,sizeof(*CG_Config));
|
||||
|
||||
@@ -149,7 +149,8 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco
|
||||
int scg_id,
|
||||
int servCellIndex,
|
||||
int n_physical_antenna_ports,
|
||||
int initial_csi_index) {
|
||||
int initial_csi_index,
|
||||
int uid) {
|
||||
AssertFatal(servingcellconfigcommon!=NULL,"servingcellconfigcommon is null\n");
|
||||
AssertFatal(secondaryCellGroup!=NULL,"secondaryCellGroup is null\n");
|
||||
|
||||
@@ -184,7 +185,17 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco
|
||||
ASN_SEQUENCE_ADD(&secondaryCellGroup->rlc_BearerToAddModList->list, RLC_BearerConfig);
|
||||
secondaryCellGroup->mac_CellGroupConfig=calloc(1,sizeof(*secondaryCellGroup->mac_CellGroupConfig));
|
||||
secondaryCellGroup->mac_CellGroupConfig->drx_Config = NULL;
|
||||
secondaryCellGroup->mac_CellGroupConfig->schedulingRequestConfig = NULL;
|
||||
|
||||
secondaryCellGroup->mac_CellGroupConfig->schedulingRequestConfig = calloc(1,sizeof(*secondaryCellGroup->mac_CellGroupConfig->schedulingRequestConfig));
|
||||
secondaryCellGroup->mac_CellGroupConfig->schedulingRequestConfig->schedulingRequestToAddModList = calloc(1,sizeof(*secondaryCellGroup->mac_CellGroupConfig->schedulingRequestConfig->schedulingRequestToAddModList));
|
||||
NR_SchedulingRequestToAddMod_t *SchedulingRequestConf = calloc(1,sizeof(*SchedulingRequestConf));
|
||||
SchedulingRequestConf->schedulingRequestId = 0; //Could be changed
|
||||
SchedulingRequestConf->sr_ProhibitTimer = calloc(1,sizeof(*SchedulingRequestConf->sr_ProhibitTimer));
|
||||
*SchedulingRequestConf->sr_ProhibitTimer = NR_SchedulingRequestToAddMod__sr_ProhibitTimer_ms16;
|
||||
SchedulingRequestConf->sr_TransMax = NR_SchedulingRequestToAddMod__sr_TransMax_n32;
|
||||
ASN_SEQUENCE_ADD(&secondaryCellGroup->mac_CellGroupConfig->schedulingRequestConfig->schedulingRequestToAddModList->list,SchedulingRequestConf);
|
||||
secondaryCellGroup->mac_CellGroupConfig->schedulingRequestConfig->schedulingRequestToReleaseList = NULL;
|
||||
|
||||
secondaryCellGroup->mac_CellGroupConfig->bsr_Config=calloc(1,sizeof(*secondaryCellGroup->mac_CellGroupConfig->bsr_Config));
|
||||
secondaryCellGroup->mac_CellGroupConfig->bsr_Config->periodicBSR_Timer = NR_BSR_Config__periodicBSR_Timer_sf10;
|
||||
secondaryCellGroup->mac_CellGroupConfig->bsr_Config->retxBSR_Timer = NR_BSR_Config__retxBSR_Timer_sf160;
|
||||
@@ -251,7 +262,7 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco
|
||||
if ((bitmap>>(63-i))&0x01){
|
||||
ssbElem[n_ssb] = calloc(1,sizeof(struct NR_CFRA_SSB_Resource));
|
||||
ssbElem[n_ssb]->ssb = i;
|
||||
ssbElem[n_ssb]->ra_PreambleIndex = 63;
|
||||
ssbElem[n_ssb]->ra_PreambleIndex = 63 - (uid % 64);
|
||||
ASN_SEQUENCE_ADD(&secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink->cfra->resources.choice.ssb->ssb_ResourceList.list,ssbElem[n_ssb]);
|
||||
n_ssb++;
|
||||
}
|
||||
@@ -263,8 +274,8 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco
|
||||
secondaryCellGroup->spCellConfig->rlf_TimersAndConstants = calloc(1,sizeof(*secondaryCellGroup->spCellConfig->rlf_TimersAndConstants));
|
||||
secondaryCellGroup->spCellConfig->rlf_TimersAndConstants->present = NR_SetupRelease_RLF_TimersAndConstants_PR_setup;
|
||||
secondaryCellGroup->spCellConfig->rlf_TimersAndConstants->choice.setup=calloc(1,sizeof(*secondaryCellGroup->spCellConfig->rlf_TimersAndConstants->choice.setup));
|
||||
secondaryCellGroup->spCellConfig->rlf_TimersAndConstants->choice.setup->t310 = NR_RLF_TimersAndConstants__t310_ms2000;
|
||||
secondaryCellGroup->spCellConfig->rlf_TimersAndConstants->choice.setup->n310 = NR_RLF_TimersAndConstants__n310_n10;
|
||||
secondaryCellGroup->spCellConfig->rlf_TimersAndConstants->choice.setup->t310 = NR_RLF_TimersAndConstants__t310_ms4000;
|
||||
secondaryCellGroup->spCellConfig->rlf_TimersAndConstants->choice.setup->n310 = NR_RLF_TimersAndConstants__n310_n20;
|
||||
secondaryCellGroup->spCellConfig->rlf_TimersAndConstants->choice.setup->n311 = NR_RLF_TimersAndConstants__n311_n1;
|
||||
secondaryCellGroup->spCellConfig->rlf_TimersAndConstants->choice.setup->ext1 = calloc(1,sizeof(*secondaryCellGroup->spCellConfig->rlf_TimersAndConstants->choice.setup->ext1));
|
||||
secondaryCellGroup->spCellConfig->rlf_TimersAndConstants->choice.setup->ext1->t311 = NR_RLF_TimersAndConstants__ext1__t311_ms30000;
|
||||
@@ -975,7 +986,7 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco
|
||||
NR_PUCCH_Resource_t *pucchres2=calloc(1,sizeof(*pucchres2));
|
||||
NR_PUCCH_Resource_t *pucchres3=calloc(1,sizeof(*pucchres3));
|
||||
pucchres0->pucch_ResourceId=1;
|
||||
pucchres0->startingPRB=8;
|
||||
pucchres0->startingPRB= (8 + uid) % curr_bwp;
|
||||
pucchres0->intraSlotFrequencyHopping=NULL;
|
||||
pucchres0->secondHopPRB=NULL;
|
||||
pucchres0->format.present= NR_PUCCH_Resource__format_PR_format0;
|
||||
@@ -986,7 +997,7 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco
|
||||
ASN_SEQUENCE_ADD(&pucch_Config->resourceToAddModList->list,pucchres0);
|
||||
|
||||
pucchres1->pucch_ResourceId=2;
|
||||
pucchres1->startingPRB=8;
|
||||
pucchres1->startingPRB= (8 + uid) % curr_bwp;
|
||||
pucchres1->intraSlotFrequencyHopping=NULL;
|
||||
pucchres1->secondHopPRB=NULL;
|
||||
pucchres1->format.present= NR_PUCCH_Resource__format_PR_format0;
|
||||
@@ -1029,7 +1040,19 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco
|
||||
pucchfmt2->nrofSlots=NULL;
|
||||
pucchfmt2->pi2BPSK=NULL;
|
||||
pucchfmt2->simultaneousHARQ_ACK_CSI=NULL;
|
||||
pucch_Config->schedulingRequestResourceToAddModList=NULL;
|
||||
|
||||
// for scheduling requestresource
|
||||
pucch_Config->schedulingRequestResourceToAddModList = calloc(1,sizeof(*pucch_Config->schedulingRequestResourceToAddModList));
|
||||
NR_SchedulingRequestResourceConfig_t *schedulingRequestResourceConfig = calloc(1,sizeof(*schedulingRequestResourceConfig));
|
||||
schedulingRequestResourceConfig->schedulingRequestResourceId = 1;
|
||||
schedulingRequestResourceConfig->schedulingRequestID = 0;
|
||||
schedulingRequestResourceConfig->periodicityAndOffset = calloc(1,sizeof(*schedulingRequestResourceConfig->periodicityAndOffset));
|
||||
schedulingRequestResourceConfig->periodicityAndOffset->present = NR_SchedulingRequestResourceConfig__periodicityAndOffset_PR_sl10;
|
||||
schedulingRequestResourceConfig->periodicityAndOffset->choice.sl10 = 7;
|
||||
schedulingRequestResourceConfig->resource = calloc(1,sizeof(*schedulingRequestResourceConfig->resource));
|
||||
*schedulingRequestResourceConfig->resource = 1;
|
||||
ASN_SEQUENCE_ADD(&pucch_Config->schedulingRequestResourceToAddModList->list,schedulingRequestResourceConfig);
|
||||
|
||||
pucch_Config->schedulingRequestResourceToReleaseList=NULL;
|
||||
pucch_Config->multi_CSI_PUCCH_ResourceList=NULL;
|
||||
pucch_Config->dl_DataToUL_ACK = calloc(1,sizeof(*pucch_Config->dl_DataToUL_ACK));
|
||||
@@ -1177,7 +1200,7 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco
|
||||
csirep1->reportConfigType.present = NR_CSI_ReportConfig__reportConfigType_PR_periodic;
|
||||
csirep1->reportConfigType.choice.periodic = calloc(1,sizeof(*csirep1->reportConfigType.choice.periodic));
|
||||
csirep1->reportConfigType.choice.periodic->reportSlotConfig.present=NR_CSI_ReportPeriodicityAndOffset_PR_slots320;
|
||||
csirep1->reportConfigType.choice.periodic->reportSlotConfig.choice.slots320 = 49;
|
||||
csirep1->reportConfigType.choice.periodic->reportSlotConfig.choice.slots320 = 9 + (10 * uid) % 320;
|
||||
NR_PUCCH_CSI_Resource_t *pucchcsires1 = calloc(1,sizeof(*pucchcsires1));
|
||||
pucchcsires1->uplinkBandwidthPartId=1;
|
||||
pucchcsires1->pucch_Resource=3;
|
||||
@@ -1241,14 +1264,22 @@ void fill_default_reconfig(NR_ServingCellConfigCommon_t *servingcellconfigcommon
|
||||
NR_RRCReconfiguration_IEs_t *reconfig,
|
||||
NR_CellGroupConfig_t *secondaryCellGroup,
|
||||
int n_physical_antenna_ports,
|
||||
int initial_csi_index) {
|
||||
int initial_csi_index,
|
||||
int uid) {
|
||||
AssertFatal(servingcellconfigcommon!=NULL,"servingcellconfigcommon is null\n");
|
||||
AssertFatal(reconfig!=NULL,"reconfig is null\n");
|
||||
AssertFatal(secondaryCellGroup!=NULL,"secondaryCellGroup is null\n");
|
||||
// radioBearerConfig
|
||||
reconfig->radioBearerConfig=NULL;
|
||||
// secondaryCellGroup
|
||||
fill_default_secondaryCellGroup(servingcellconfigcommon,servingcellconfigdedicated,secondaryCellGroup,1,1,n_physical_antenna_ports,initial_csi_index);
|
||||
fill_default_secondaryCellGroup(servingcellconfigcommon,
|
||||
servingcellconfigdedicated,
|
||||
secondaryCellGroup,
|
||||
1,
|
||||
1,
|
||||
n_physical_antenna_ports,
|
||||
initial_csi_index,
|
||||
uid);
|
||||
xer_fprint(stdout, &asn_DEF_NR_CellGroupConfig, (const void*)secondaryCellGroup);
|
||||
|
||||
char scg_buffer[1024];
|
||||
|
||||
@@ -130,6 +130,18 @@ void x2ap_eNB_handle_sctp_association_resp(instance_t instance, sctp_new_associa
|
||||
DevAssert(x2ap_enb_data_p != NULL);
|
||||
dump_trees();
|
||||
|
||||
/* gNB: exit if connection to eNB failed - to be modified if needed.
|
||||
* We may want to try to connect over and over again until we succeed
|
||||
* but the modifications to the code to get this behavior are complex.
|
||||
* Exit on error is a simple solution that can be caught by a script
|
||||
* for example.
|
||||
*/
|
||||
if (instance_p->cell_type == CELL_MACRO_GNB
|
||||
&& sctp_new_association_resp->sctp_state == SCTP_STATE_UNREACHABLE) {
|
||||
X2AP_ERROR("association with eNB failed, is it running? If no, run it first. If yes, check IP addresses in your configuration file.\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (sctp_new_association_resp->sctp_state != SCTP_STATE_ESTABLISHED) {
|
||||
X2AP_WARN("Received unsuccessful result for SCTP association (%u), instance %ld, cnx_id %u\n",
|
||||
sctp_new_association_resp->sctp_state,
|
||||
|
||||
Reference in New Issue
Block a user