Commit 82ba8ab0 authored by francescomani's avatar francescomani

Merge remote-tracking branch 'origin/develop' into pdsch_semistatic_fixes

parents 10aee35f a7229937
......@@ -220,6 +220,21 @@ pipeline {
}
}
}
stage ("Images Push to Registries") {
when { expression {"PUSH".equals(env.gitlabActionType)} }
steps {
script {
triggerSlaveJob ('RAN-DockerHub-Push', 'Push-to-Docker-Hub')
}
post {
failure {
script {
currentBuild.result = 'FAILURE'
}
}
}
}
}
}
post {
always {
......
......@@ -503,6 +503,29 @@ pipeline {
}
}
}
stage ("Test F1 - FDD - Band 7 - B210") {
when {
expression {doFullTestsuite}
}
steps {
script {
sh "sleep 60"
triggerSlaveJob ('eNB-CI-F1-FDD-Band7-B210', 'Test-F1-FDD-Band7')
}
}
post {
always {
script {
finalizeSlaveJob('eNB-CI-F1-FDD-Band7-B210')
}
}
failure {
script {
currentBuild.result = 'FAILURE'
}
}
}
}
stage ("Test IF4p5 - TDD - Band 40 - B210") {
when {
expression {doFullTestsuite}
......
#!/bin/groovy
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
......@@ -19,57 +20,67 @@
* contact@openairinterface.org
*/
#include "nr_pdcp_entity_srb.h"
// Location of the python executor node shall be in the same subnet as the others servers
def nodeExecutor = params.nodeExecutor
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// Name of the phone resource
def ciServerResource = params.serverResource
void nr_pdcp_entity_srb_recv_pdu(nr_pdcp_entity_t *_entity, char *buffer, int size)
{
nr_pdcp_entity_srb_t *entity = (nr_pdcp_entity_srb_t *)_entity;
if (size < 2) abort();
entity->common.deliver_sdu(entity->common.deliver_sdu_data,
(nr_pdcp_entity_t *)entity, buffer+2, size-6);
}
void nr_pdcp_entity_srb_recv_sdu(nr_pdcp_entity_t *_entity, char *buffer, int size,
int sdu_id)
{
nr_pdcp_entity_srb_t *entity = (nr_pdcp_entity_srb_t *)_entity;
int sn;
char buf[size+6];
sn = entity->common.next_nr_pdcp_tx_sn;
entity->common.next_nr_pdcp_tx_sn++;
if (entity->common.next_nr_pdcp_tx_sn > entity->common.maximum_nr_pdcp_sn) {
entity->common.next_nr_pdcp_tx_sn = 0;
entity->common.tx_hfn++;
pipeline {
agent {
label nodeExecutor
}
options {
disableConcurrentBuilds()
ansiColor('xterm')
lock (ciServerResource)
}
stages {
stage ("Verify Parameters") {
steps {
script {
echo '\u2705 \u001B[32mVerify Parameters\u001B[0m'
def allParametersPresent = true
buf[0] = (sn >> 8) & 0x0f;
buf[1] = sn & 0xff;
memcpy(buf+2, buffer, size);
/* For now use padding for the MAC-I bytes (normally carrying message authentication code)
* which come after the data payload bytes (38.323, section 6.2.2.1) */
for (int i=size+2; i<size+6; i++)
buf[i] = 0x11*(i-size-1);
entity->common.deliver_pdu(entity->common.deliver_pdu_data,
(nr_pdcp_entity_t *)entity, buf, size+6, sdu_id);
}
void nr_pdcp_entity_srb_set_integrity_key(nr_pdcp_entity_t *_entity, char *key)
{
/* nothing to do */
}
// It is already to late to check it
if (params.nodeExecutor != null) {
echo "Docker Push executor node : ${nodeExecutor}"
}
if (params.serverResource == null) {
allParametersPresent = false
}
}
}
}
stage ("Push to DockerHub") {
steps {
script {
WEEK_TAG = sh returnStdout: true, script: 'date +"%Y.w%U"'
WEEK_TAG = WEEK_TAG.trim()
void nr_pdcp_entity_srb_delete(nr_pdcp_entity_t *_entity)
{
nr_pdcp_entity_srb_t *entity = (nr_pdcp_entity_srb_t *)_entity;
free(entity);
withCredentials([
[$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.DH_Credentials}", usernameVariable: 'DH_Username', passwordVariable: 'DH_Password']
]) {
def listOfImages = ["oai-enb", "oai-gnb", "oai-lte-ue", "oai-nr-ue"]
sh "docker login -u ${DH_Username} -p ${DH_Password} > /dev/null 2>&1"
listOfImages.eachWithIndex { item, iindex ->
sh "docker image tag ${item}:develop ${DH_Username}/${item}:develop"
sh "docker image tag ${item}:develop ${DH_Username}/${item}:${WEEK_TAG}"
sh "docker push --quiet ${DH_Username}/${item}:${WEEK_TAG}"
sh "docker push --quiet ${DH_Username}/${item}:develop"
sh "docker rmi ${DH_Username}/${item}:${WEEK_TAG} ${DH_Username}/${item}:develop"
}
sh "docker logout > /dev/null 2>&1"
}
}
}
}
}
post {
always {
script {
echo "End of Registry Push"
}
}
}
}
......@@ -265,6 +265,21 @@ pipeline {
if(fileExists("enb.log.${env.BUILD_ID}.zip")) {
archiveArtifacts "enb.log.${env.BUILD_ID}.zip"
}
}
}
}
stage('Log Collection (CN)') {
steps {
withCredentials([
[$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.EPC_Credentials}", usernameVariable: 'EPC_Username', passwordVariable: 'EPC_Password']
]) {
echo '\u2705 \u001B[32mLog Transfer (CN)\u001B[0m'
sh "sshpass -p \'${EPC_Password}\' scp -o 'StrictHostKeyChecking no' -o 'ConnectTimeout 10' ${EPC_Username}@${params.EPC_IPAddress}:${EPC_SourceCodePath}/logs/oai-cn5g.log.zip ./oai-cn5g.log.${env.BUILD_ID}.zip || true"
}
script {
if(fileExists("oai-cn5g.log.${env.BUILD_ID}.zip")) {
archiveArtifacts "oai-cn5g.log.${env.BUILD_ID}.zip"
}
if(fileExists("ci-scripts/test_results.html")) {
sh "mv ci-scripts/test_results.html test_results-${JOB_NAME}.html"
sh "sed -i -e 's#TEMPLATE_JOB_NAME#${JOB_NAME}#' -e 's@build #TEMPLATE_BUILD_ID@build #${BUILD_ID}@' -e 's#Build-ID: TEMPLATE_BUILD_ID#Build-ID: <a href=\"${BUILD_URL}\">${BUILD_ID}</a>#' -e 's#TEMPLATE_STAGE_NAME#${testStageName}#' test_results-${JOB_NAME}.html"
......
......@@ -47,30 +47,38 @@ pipeline {
COMMIT_ID=sh returnStdout: true, script: """curl --silent "https://gitlab.eurecom.fr/api/v4/projects/oai%2Fopenairinterface5g/merge_requests/${MR}" | jq ".sha" || true """
COMMIT_ID=COMMIT_ID.trim()
echo "Testing NSA on : ${MR} ${SRC_BRANCH} ${COMMIT_ID}"
//calling NSA sub job
build job: "RAN-NSA-Mini-Module", wait : true, propagate : false, parameters: [
//calling NSA B200
build job: "RAN-NSA-B200-Module-LTEBOX", wait : true, propagate : false, parameters: [
string(name: 'eNB_MR', value: String.valueOf(MR)),
string(name: 'eNB_Branch', value: String.valueOf(SRC_BRANCH)),
string(name: 'eNB_CommitID', value: String.valueOf(COMMIT_ID)),
string(name: 'eNB_TargetBranch', value: String.valueOf(TARGET_BRANCH)),
booleanParam(name: 'eNB_AllowMergeRequestProcess', value: Boolean.valueOf(ALLOW_MERGE))
]
//calling NSA 2x2
build job: "RAN-NSA-2x2-Module-OAIEPC", wait : true, propagate : false, parameters: [
string(name: 'eNB_MR', value: String.valueOf(MR)),
string(name: 'eNB_Branch', value: String.valueOf(SRC_BRANCH)),
string(name: 'eNB_CommitID', value: String.valueOf(COMMIT_ID)),
string(name: 'eNB_TargetBranch', value: String.valueOf(TARGET_BRANCH)),
booleanParam(name: 'eNB_AllowMergeRequestProcess', value: Boolean.valueOf(ALLOW_MERGE))
]
//calling LTE 2x2
build job: "RAN-LTE-2x2-Module-OAIEPC", wait : true, propagate : false, parameters: [
string(name: 'eNB_MR', value: String.valueOf(MR)),
string(name: 'eNB_Branch', value: String.valueOf(SRC_BRANCH)),
string(name: 'eNB_CommitID', value: String.valueOf(COMMIT_ID)),
string(name: 'eNB_TargetBranch', value: String.valueOf(TARGET_BRANCH)),
booleanParam(name: 'eNB_AllowMergeRequestProcess', value: Boolean.valueOf(ALLOW_MERGE))
]
//calling SA
build job: "RAN-SA-Module-CN5G", wait : true, propagate : false, parameters: [
string(name: 'eNB_MR', value: String.valueOf(MR)),
string(name: 'eNB_Branch', value: String.valueOf(SRC_BRANCH)),
string(name: 'eNB_CommitID', value: String.valueOf(COMMIT_ID)),
string(name: 'eNB_TargetBranch', value: String.valueOf(TARGET_BRANCH)),
booleanParam(name: 'eNB_AllowMergeRequestProcess', value: Boolean.valueOf(ALLOW_MERGE))
]
//calling NSA long sub job
// build job: "RAN-NSA-Mini-Module-Long", wait : true, propagate : false, parameters: [
// string(name: 'eNB_MR', value: String.valueOf(MR)),
// string(name: 'eNB_Branch', value: String.valueOf(SRC_BRANCH)),
// string(name: 'eNB_CommitID', value: String.valueOf(COMMIT_ID)),
// string(name: 'eNB_TargetBranch', value: String.valueOf(TARGET_BRANCH)),
// booleanParam(name: 'eNB_AllowMergeRequestProcess', value: Boolean.valueOf(ALLOW_MERGE))
// ]
//calling NSA attach/detach job
// build job: "RAN-NSA-Mini-Module-Attach-Detach", wait : true, propagate : false, parameters: [
// string(name: 'eNB_MR', value: String.valueOf(MR)),
// string(name: 'eNB_Branch', value: String.valueOf(SRC_BRANCH)),
// string(name: 'eNB_CommitID', value: String.valueOf(COMMIT_ID)),
// string(name: 'eNB_TargetBranch', value: String.valueOf(TARGET_BRANCH)),
// booleanParam(name: 'eNB_AllowMergeRequestProcess', value: Boolean.valueOf(ALLOW_MERGE))
// ]
}
}
......
......@@ -4,7 +4,9 @@ idefix:
Kind : quectel
Process :
Name : quectel-CM
Cmd : /home/oaicicd/quectel-CM/quectel-CM -s oai.ipv4 -4
Cmd : /home/oaicicd/quectel-CM/quectel-CM -4 -s
Apn :
ltebox : oai.ipv4
WakeupScript : ci_ctl_qtel.py /dev/ttyUSB2 wup
DetachScript : ci_ctl_qtel.py /dev/ttyUSB2 detach
LogStore : /media/usb-drive/ci_qlogs
......@@ -14,22 +16,29 @@ idefix:
HostUsername : oaicicd
HostPassword : oaicicd
HostSourceCodePath : none
MTU : 1500
nrmodule2_quectel:
ID: nrmodule2_quectel
State : enabled
Kind : quectel
Process :
Name : quectel-CM
Cmd : /home/nrmodule2/quectel-CM/quectel-CM -s oai.ipv4 -4
Cmd : /home/nrmodule2/quectel-CM/quectel-CM -4 -s
Apn :
OAICN5G : oai
OAI-Rel14-Docker : oai.ipv4
WakeupScript : ci_ctl_qtel.py /dev/ttyUSB7 wup
DetachScript : ci_ctl_qtel.py /dev/ttyUSB7 detach
LogStore : /media/ci_qlogs
PLMN : 20899
PLMN : 20897
UENetwork : wwan1
HostIPAddress : 192.168.18.189
HostUsername : nrmodule2
HostPassword : linux
HostSourceCodePath : none
StartCommands :
- sudo -S ip link set dev wwan1 mtu 1500
MTU : 1500
dummy:
ID: ''
State : ''
......
......@@ -61,7 +61,7 @@ class Module_UE:
#this method checks if the specified Process is running on the server hosting the module
#if not it will be started
def CheckCMProcess(self):
def CheckCMProcess(self,CNType):
HOST=self.HostUsername+'@'+self.HostIPAddress
COMMAND="ps aux | grep " + self.Process['Name'] + " | grep -v grep "
logging.debug(COMMAND)
......@@ -76,7 +76,7 @@ class Module_UE:
logging.debug('Starting ' + self.Process['Name'])
mySSH = sshconnection.SSHConnection()
mySSH.open(self.HostIPAddress, self.HostUsername, self.HostPassword)
mySSH.command('echo $USER; echo ' + self.HostPassword + ' | nohup sudo -S ' + self.Process['Cmd'] + ' &','\$',5)
mySSH.command('echo $USER; echo ' + self.HostPassword + ' | nohup sudo -S ' + self.Process['Cmd'] + ' ' + self.Process['Apn'][CNType] + ' &','\$',5)
mySSH.close()
#checking the process
time.sleep(5)
......@@ -131,6 +131,33 @@ class Module_UE:
logging.debug('\u001B[1;37;41m Module IP Address Not Found! \u001B[0m')
return -1
def CheckModuleMTU(self):
HOST=self.HostUsername+'@'+self.HostIPAddress
response= []
tentative = 3
while (len(response)==0) and (tentative>0):
COMMAND="ip a show dev " + self.UENetwork + " | grep mtu"
logging.debug(COMMAND)
ssh = subprocess.Popen(["ssh", "%s" % HOST, COMMAND],shell=False,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
response = ssh.stdout.readlines()
tentative-=1
time.sleep(10)
if (tentative==0) and (len(response)==0):
logging.debug('\u001B[1;37;41m Module NIC MTU Not Found! Time expired \u001B[0m')
return -1
else: #check response
result = re.search('mtu (?P<mtu>[0-9]+)', response[0].decode("utf-8") )
if result is not None:
if (result.group('mtu') is not None) and (str(result.group('mtu'))==str(self.MTU)) :
logging.debug('\u001B[1mUE Module NIC MTU is ' + str(self.MTU) + ' as expected\u001B[0m')
return 0
else:
logging.debug('\u001B[1;37;41m Incorrect Module NIC MTU ' + str(result.group('mtu')) + '! Expected : ' + str(self.MTU) + '\u001B[0m')
return -1
else:
logging.debug('\u001B[1;37;41m Module NIC MTU Not Found! \u001B[0m')
return -1
def EnableTrace(self):
if self.ue_trace=="yes":
mySSH = sshconnection.SSHConnection()
......
This diff is collapsed.
......@@ -14,7 +14,7 @@ eNBs =
// Tracking area code, 0x0000 and 0xfffe are reserved values
tracking_area_code = 1;
plmn_list = ( { mcc = 208; mnc = 99; mnc_length = 2; } );
plmn_list = ( { mcc = 208; mnc = 97; mnc_length = 2; } );
tr_s_preference = "local_mac"
......@@ -31,6 +31,7 @@ eNBs =
prefix_type = "NORMAL";
eutra_band = 38;
downlink_frequency = 2605000000L;
nr_scg_ssb_freq = 624608;
uplink_frequency_offset = 0;
Nid_cell = 0;
N_RB_DL = 100;
......@@ -209,8 +210,8 @@ MACRLCs = (
scheduler_mode = "fairRR";
bler_target_upper = 20.0;
bler_target_lower = 10.0;
max_ul_rb_index = 24;
puSch10xSnr = 100;
max_ul_rb_index = 27;
puSch10xSnr = 200;
puCch10xSnr = 150;
}
);
......
This diff is collapsed.
This diff is collapsed.
......@@ -270,6 +270,23 @@ THREAD_STRUCT = (
}
);
security = {
# preferred ciphering algorithms
# the first one of the list that an UE supports in chosen
# valid values: nea0, nea1, nea2, nea3
ciphering_algorithms = ( "nea0" );
# preferred integrity algorithms
# the first one of the list that an UE supports in chosen
# valid values: nia0, nia1, nia2, nia3
integrity_algorithms = ( "nia2", "nia0" );
# setting 'drb_ciphering' to "no" disables ciphering for DRBs, no matter
# what 'ciphering_algorithms' configures; same thing for 'drb_integrity'
drb_ciphering = "yes";
drb_integrity = "no";
};
log_config :
{
global_log_level ="info";
......
......@@ -259,6 +259,23 @@ THREAD_STRUCT = (
}
);
security = {
# preferred ciphering algorithms
# the first one of the list that an UE supports in chosen
# valid values: nea0, nea1, nea2, nea3
ciphering_algorithms = ( "nea0" );
# preferred integrity algorithms
# the first one of the list that an UE supports in chosen
# valid values: nia0, nia1, nia2, nia3
integrity_algorithms = ( "nia2", "nia0" );
# setting 'drb_ciphering' to "no" disables ciphering for DRBs, no matter
# what 'ciphering_algorithms' configures; same thing for 'drb_integrity'
drb_ciphering = "yes";
drb_integrity = "no";
};
log_config :
{
global_log_level ="info";
......
......@@ -13,7 +13,7 @@ gNBs =
// Tracking area code, 0x0000 and 0xfffe are reserved values
tracking_area_code = 1;
plmn_list = ({mcc = 208; mnc = 99; mnc_length = 2;});
plmn_list = ({mcc = 208; mnc = 97; mnc_length = 2;});
tr_s_preference = "local_mac"
......@@ -24,6 +24,7 @@ gNBs =
pusch_AntennaPorts = 2;
pusch_TargetSNRx10 = 200;
pucch_TargetSNRx10 = 200;
ul_prbblacklist = "51,52,53,54"
servingCellConfigCommon = (
{
......@@ -33,11 +34,11 @@ gNBs =
# downlinkConfigCommon
#frequencyInfoDL
# this is 3600 MHz + 84 PRBs@30kHz SCS (same as initial BWP)
absoluteFrequencySSB = 641272; //641032; #641968; 641968=start of ssb at 3600MHz + 82 RBs 641032=center of SSB at center of cell
# this is 3350.04 MHz + 53 PRBs@30kHz SCS (same as initial BWP)
absoluteFrequencySSB = 624608;
dl_frequencyBand = 78;
# this is 3600 MHz
dl_absoluteFrequencyPointA = 640000;
# this is 3350.04 MHz
dl_absoluteFrequencyPointA = 623336;
#scs-SpecificCarrierList
dl_offstToCarrier = 0;
# subcarrierSpacing
......@@ -46,7 +47,7 @@ gNBs =
dl_carrierBandwidth = 106;
#initialDownlinkBWP
#genericParameters
# this is RBstart=84,L=13 (275*(L-1))+RBstart
# this is RBstart=43,L=24 (275*(L-1))+RBstart
initialDLBWPlocationAndBandwidth = 6368;
# subcarrierSpacing
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
......@@ -233,7 +234,7 @@ L1s = (
num_cc = 1;
tr_n_preference = "local_mac";
pusch_proc_threads = 8;
prach_dtx_threshold = 100;
prach_dtx_threshold = 120;
}
);
......@@ -268,12 +269,17 @@ security = {
# preferred ciphering algorithms
# the first one of the list that an UE supports in chosen
# valid values: nea0, nea1, nea2, nea3
ciphering_algorithms = ( "nea0", "nea2" );
ciphering_algorithms = ( "nea0" );
# preferred integrity algorithms
# the first one of the list that an UE supports in chosen
# valid values: nia0, nia1, nia2, nia3
integrity_algorithms = ( "nia0" );
integrity_algorithms = ( "nia2", "nia0" );
# setting 'drb_ciphering' to "no" disables ciphering for DRBs, no matter
# what 'ciphering_algorithms' configures; same thing for 'drb_integrity'
drb_ciphering = "yes";
drb_integrity = "no";
};
log_config :
......
Active_gNBs = ( "gNB-Eurecom-DU");
Active_gNBs = ( "gNB-OAI");
# Asn1_verbosity, choice in: none, info, annoying
Asn1_verbosity = "none";
......@@ -7,7 +7,7 @@ gNBs =
{
////////// Identification parameters:
gNB_ID = 0xe00;
gNB_name = "gNB-Eurecom-DU";
gNB_name = "gNB-OAI";
// Tracking area code, 0x0000 and 0xfffe are reserved values
tracking_area_code = 1;
......@@ -35,6 +35,7 @@ gNBs =
ssb_SubcarrierOffset = 0;
pdsch_AntennaPorts = 1;
pusch_AntennaPorts = 1;
ul_prbblacklist = "51,52,53,54"
pdcch_ConfigSIB1 = (
{
......@@ -203,7 +204,7 @@ gNBs =
};
////////// MME parameters:
////////// AMF parameters:
amf_ip_address = ( { ipv4 = "CI_MME_IP_ADDR";
ipv6 = "192:168:30::17";
active = "yes";
......@@ -229,9 +230,9 @@ MACRLCs = (
num_cc = 1;
tr_s_preference = "local_L1";
tr_n_preference = "local_RRC";
ulsch_max_slots_inactivity = 100;
pusch_TargetSNRx10 = 200;
pucch_TargetSNRx10 = 200;
pucch_TargetSNRx10 = 150;
ulsch_max_slots_inactivity = 10;
}
);
......@@ -240,6 +241,8 @@ L1s = (
num_cc = 1;
tr_n_preference = "local_mac";
pusch_proc_threads = 8;
prach_dtx_threshold = 120;
pucch0_dtx_threshold = 150;
}
);
......@@ -250,9 +253,9 @@ RUs = (
nb_rx = 1
att_tx = 0
att_rx = 0;
bands = [7];
bands = [78];
max_pdschReferenceSignalPower = -27;
max_rxgain = 81;
max_rxgain = 75;
eNB_instances = [0];
#beamforming 1x4 matrix:
bf_weights = [0x00007fff, 0x0000, 0x0000, 0x0000];
......@@ -279,6 +282,23 @@ rfsimulator :
IQfile = "/tmp/rfsimulator.iqs";
};
security = {
# preferred ciphering algorithms
# the first one of the list that an UE supports in chosen
# valid values: nea0, nea1, nea2, nea3
ciphering_algorithms = ( "nea0" );
# preferred integrity algorithms
# the first one of the list that an UE supports in chosen
# valid values: nia0, nia1, nia2, nia3
integrity_algorithms = ( "nia2", "nia0" );
# setting 'drb_ciphering' to "no" disables ciphering for DRBs, no matter
# what 'ciphering_algorithms' configures; same thing for 'drb_integrity'
drb_ciphering = "yes";
drb_integrity = "no";
};
log_config :
{
global_log_level ="info";
......
......@@ -257,6 +257,23 @@ THREAD_STRUCT = (
}
);
security = {
# preferred ciphering algorithms
# the first one of the list that an UE supports in chosen
# valid values: nea0, nea1, nea2, nea3
ciphering_algorithms = ( "nea0" );
# preferred integrity algorithms
# the first one of the list that an UE supports in chosen
# valid values: nia0, nia1, nia2, nia3
integrity_algorithms = ( "nia2", "nia0" );
# setting 'drb_ciphering' to "no" disables ciphering for DRBs, no matter
# what 'ciphering_algorithms' configures; same thing for 'drb_integrity'
drb_ciphering = "yes";
drb_integrity = "no";
};
log_config :
{
global_log_level ="info";
......
......@@ -262,6 +262,23 @@ THREAD_STRUCT = (
}
);
security = {
# preferred ciphering algorithms
# the first one of the list that an UE supports in chosen
# valid values: nea0, nea1, nea2, nea3
ciphering_algorithms = ( "nea0" );
# preferred integrity algorithms
# the first one of the list that an UE supports in chosen
# valid values: nia0, nia1, nia2, nia3
integrity_algorithms = ( "nia2", "nia0" );
# setting 'drb_ciphering' to "no" disables ciphering for DRBs, no matter
# what 'ciphering_algorithms' configures; same thing for 'drb_integrity'
drb_ciphering = "yes";
drb_integrity = "no";
};
log_config :
{
global_log_level ="info";
......
......@@ -272,6 +272,23 @@ THREAD_STRUCT = (
}
);
security = {
# preferred ciphering algorithms
# the first one of the list that an UE supports in chosen
# valid values: nea0, nea1, nea2, nea3
ciphering_algorithms = ( "nea0" );
# preferred integrity algorithms
# the first one of the list that an UE supports in chosen
# valid values: nia0, nia1, nia2, nia3
integrity_algorithms = ( "nia2", "nia0" );
# setting 'drb_ciphering' to "no" disables ciphering for DRBs, no matter
# what 'ciphering_algorithms' configures; same thing for 'drb_integrity'
drb_ciphering = "yes";
drb_integrity = "no";
};
log_config :
{
global_log_level ="info";
......
......@@ -12,7 +12,8 @@ Ref :
feptx_prec : 8.0
feptx_ofdm : 50.0
feptx_total : 75.0
L1 Tx processing : 300.0
L1 Tx processing thread 0 : 300.0
L1 Tx processing thread 1 : 300.0
DLSCH encoding : 230.0
L1 Rx processing : 175.0
PUSCH inner-receiver : 100.0
......@@ -24,7 +25,8 @@ Threshold :
feptx_prec : 1.25
feptx_ofdm : 1.25
feptx_total : 1.25
L1 Tx processing : 1.25
L1 Tx processing thread 0 : 1.25
L1 Tx processing thread 1 : 1.25
DLSCH encoding : 1.25
L1 Rx processing : 1.25
PUSCH inner-receiver : 1.25
......
......@@ -220,7 +220,7 @@ class EPCManagement():
mySSH = SSH.SSHConnection()
mySSH.open(self.IPAddress, self.UserName, self.Password)
if re.match('ltebox', self.Type, re.IGNORECASE):
logging.debug('Using the sabox simulated HSS')
logging.debug('Using the SABOX simulated HSS')
mySSH.command('if [ -d ' + self.SourceCodePath + '/scripts ]; then echo ' + self.Password + ' | sudo -S rm -Rf ' + self.SourceCodePath + '/scripts ; fi', '\$', 5)
mySSH.command('mkdir -p ' + self.SourceCodePath + '/scripts', '\$', 5)
mySSH.command('cd /opt/hss_sim0609', '\$', 5)
......@@ -229,6 +229,12 @@ class EPCManagement():
logging.debug('Using the sabox')
mySSH.command('cd /opt/ltebox/tools', '\$', 5)
mySSH.command('echo ' + self.Password + ' | sudo -S ./start_sabox', '\$', 5)
elif re.match('OAICN5G', self.Type, re.IGNORECASE):
logging.debug('Starting OAI CN5G')
mySSH.command('if [ -d ' + self.SourceCodePath + '/scripts ]; then echo ' + self.Password + ' | sudo -S rm -Rf ' + self.SourceCodePath + '/scripts ; fi', '\$', 5)
mySSH.command('mkdir -p ' + self.SourceCodePath + '/scripts', '\$', 5)
mySSH.command('cd /opt/oai-cn5g-fed/docker-compose', '\$', 5)
mySSH.command('./core-network.sh start nrf spgwu', '\$', 60)
else:
logging.error('This option should not occur!')
mySSH.close()
......@@ -242,6 +248,16 @@ class EPCManagement():
return
if re.match('ltebox', self.Type, re.IGNORECASE):
self.MmeIPAddress = self.IPAddress
elif re.match('OAICN5G', self.Type, re.IGNORECASE):
mySSH = SSH.SSHConnection()
mySSH.open(self.IPAddress, self.UserName, self.Password)
response=mySSH.command3('docker container ls -f name=oai-amf', 10)
if len(response)>1:
response=mySSH.command3('docker inspect --format=\'{{range.NetworkSettings.Networks}}{{.IPAddress}}{{end}}\' oai-amf', 10)
tmp = str(response[0],'utf-8')
self.MmeIPAddress = tmp.rstrip()
logging.debug('AMF IP Address ' + self.MmeIPAddress)
mySSH.close()
def CheckHSSProcess(self, status_queue):
try:
......@@ -433,6 +449,7 @@ class EPCManagement():
mySSH = SSH.SSHConnection()
mySSH.open(self.IPAddress, self.UserName, self.Password)
if re.match('ltebox', self.Type, re.IGNORECASE):
logging.debug('Terminating SA BOX')
mySSH.command('cd /opt/ltebox/tools', '\$', 5)
mySSH.command('echo ' + self.Password + ' | sudo -S ./stop_sabox', '\$', 5)
time.sleep(1)
......@@ -440,6 +457,12 @@ class EPCManagement():
mySSH.command('cd scripts', '\$', 5)
time.sleep(1)
mySSH.command('echo ' + self.Password + ' | sudo -S screen -S simulated_5g_hss -X quit', '\$', 5)
elif re.match('OAICN5G', self.Type, re.IGNORECASE):
self.LogCollectOAICN5G()
logging.debug('Terminating OAI CN5G')
mySSH.command('cd /opt/oai-cn5g-fed/docker-compose', '\$', 5)
mySSH.command('docker-compose down', '\$', 5)
mySSH.command('./core-network.sh stop nrf spgwu', '\$', 60)
else:
logging.error('This should not happen!')
mySSH.close()
......@@ -679,3 +702,16 @@ class EPCManagement():
logging.error('This option should not occur!')
mySSH.close()
def LogCollectOAICN5G(self):
mySSH = SSH.SSHConnection()
mySSH.open(self.IPAddress, self.UserName, self.Password)
logging.debug('OAI CN5G Collecting Log files to workspace')
mySSH.command('echo ' + self.Password + ' | sudo rm -rf ' + self.SourceCodePath + '/logs', '\$', 5)
mySSH.command('mkdir ' + self.SourceCodePath + '/logs','\$', 5)
containers_list=['oai-smf','oai-spgwu','oai-amf','oai-nrf']
for c in containers_list:
mySSH.command('docker logs ' + c + ' > ' + self.SourceCodePath + '/logs/' + c + '.log', '\$', 5)
mySSH.command('cd ' + self.SourceCodePath + '/logs', '\$', 5)
mySSH.command('zip oai-cn5g.log.zip *.log', '\$', 60)
mySSH.close()
......@@ -154,6 +154,7 @@ def GetParametersFromXML(action):
elif action == 'Initialize_eNB':
RAN.eNB_Trace=test.findtext('eNB_Trace')
RAN.eNB_Stats=test.findtext('eNB_Stats')
RAN.Initialize_eNB_args=test.findtext('Initialize_eNB_args')
eNB_instance=test.findtext('eNB_instance')
USRPIPAddress=test.findtext('USRP_IPAddress')
......
......@@ -39,7 +39,6 @@ import time
from multiprocessing import Process, Lock, SimpleQueue
import yaml
#-----------------------------------------------------------
# OAI Testing modules
#-----------------------------------------------------------
......@@ -94,6 +93,7 @@ class RANManagement():
self.runtime_stats= ''
self.datalog_rt_stats={}
self.eNB_Trace = '' #if 'yes', Tshark will be launched at initialization
self.eNB_Stats = '' #if 'yes', Statistics Monitor will be launched at initialization
self.USRPIPAddress = ''
......@@ -341,6 +341,8 @@ class RANManagement():
self.testCase_id = HTML.testCase_id
mySSH = SSH.SSHConnection()
cwd = os.getcwd()
mySSH.copyout(lIpAddr,lUserName,lPassWord, cwd + "/active_net_interfaces.awk", "/tmp")
#reboot USRP if requested in xml
if self.USRPIPAddress!='':
......@@ -461,10 +463,36 @@ class RANManagement():
mySSH.command('if [ -e rbconfig.raw ]; then echo ' + lPassWord + ' | sudo -S rm rbconfig.raw; fi', '\$', 5)
mySSH.command('if [ -e reconfig.raw ]; then echo ' + lPassWord + ' | sudo -S rm reconfig.raw; fi', '\$', 5)
# NOTE: WE SHALL do a check if the executable is present (in case build went wrong)
#hack UHD_RFNOC_DIR variable for gNB / N310 on RHEL8 server:
#if the USRP address is in the xml then we are using an eth USRP (N3xx)
if (self.air_interface[self.eNB_instance] == 'lte-softmodem') or (self.air_interface[self.eNB_instance] == 'ocp-enb'):
gNB = False
else:
gNB = True
if ((self.USRPIPAddress!='') and (gNB==True)):
mySSH.command('echo ' + lPassWord + ' | echo "ulimit -c unlimited && sudo UHD_RFNOC_DIR=/usr/local/share/uhd/rfnoc ./ran_build/build/' + self.air_interface[self.eNB_instance] + ' -O ' + lSourcePath + '/' + ci_full_config_file + extra_options + '" > ./my-lte-softmodem-run' + str(self.eNB_instance) + '.sh', '\$', 5)
#otherwise the regular command is ok
else:
mySSH.command('echo "ulimit -c unlimited && ./ran_build/build/' + self.air_interface[self.eNB_instance] + ' -O ' + lSourcePath + '/' + ci_full_config_file + extra_options + '" > ./my-lte-softmodem-run' + str(self.eNB_instance) + '.sh', '\$', 5)
mySSH.command('chmod 775 ./my-lte-softmodem-run' + str(self.eNB_instance) + '.sh', '\$', 5)
mySSH.command('echo ' + lPassWord + ' | sudo -S rm -Rf enb_' + self.testCase_id + '.log', '\$', 5)
mySSH.command('echo $USER; nohup sudo -E ./my-lte-softmodem-run' + str(self.eNB_instance) + '.sh > ' + lSourcePath + '/cmake_targets/enb_' + self.testCase_id + '.log 2>&1 &', lUserName, 10)
#stats monitoring during runtime
time.sleep(20)
monitor_file='../ci-scripts/stats_monitor.py'
conf_file='../ci-scripts/stats_monitor_conf.yaml'
if self.eNB_Stats=='yes':
if (self.air_interface[self.eNB_instance] == 'lte-softmodem') or (self.air_interface[self.eNB_instance] == 'ocp-enb'):
mySSH.command('echo $USER; nohup python3 ' + monitor_file + ' ' + conf_file + ' enb 2>&1 > enb_stats_monitor_execution.log &', '\$', 5)
else:
mySSH.command('echo $USER; nohup python3 ' + monitor_file + ' ' + conf_file + ' gnb 2>&1 > gnb_stats_monitor_execution.log &', '\$', 5)
self.eNBLogFiles[int(self.eNB_instance)] = 'enb_' + self.testCase_id + '.log'
if extra_options != '':
self.eNBOptions[int(self.eNB_instance)] = extra_options
......@@ -539,6 +567,8 @@ class RANManagement():
self.eNBstatuses[int(self.eNB_instance)] = int(self.eNB_serverId[self.eNB_instance])
mySSH.close()
HTML.CreateHtmlTestRow(self.air_interface[self.eNB_instance] + ' -O ' + config_file + extra_options, 'OK', CONST.ALL_PROCESSES_OK)
logging.debug('\u001B[1m Initialize eNB/gNB/ocp-eNB Completed\u001B[0m')
......@@ -657,6 +687,11 @@ class RANManagement():
fileToAnalyze = self.eNBLogFiles[int(self.eNB_instance)]
self.eNBLogFiles[int(self.eNB_instance)] = ''
if analyzeFile:
#*stats.log files + pickle + png
mySSH.copyin(lIpAddr, lUserName, lPassWord, lSourcePath + '/cmake_targets/*stats.log', '.')
mySSH.copyin(lIpAddr, lUserName, lPassWord, lSourcePath + '/cmake_targets/*.pickle', '.')
mySSH.copyin(lIpAddr, lUserName, lPassWord, lSourcePath + '/cmake_targets/*.png', '.')
#
copyin_res = mySSH.copyin(lIpAddr, lUserName, lPassWord, lSourcePath + '/cmake_targets/' + fileToAnalyze, '.')
if (copyin_res == -1):
logging.debug('\u001B[1;37;41m Could not copy ' + nodeB_prefix + 'NB logfile to analyze it! \u001B[0m')
......@@ -665,12 +700,20 @@ class RANManagement():
self.eNBmbmsEnables[int(self.eNB_instance)] = False
return
if self.eNB_serverId[self.eNB_instance] != '0':
#*stats.log files + pickle + png
#debug / tentative
mySSH.copyout(self.eNBIPAddress, self.eNBUserName, self.eNBPassword, './nrL1_stats.log', self.eNBSourceCodePath + '/cmake_targets/')
mySSH.copyout(self.eNBIPAddress, self.eNBUserName, self.eNBPassword, './nrMAC_stats.log', self.eNBSourceCodePath + '/cmake_targets/')
mySSH.copyout(self.eNBIPAddress, self.eNBUserName, self.eNBPassword, './gnb_stats_monitor.pickle', self.eNBSourceCodePath + '/cmake_targets/')
mySSH.copyout(self.eNBIPAddress, self.eNBUserName, self.eNBPassword, './gnb_stats_monitor.png', self.eNBSourceCodePath + '/cmake_targets/')
#
mySSH.copyout(self.eNBIPAddress, self.eNBUserName, self.eNBPassword, './' + fileToAnalyze, self.eNBSourceCodePath + '/cmake_targets/')
logging.debug('\u001B[1m Analyzing ' + nodeB_prefix + 'NB logfile \u001B[0m ' + fileToAnalyze)
logStatus = self.AnalyzeLogFile_eNB(fileToAnalyze, HTML)
if (logStatus < 0):
HTML.CreateHtmlTestRow('N/A', 'KO', logStatus)
self.preamtureExit = True
self.prematureExit = True
self.eNBmbmsEnables[int(self.eNB_instance)] = False
return
else:
......@@ -691,8 +734,8 @@ class RANManagement():
mySSH.command('echo ' + self.eNBPassword + ' | sudo -S mv /tmp/enb_*.pcap .','\$',20)
mySSH.command('echo ' + self.eNBPassword + ' | sudo -S mv /tmp/gnb_*.pcap .','\$',20)
mySSH.command('echo ' + self.eNBPassword + ' | sudo -S rm -f enb.log.zip', '\$', 5)
mySSH.command('echo ' + self.eNBPassword + ' | sudo -S zip enb.log.zip enb*.log core* enb_*record.raw enb_*.pcap gnb_*.pcap enb_*txt physim_*.log *stats.log', '\$', 60)
mySSH.command('echo ' + self.eNBPassword + ' | sudo -S rm enb*.log core* enb_*record.raw enb_*.pcap gnb_*.pcap enb_*txt physim_*.log *stats.log', '\$', 5)
mySSH.command('echo ' + self.eNBPassword + ' | sudo -S zip enb.log.zip enb*.log core* enb_*record.raw enb_*.pcap gnb_*.pcap enb_*txt physim_*.log *stats.log *monitor.pickle *monitor.png', '\$', 60)
mySSH.command('echo ' + self.eNBPassword + ' | sudo -S rm enb*.log core* enb_*record.raw enb_*.pcap gnb_*.pcap enb_*txt physim_*.log *stats.log *.pickle *.png', '\$', 5)
mySSH.close()
def AnalyzeLogFile_eNB(self, eNBlogFile, HTML):
......@@ -1032,7 +1075,7 @@ class RANManagement():
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
self.prematureExit=False #temp for debug : do not stop the test if RT stats are excedeed
else:
statMsg = 'No real time stats found in the log file\n'
logging.debug('No real time stats found in the log file')
......
......@@ -163,6 +163,18 @@ class SSHConnection():
lSsh = subprocess.Popen(["ssh", "%s" % myHost, commandline],shell=False,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
self.cmd2Results = str(lSsh.stdout.readlines())
def command3(self, commandline, timeout, silent=False):
if not silent:
logging.debug(commandline)
self.cmd2Results = ''
myHost = self.username + '@' + self.ipaddress
# CAUTION: THIS METHOD IMPLIES THAT THERE ARE VALID SSH KEYS
# BETWEEN THE PYTHON EXECUTOR NODE AND THE REMOTE HOST
# OTHERWISE IT WON'T WORK
lSsh = subprocess.Popen(["ssh", "%s" % myHost, commandline],shell=False,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
return lSsh.stdout.readlines()
def close(self):
self.ssh.timeout = 5
self.ssh.sendline('exit')
......
"""
To create graphs and pickle from runtime statistics in L1,MAC,RRC,PDCP files
"""
import subprocess
import time
import shlex
import re
import sys
import pickle
import matplotlib.pyplot as plt
import numpy as np
import yaml
class StatMonitor():
def __init__(self,cfg_file):
with open(cfg_file,'r') as file:
self.d = yaml.load(file)
for node in self.d:
for metric in self.d[node]:
self.d[node][metric]=[]
def process_gnb (self,node_type,output):
for line in output:
tmp=line.decode("utf-8")
result=re.match(r'^.*\bdlsch_rounds\b ([0-9]+)\/([0-9]+).*\bdlsch_errors\b ([0-9]+)',tmp)
if result is not None:
self.d[node_type]['dlsch_err'].append(int(result.group(3)))
percentage=float(result.group(2))/float(result.group(1))
self.d[node_type]['dlsch_err_perc_round_1'].append(percentage)
result=re.match(r'^.*\bulsch_rounds\b ([0-9]+)\/([0-9]+).*\bulsch_errors\b ([0-9]+)',tmp)
if result is not None:
self.d[node_type]['ulsch_err'].append(int(result.group(3)))
percentage=float(result.group(2))/float(result.group(1))
self.d[node_type]['ulsch_err_perc_round_1'].append(percentage)
def process_enb (self,node_type,output):
for line in output:
tmp=line.decode("utf-8")
result=re.match(r'^.*\bPHR\b ([0-9]+).+\bbler\b ([0-9]+\.[0-9]+).+\bmcsoff\b ([0-9]+).+\bmcs\b ([0-9]+)',tmp)
if result is not None:
self.d[node_type]['PHR'].append(int(result.group(1)))
self.d[node_type]['bler'].append(float(result.group(2)))
self.d[node_type]['mcsoff'].append(int(result.group(3)))
self.d[node_type]['mcs'].append(int(result.group(4)))
def collect(self,node_type):
if node_type=='enb':
cmd='cat L1_stats.log MAC_stats.log PDCP_stats.log RRC_stats.log'
else: #'gnb'
cmd='cat nrL1_stats.log nrMAC_stats.log nrPDCP_stats.log nrRRC_stats.log'
process=subprocess.Popen(shlex.split(cmd), stdout=subprocess.PIPE)
output = process.stdout.readlines()
if node_type=='enb':
self.process_enb(node_type,output)
else: #'gnb'
self.process_gnb(node_type,output)
def graph(self,node_type):
col = 1
figure, axis = plt.subplots(len(self.d[node_type]), col ,figsize=(10, 10))
i=0
for metric in self.d[node_type]:
major_ticks = np.arange(0, len(self.d[node_type][metric])+1, 1)
axis[i].set_xticks(major_ticks)
axis[i].set_xticklabels([])
axis[i].plot(self.d[node_type][metric],marker='o')
axis[i].set_xlabel('time')
axis[i].set_ylabel(metric)
axis[i].set_title(metric)
i+=1
plt.tight_layout()
# Combine all the operations and display
plt.savefig(node_type+'_stats_monitor.png')
plt.show()
if __name__ == "__main__":
cfg_filename = sys.argv[1] #yaml file as metrics config
node = sys.argv[2]#enb or gnb
mon=StatMonitor(cfg_filename)
#collecting stats when modem process is stopped
CMD='ps aux | grep mode | grep -v grep'
process=subprocess.Popen(CMD, shell=True, stdout=subprocess.PIPE)
output = process.stdout.readlines()
while len(output)!=0 :
mon.collect(node)
process=subprocess.Popen(CMD, shell=True, stdout=subprocess.PIPE)
output = process.stdout.readlines()
time.sleep(1)
print('Process stopped')
with open(node+'_stats_monitor.pickle', 'wb') as handle:
pickle.dump(mon.d, handle, protocol=pickle.HIGHEST_PROTOCOL)
mon.graph(node)
import subprocess
import time
import shlex
import re
import sys
import matplotlib.pyplot as plt
import pickle
import numpy as np
import os
def collect(d, node_type):
if node_type=='enb':
cmd='cat L1_stats.log MAC_stats.log PDCP_stats.log RRC_stats.log'
else: #'gnb'
cmd='cat nrL1_stats.log nrMAC_stats.log nrPDCP_stats.log nrRRC_stats.log'
process=subprocess.Popen(shlex.split(cmd), stdout=subprocess.PIPE)
output = process.stdout.readlines()
for l in output:
tmp=l.decode("utf-8")
result=re.match(rf'^.*\bPHR\b ([0-9]+).+\bbler\b ([0-9]+\.[0-9]+).+\bmcsoff\b ([0-9]+).+\bmcs\b ([0-9]+)',tmp)
if result is not None:
d['PHR'].append(int(result.group(1)))
d['bler'].append(float(result.group(2)))
d['mcsoff'].append(int(result.group(3)))
d['mcs'].append(int(result.group(4)))
def graph(d, node_type):
figure, axis = plt.subplots(4, 1,figsize=(10, 10))
major_ticks = np.arange(0, len(d['PHR'])+1, 1)
axis[0].set_xticks(major_ticks)
axis[0].set_xticklabels([])
axis[0].plot(d['PHR'],marker='o')
axis[0].set_xlabel('time')
axis[0].set_ylabel('PHR')
axis[0].set_title("PHR")
major_ticks = np.arange(0, len(d['bler'])+1, 1)
axis[1].set_xticks(major_ticks)
axis[1].set_xticklabels([])
axis[1].plot(d['bler'],marker='o')
axis[1].set_xlabel('time')
axis[1].set_ylabel('bler')
axis[1].set_title("bler")
major_ticks = np.arange(0, len(d['mcsoff'])+1, 1)
axis[2].set_xticks(major_ticks)
axis[2].set_xticklabels([])
axis[2].plot(d['mcsoff'],marker='o')
axis[2].set_xlabel('time')
axis[2].set_ylabel('mcsoff')
axis[2].set_title("mcsoff")
major_ticks = np.arange(0, len(d['mcs'])+1, 1)
axis[3].set_xticks(major_ticks)
axis[3].set_xticklabels([])
axis[3].plot(d['mcs'],marker='o')
axis[3].set_xlabel('time')
axis[3].set_ylabel('mcs')
axis[3].set_title("mcs")
plt.tight_layout()
# Combine all the operations and display
plt.savefig(node_type+'_stats_monitor.png')
plt.show()
if __name__ == "__main__":
node_type = sys.argv[1]#enb or gnb
d={}
d['PHR']=[]
d['bler']=[]
d['mcsoff']=[]
d['mcs']=[]
cmd='ps aux | grep modem | grep -v grep'
process=subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE)
output = process.stdout.readlines()
while len(output)!=0 :
collect(d, node_type)
process=subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE)
output = process.stdout.readlines()
time.sleep(1)
print('process stopped')
with open(node_type+'_stats_monitor.pickle', 'wb') as handle:
pickle.dump(d, handle, protocol=pickle.HIGHEST_PROTOCOL)
graph(d, node_type)
enb :
PHR:
bler:
mcsoff:
mcs:
gnb :
dlsch_err:
dlsch_err_perc_round_1:
ulsch_err:
ulsch_err_perc_round_1:
\ No newline at end of file
"""
To create graphs and pickle from runtime statistics in L1,MAC,RRC,PDCP files
"""
import subprocess
import time
import shlex
import re
import sys
import pickle
import matplotlib.pyplot as plt
import numpy as np
import yaml
class StatMonitor():
def __init__(self,):
with open('stats_monitor_conf.yaml','r') as file:
self.d = yaml.load(file)
for node in self.d:
for metric in self.d[node]:
self.d[node][metric]=[]
def process_gnb (self,node_type,output):
for line in output:
tmp=line.decode("utf-8")
result=re.match(r'^.*\bdlsch_rounds\b ([0-9]+)\/([0-9]+).*\bdlsch_errors\b ([0-9]+)',tmp)
if result is not None:
self.d[node_type]['dlsch_err'].append(int(result.group(3)))
percentage=float(result.group(2))/float(result.group(1))
self.d[node_type]['dlsch_err_perc_round_1'].append(percentage)
result=re.match(r'^.*\bulsch_rounds\b ([0-9]+)\/([0-9]+).*\bulsch_errors\b ([0-9]+)',tmp)
if result is not None:
self.d[node_type]['ulsch_err'].append(int(result.group(3)))
percentage=float(result.group(2))/float(result.group(1))
self.d[node_type]['ulsch_err_perc_round_1'].append(percentage)
def process_enb (self,node_type,output):
for line in output:
tmp=line.decode("utf-8")
result=re.match(r'^.*\bPHR\b ([0-9]+).+\bbler\b ([0-9]+\.[0-9]+).+\bmcsoff\b ([0-9]+).+\bmcs\b ([0-9]+)',tmp)
if result is not None:
self.d[node_type]['PHR'].append(int(result.group(1)))
self.d[node_type]['bler'].append(float(result.group(2)))
self.d[node_type]['mcsoff'].append(int(result.group(3)))
self.d[node_type]['mcs'].append(int(result.group(4)))
def collect(self,node_type):
if node_type=='enb':
cmd='cat L1_stats.log MAC_stats.log PDCP_stats.log RRC_stats.log'
else: #'gnb'
cmd='cat nrL1_stats.log nrMAC_stats.log nrPDCP_stats.log nrRRC_stats.log'
process=subprocess.Popen(shlex.split(cmd), stdout=subprocess.PIPE)
output = process.stdout.readlines()
if node_type=='enb':
self.process_enb(node_type,output)
else: #'gnb'
self.process_gnb(node_type,output)
def graph(self,node_type):
col = 1
figure, axis = plt.subplots(len(self.d[node_type]), col ,figsize=(10, 10))
i=0
for metric in self.d[node_type]:
major_ticks = np.arange(0, len(self.d[node_type][metric])+1, 1)
axis[i].set_xticks(major_ticks)
axis[i].set_xticklabels([])
axis[i].plot(self.d[node_type][metric],marker='o')
axis[i].set_xlabel('time')
axis[i].set_ylabel(metric)
axis[i].set_title(metric)
i+=1
plt.tight_layout()
# Combine all the operations and display
plt.savefig(node_type+'_stats_monitor.png')
plt.show()
if __name__ == "__main__":
node = sys.argv[1]#enb or gnb
mon=StatMonitor()
#collecting stats when modem process is stopped
CMD='ps aux | grep mode | grep -v grep'
process=subprocess.Popen(CMD, shell=True, stdout=subprocess.PIPE)
output = process.stdout.readlines()
while len(output)!=0 :
mon.collect(node)
process=subprocess.Popen(CMD, shell=True, stdout=subprocess.PIPE)
output = process.stdout.readlines()
time.sleep(1)
print('Process stopped')
with open(node+'_stats_monitor.pickle', 'wb') as handle:
pickle.dump(mon.d, handle, protocol=pickle.HIGHEST_PROTOCOL)
mon.graph(node)
<!--
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
-->
<testCaseList>
<htmlTabRef>build-tab</htmlTabRef>
<htmlTabName>Build</htmlTabName>
<htmlTabIcon>wrench</htmlTabIcon>
<TestCaseRequestedList>
000001
000002
</TestCaseRequestedList>
<TestCaseExclusionList></TestCaseExclusionList>
<testCase id="000001">
<class>Build_eNB</class>
<desc>Build eNB</desc>
<Build_eNB_args>-w USRP -c --eNB --ninja</Build_eNB_args>
<eNB_instance>0</eNB_instance>
<eNB_serverId>0</eNB_serverId>
<backgroundBuild>True</backgroundBuild>
<forced_workspace_cleanup>True</forced_workspace_cleanup>
</testCase>
<testCase id="000002">
<class>WaitEndBuild_eNB</class>
<desc>Wait for end of Build eNB</desc>
<eNB_instance>0</eNB_instance>
<eNB_serverId>0</eNB_serverId>
</testCase>
</testCaseList>
......@@ -26,7 +26,6 @@
<htmlTabIcon>wrench</htmlTabIcon>
<TestCaseRequestedList>
000001
000002
</TestCaseRequestedList>
<TestCaseExclusionList></TestCaseExclusionList>
......@@ -36,7 +35,6 @@
<Build_eNB_args>-w USRP -c --gNB --ninja</Build_eNB_args>
<eNB_instance>0</eNB_instance>
<eNB_serverId>0</eNB_serverId>
<backgroundBuild>True</backgroundBuild>
<forced_workspace_cleanup>True</forced_workspace_cleanup>
</testCase>
......
<!--
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
-->
<testCaseList>
<htmlTabRef>TEST-LTE-TM2</htmlTabRef>
<htmlTabName>LTE 2x2 Ping DL UL with QUECTEL</htmlTabName>
<htmlTabIcon>tasks</htmlTabIcon>
<repeatCount>1</repeatCount>
<TestCaseRequestedList>
030000
000002
010000
000001
050000
050001
000002
070000
070001
000001
010002
080000
</TestCaseRequestedList>
<TestCaseExclusionList></TestCaseExclusionList>
<testCase id="010000">
<class>Initialize_UE</class>
<desc>Initialize Quectel</desc>
<id>nrmodule2_quectel</id>
<UE_Trace>yes</UE_Trace>
</testCase>
<testCase id="010002">
<class>Terminate_UE</class>
<desc>Terminate Quectel</desc>
<id>nrmodule2_quectel</id>
</testCase>
<testCase id="030000">
<class>Initialize_eNB</class>
<desc>Initialize eNB</desc>
<Initialize_eNB_args>-O ci-scripts/conf_files/enb.band38.nsa_2x2.100PRB.usrpn310.conf --usrp-tx-thread-config 1 --thread-pool 0,2,4,6</Initialize_eNB_args>
<eNB_instance>0</eNB_instance>
<eNB_serverId>0</eNB_serverId>
<air_interface>lte</air_interface>
<eNB_Trace>yes</eNB_Trace>
<eNB_Stats>yes</eNB_Stats>
<USRP_IPAddress>192.168.18.241</USRP_IPAddress>
</testCase>
<testCase id="000001">
<class>IdleSleep</class>
<desc>Sleep</desc>
<idle_sleep_time_in_sec>5</idle_sleep_time_in_sec>
</testCase>
<testCase id="000002">
<class>IdleSleep</class>
<desc>Sleep</desc>
<idle_sleep_time_in_sec>20</idle_sleep_time_in_sec>
</testCase>
<testCase id="050000">
<class>Ping</class>
<desc>Ping: 20 pings</desc>
<id>nrmodule2_quectel</id>
<ping_args>-c 20</ping_args>
<ping_packetloss_threshold>5</ping_packetloss_threshold>
</testCase>
<testCase id="050001">
<class>Ping</class>
<desc>Ping: 100 pings, size 1024</desc>
<id>nrmodule2_quectel</id>
<ping_args>-c 100 -s 1024 -i 0,2</ping_args>
<ping_packetloss_threshold>5</ping_packetloss_threshold>
</testCase>
<testCase id="070000">
<class>Iperf</class>
<desc>iperf (DL/26Mbps/UDP)(60 sec)(single-ue profile)</desc>
<iperf_args>-u -b 26M -t 60</iperf_args>
<direction>DL</direction>
<id>nrmodule2_quectel</id>
<iperf_packetloss_threshold>5</iperf_packetloss_threshold>
<iperf_profile>single-ue</iperf_profile>
</testCase>
<testCase id="070001">
<class>Iperf</class>
<desc>iperf (UL/7Mbps/UDP)(60 sec)(single-ue profile)</desc>
<iperf_args>-u -b 7M -t 60</iperf_args>
<direction>UL</direction>
<id>nrmodule2_quectel</id>
<iperf_packetloss_threshold>5</iperf_packetloss_threshold>
<iperf_profile>single-ue</iperf_profile>
</testCase>
<testCase id="080000">
<class>Terminate_eNB</class>
<desc>Terminate eNB</desc>
<eNB_instance>0</eNB_instance>
<eNB_serverId>0</eNB_serverId>
<air_interface>lte</air_interface>
</testCase>
<testCase id="080001">
<class>Terminate_eNB</class>
<desc>Terminate gNB</desc>
<eNB_instance>1</eNB_instance>
<eNB_serverId>1</eNB_serverId>
<air_interface>nr</air_interface>
</testCase>
</testCaseList>
......@@ -26,7 +26,7 @@
<htmlTabIcon>wrench</htmlTabIcon>
<TestCaseRequestedList>
000001 000002
000003 000004
000004 000005 000003
</TestCaseRequestedList>
<TestCaseExclusionList></TestCaseExclusionList>
......@@ -64,5 +64,10 @@
<eNB_serverId>1</eNB_serverId>
</testCase>
<testCase id="000005">
<class>IdleSleep</class>
<desc>Sleep</desc>
<idle_sleep_time_in_sec>120</idle_sleep_time_in_sec>
</testCase>
</testCaseList>
......@@ -21,8 +21,8 @@
-->
<testCaseList>
<htmlTabRef>TEST-NSA-FR1-TM1</htmlTabRef>
<htmlTabName>NSA Ping DL UL with QUECTEL</htmlTabName>
<htmlTabRef>TEST-NSA-FR1-TM2</htmlTabRef>
<htmlTabName>NSA 2x2 Ping DL UL with QUECTEL</htmlTabName>
<htmlTabIcon>tasks</htmlTabIcon>
<repeatCount>1</repeatCount>
<TestCaseRequestedList>
......@@ -32,6 +32,10 @@
010000
000001
050000
050001
000002
070000
070001
000001
010002
080001
......@@ -57,11 +61,12 @@
<testCase id="030000">
<class>Initialize_eNB</class>
<desc>Initialize eNB</desc>
<Initialize_eNB_args>-O ci-scripts/conf_files/enb.band38.nsa_2x2.100PRB.usrpn310.conf</Initialize_eNB_args>
<Initialize_eNB_args>-O ci-scripts/conf_files/enb.band38.nsa_2x2.100PRB.usrpn310.conf --usrp-tx-thread-config 1 --thread-pool 0,2,4,6</Initialize_eNB_args>
<eNB_instance>0</eNB_instance>
<eNB_serverId>0</eNB_serverId>
<air_interface>lte</air_interface>
<eNB_Trace>yes</eNB_Trace>
<eNB_Stats>yes</eNB_Stats>
<USRP_IPAddress>192.168.18.241</USRP_IPAddress>
</testCase>
......@@ -69,10 +74,11 @@
<testCase id="040000">
<class>Initialize_eNB</class>
<desc>Initialize gNB</desc>
<Initialize_eNB_args>-O ci-scripts/conf_files/gnb.band78.nsa_2x2.106PRB.usrpn310.conf -q</Initialize_eNB_args>
<Initialize_eNB_args>-O ci-scripts/conf_files/gnb.band78.nsa_2x2.106PRB.usrpn310.conf -q --usrp-tx-thread-config 1 --thread-pool 0,2,4,6</Initialize_eNB_args>
<eNB_instance>1</eNB_instance>
<eNB_serverId>1</eNB_serverId>
<air_interface>nr</air_interface>
<eNB_Stats>yes</eNB_Stats>
<USRP_IPAddress>192.168.18.240</USRP_IPAddress>
</testCase>
......@@ -94,15 +100,15 @@
<desc>Ping: 20pings in 20sec</desc>
<id>nrmodule2_quectel</id>
<ping_args>-c 20</ping_args>
<ping_packetloss_threshold>50</ping_packetloss_threshold>
<ping_packetloss_threshold>5</ping_packetloss_threshold>
</testCase>
<testCase id="050001">
<class>Ping</class>
<desc>Ping: 100pings in 20sec</desc>
<id>nrmodule2_quectel</id>
<ping_args>-c 100 -i 0.2</ping_args>
<ping_packetloss_threshold>50</ping_packetloss_threshold>
<ping_args>-c 100 -i 0,2</ping_args>
<ping_packetloss_threshold>5</ping_packetloss_threshold>
</testCase>
<testCase id="070000">
......@@ -111,17 +117,17 @@
<iperf_args>-u -b 20M -t 60</iperf_args>
<direction>DL</direction>
<id>nrmodule2_quectel</id>
<iperf_packetloss_threshold>50</iperf_packetloss_threshold>
<iperf_packetloss_threshold>5</iperf_packetloss_threshold>
<iperf_profile>single-ue</iperf_profile>
</testCase>
<testCase id="070001">
<class>Iperf</class>
<desc>iperf (UL/3Mbps/UDP)(60 sec)(single-ue profile)</desc>
<desc>iperf (UL/1Mbps/UDP)(20 sec)(single-ue profile)</desc>
<iperf_args>-u -b 3M -t 60</iperf_args>
<direction>UL</direction>
<id>nrmodule2_quectel</id>
<iperf_packetloss_threshold>50</iperf_packetloss_threshold>
<iperf_packetloss_threshold>5</iperf_packetloss_threshold>
<iperf_profile>single-ue</iperf_profile>
</testCase>
......
......@@ -33,7 +33,7 @@
<testCase id="000100">
<class>Deploy_EPC</class>
<desc>Deploy all EPC containers</desc>
<parameters>yaml_files/fr1_epc_tim</parameters>
<parameters>yaml_files/fr1_epc_20897</parameters>
</testCase>
</testCaseList>
......@@ -31,6 +31,9 @@
010000
000001
050000
050001
070000
070001
000001
010002
080000
......@@ -55,11 +58,12 @@
<testCase id="040000">
<class>Initialize_eNB</class>
<desc>Initialize gNB</desc>
<Initialize_eNB_args>-O ci-scripts/conf_files/gnb.band78.sa.fr1.106PRB.usrpn310.conf --sa -q</Initialize_eNB_args>
<Initialize_eNB_args>-O ci-scripts/conf_files/gnb.band78.sa.fr1.106PRB.2x2.usrpn310.conf --sa -q --usrp-tx-thread-config 1 --thread-pool 0,2,4,6</Initialize_eNB_args>
<eNB_instance>0</eNB_instance>
<eNB_serverId>0</eNB_serverId>
<air_interface>nr</air_interface>
<eNB_Trace>yes</eNB_Trace>
<eNB_Stats>yes</eNB_Stats>
<USRP_IPAddress>192.168.18.240</USRP_IPAddress>
</testCase>
......@@ -81,15 +85,15 @@
<desc>Ping: 20pings in 20sec</desc>
<id>nrmodule2_quectel</id>
<ping_args>-c 20</ping_args>
<ping_packetloss_threshold>50</ping_packetloss_threshold>
<ping_packetloss_threshold>5</ping_packetloss_threshold>
</testCase>
<testCase id="050001">
<class>Ping</class>
<desc>Ping: 100pings in 20sec</desc>
<id>nrmodule2_quectel</id>
<ping_args>-c 100 -i 0.2</ping_args>
<ping_packetloss_threshold>50</ping_packetloss_threshold>
<ping_args>-c 100 -i 0,2</ping_args>
<ping_packetloss_threshold>5</ping_packetloss_threshold>
</testCase>
<testCase id="070000">
......@@ -98,7 +102,7 @@
<iperf_args>-u -b 20M -t 60</iperf_args>
<direction>DL</direction>
<id>nrmodule2_quectel</id>
<iperf_packetloss_threshold>50</iperf_packetloss_threshold>
<iperf_packetloss_threshold>5</iperf_packetloss_threshold>
<iperf_profile>single-ue</iperf_profile>
</testCase>
......@@ -108,7 +112,7 @@
<iperf_args>-u -b 3M -t 60</iperf_args>
<direction>UL</direction>
<id>nrmodule2_quectel</id>
<iperf_packetloss_threshold>50</iperf_packetloss_threshold>
<iperf_packetloss_threshold>5</iperf_packetloss_threshold>
<iperf_profile>single-ue</iperf_profile>
</testCase>
......
......@@ -14,6 +14,8 @@
This page is only valid for an `Ubuntu18` host.
**NOTE: this version (2021-10-05) is valid for the `v1.1.0` and `v1.2.0` versions of the `OAI 5G CN`.**
**TABLE OF CONTENTS**
1. [Retrieving the images on Docker-Hub](#1-retrieving-the-images-on-docker-hub)
......@@ -26,6 +28,9 @@ This page is only valid for an `Ubuntu18` host.
2. [Start the iperf server inside the NR-UE container](#32-start-the-iperf-server-inside-the-nr-ue-container)
3. [Start the iperf client inside the ext-dn container](#33-start-the-iperf-client-inside-the-ext-dn-container)
4. [Un-deployment](#4-un-deployment)
5. [Explanations on the configuration in the docker-compose.yaml](##5-explanations-on-the-configuration-in-the-docker-composeyaml)
1. [Making the NR-UE connect to the core network](#51-making-the-nr-ue-connect-to-the-core-network)
2. [Making the gNB connect to the core network](#52-making-the-gnb-connect-to-the-core-network)
# 1. Retrieving the images on Docker-Hub #
......@@ -71,6 +76,10 @@ $ docker image tag rdefosseoai/oai-nr-ue:develop oai-nr-ue:develop
$ docker logout
```
**CAUTION: 2021/10/05 with the release `v1.2.0` of the `CN5G`, the previous version was not compatible any-more.**
**This new version is working for both the `v1.1.0` and `v1.2.0` of the `CN5G`.**
# 2. Deploy containers #
![Deployment](./oai-end-to-end.jpg)
......@@ -137,6 +146,8 @@ rfsim5g-traffic: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
## 2.2. Deploy OAI gNB in RF simulator mode and in Standalone Mode ##
**CAUTION: To execute this 2nd step, the whole `CN5G` SHALL be in `healthy` state (especially the `mysql` container).**
```bash
$ docker-compose up -d oai-gnb
rfsim5g-oai-nrf is up-to-date
......@@ -160,6 +171,18 @@ rfsim5g-oai-smf /bin/bash -c /openair-smf/ ... Up (healthy) 80/tcp, 880
rfsim5g-oai-spgwu /openair-spgwu-tiny/bin/en ... Up (healthy) 2152/udp, 8805/udp
```
You can verify that the `gNB` is connected with the `AMF`:
```bagh
$ docker logs rfsim5g-oai-amf
...
[AMF] [amf_app] [info ] |----------------------------------------------------gNBs' information-------------------------------------------|
[AMF] [amf_app] [info ] | Index | Status | Global ID | gNB Name | PLMN |
[AMF] [amf_app] [info ] | 1 | Connected | 0x0 | gnb-rfsim | 208, 99 |
[AMF] [amf_app] [info ] |----------------------------------------------------------------------------------------------------------------|
...
```
## 2.3. Deploy OAI NR-UE in RF simulator mode and in Standalone Mode ##
```bash
......@@ -366,3 +389,47 @@ Removing rfsim5g-mysql ... done
Removing network rfsim5g-oai-public-net
Removing network rfsim5g-oai-traffic_net-net
```
# 5. Explanations on the configuration in the `docker-compose.yaml` #
## 5.1. Making the NR-UE connect to the core network ##
The NR-UE **SHALL** be provisioned in the core network, especially in the `SQL` database and in the `AMF`.
* in AMF section of `docker-compose.yaml` --> `OPERATOR_KEY=c42449363bbad02b66d16bc975d77cc1`
* in NR-UE section --> `OPC: 'C42449363BBAD02B66D16BC975D77CC1'
Both values shall match!
This value is also present in the `oai_db.sql` file:
```bash
INSERT INTO `users` VALUES ('208990100001100','1','55000000000000',NULL,'PURGED',50,40000000,100000000,47,0000000000,1,0xfec86ba6eb707ed08905757b1bb44b8f,0,0,0x40,'ebd07771ace8677a',0xc42449363bbad02b66d16bc975d77cc1);
```
As you can see, 2 other values shall match in the NR-UE section of `docker-compose.yaml`:
* `FULL_IMSI: '208990100001100'`
* `FULL_KEY: 'fec86ba6eb707ed08905757b1bb44b8f'`
We are also using a dedicated `oai-smf.conf` for the `SMF` container: the `oai` DNN shall match the one in the NR-UE section of `docker-compose.yaml` (`DNN: oai`).
## 5.2. Making the gNB connect to the core network ##
Mainly you need to match the PLMN in `gNB`, `AMF` and `SPGWU` parameters:
* `AMF`
- `MCC=208`
- `MNC=99`
- `PLMN_SUPPORT_TAC=0x0001`
- ...
* `SPGWU`
- `MCC=208`
- `MNC=99`
- `TAC=1`
* `gNB`
- `MCC: '208'`
- `MNC: '99'`
- `TAC: 1`
The `ST` and `SD` values shall also match.
......@@ -90,11 +90,14 @@ services:
- USE_FQDN_DNS=yes
- NRF_API_VERSION=v1
- NRF_FQDN=oai-nrf
- AUSF_IPV4_ADDRESS=127.0.0.1
- EXTERNAL_AUSF=no
- AUSF_IPV4_ADDRESS=0.0.0.0
- AUSF_PORT=80
- AUSF_API_VERSION=v1
- AUSF_FQDN=localhost
depends_on:
- oai-nrf
- mysql
volumes:
- ./amf-healthcheck.sh:/openair-amf/bin/amf-healthcheck.sh
healthcheck:
......@@ -139,6 +142,7 @@ services:
- USE_FQDN_DNS=yes
depends_on:
- oai-nrf
- oai-amf
volumes:
- ./smf-healthcheck.sh:/openair-smf/bin/smf-healthcheck.sh
- ./oai-smf.conf:/openair-smf/bin/oai-smf.conf
......@@ -183,6 +187,7 @@ services:
- DNN_0=oai
depends_on:
- oai-nrf
- oai-smf
cap_add:
- NET_ADMIN
- SYS_ADMIN
......@@ -285,7 +290,7 @@ networks:
com.docker.network.bridge.name: "rfsim5g-public"
traffic_net:
driver: bridge
name: rfsim5g-oai-traffic_net-net
name: rfsim5g-oai-traffic-net
ipam:
config:
- subnet: 192.168.72.128/26
......
......@@ -51,7 +51,7 @@ services:
LTE_K: FEC86BA6EB707ED08905757B1BB44B8F
APN1: oai.ipv4
APN2: oai2.ipv4
FIRST_IMSI: 208990100001127
FIRST_IMSI: 208970100001127
NB_USERS: 5
healthcheck:
test: /bin/bash -c "pgrep oai_hss"
......@@ -78,7 +78,7 @@ services:
HSS_FQDN: hss.openairinterface.org
HSS_REALM: openairinterface.org
MCC: '208'
MNC: '99'
MNC: '97'
MME_GID: 32768
MME_CODE: 3
TAC_0: 1
......@@ -97,15 +97,15 @@ services:
PEER_MME_IPV4_ADDRESS_FOR_S10_0: 0.0.0.0
PEER_MME_IPV4_ADDRESS_FOR_S10_1: 0.0.0.0
MCC_SGW_0: '208'
MNC3_SGW_0: '099'
MNC3_SGW_0: '097'
TAC_LB_SGW_0: '01'
TAC_HB_SGW_0: '00'
MCC_MME_0: '208'
MNC3_MME_0: '099'
MNC3_MME_0: '097'
TAC_LB_MME_0: '02'
TAC_HB_MME_0: '00'
MCC_MME_1: '208'
MNC3_MME_1: '099'
MNC3_MME_1: '097'
TAC_LB_MME_1: '03'
TAC_HB_MME_1: '00'
TAC_LB_SGW_TEST_0: '03'
......@@ -138,11 +138,12 @@ services:
UE_IP_ADDRESS_POOL_1: '12.1.1.2 - 12.1.1.254'
UE_IP_ADDRESS_POOL_2: '12.0.0.2 - 12.0.0.254'
MCC: '208'
MNC: '99'
MNC03: '099'
MNC: '97'
MNC03: '097'
TAC: 1
GW_ID: 1
REALM: openairinterface.org
UE_MTU_IPV4: 1500
healthcheck:
test: /bin/bash -c "pgrep oai_spgwc"
interval: 10s
......@@ -168,8 +169,8 @@ services:
NETWORK_UE_IP: '12.1.1.0/24'
NETWORK_UE_NAT_OPTION: 'yes'
MCC: '208'
MNC: '99'
MNC03: '099'
MNC: '97'
MNC03: '097'
TAC: 1
GW_ID: 1
REALM: openairinterface.org
......
version: '3.8'
services:
cassandra:
image: cassandra:2.1
container_name: prod-cassandra
networks:
private_net:
ipv4_address: 192.168.68.2
environment:
CASSANDRA_CLUSTER_NAME: "OAI HSS Cluster"
CASSANDRA_ENDPOINT_SNITCH: GossipingPropertyFileSnitch
healthcheck:
test: /bin/bash -c "nodetool status"
interval: 10s
timeout: 5s
retries: 5
db_init:
image: cassandra:2.1
container_name: prod-db-init
depends_on: [cassandra]
deploy:
restart_policy:
condition: on-failure
max_attempts: 10
networks:
private_net:
ipv4_address: 192.168.68.4
volumes:
- ./oai_db.cql:/home/oai_db.cql
entrypoint: /bin/bash -c "cqlsh --file /home/oai_db.cql 192.168.68.2 && echo 'OK'"
oai_hss:
image: oai-hss:production
container_name: prod-oai-hss
privileged: true
depends_on: [cassandra]
networks:
private_net:
ipv4_address: 192.168.68.3
public_net:
ipv4_address: 192.168.61.2
environment:
REALM: openairinterface.org
HSS_FQDN: hss.openairinterface.org
PREFIX: /openair-hss/etc
cassandra_Server_IP: 192.168.68.2
OP_KEY: 1006020f0a478bf6b699f15c062e42b3
LTE_K: fec86ba6eb707ed08905757b1bb44b8f
APN1: oai.ipv4
APN2: internet
FIRST_IMSI: 222010100001120
NB_USERS: 10
healthcheck:
test: /bin/bash -c "pgrep oai_hss"
interval: 10s
timeout: 5s
retries: 5
oai_mme:
image: oai-mme:production
container_name: prod-oai-mme
privileged: true
depends_on: [oai_hss]
networks:
public_net:
ipv4_address: 192.168.61.3
environment:
REALM: openairinterface.org
PREFIX: /openair-mme/etc
INSTANCE: 1
PID_DIRECTORY: /var/run
HSS_IP_ADDR: 192.168.61.2
HSS_HOSTNAME: hss
HSS_FQDN: hss.openairinterface.org
HSS_REALM: openairinterface.org
MCC: '222'
MNC: '01'
MME_GID: 32768
MME_CODE: 3
TAC_0: 1
TAC_1: 2
TAC_2: 3
MME_FQDN: mme.openairinterface.org
MME_S6A_IP_ADDR: 192.168.61.3
MME_INTERFACE_NAME_FOR_S1_MME: eth0
MME_IPV4_ADDRESS_FOR_S1_MME: 192.168.61.3
MME_INTERFACE_NAME_FOR_S11: eth0
MME_IPV4_ADDRESS_FOR_S11: 192.168.61.3
MME_INTERFACE_NAME_FOR_S10: lo
MME_IPV4_ADDRESS_FOR_S10: 127.0.0.10
OUTPUT: CONSOLE
SGW_IPV4_ADDRESS_FOR_S11_0: 192.168.61.4
PEER_MME_IPV4_ADDRESS_FOR_S10_0: 0.0.0.0
PEER_MME_IPV4_ADDRESS_FOR_S10_1: 0.0.0.0
MCC_SGW_0: '222'
MNC3_SGW_0: '001'
TAC_LB_SGW_0: '01'
TAC_HB_SGW_0: '00'
MCC_MME_0: '222'
MNC3_MME_0: '001'
TAC_LB_MME_0: '02'
TAC_HB_MME_0: '00'
MCC_MME_1: '222'
MNC3_MME_1: '001'
TAC_LB_MME_1: '03'
TAC_HB_MME_1: '00'
TAC_LB_SGW_TEST_0: '03'
TAC_HB_SGW_TEST_0: '00'
SGW_IPV4_ADDRESS_FOR_S11_TEST_0: 0.0.0.0
healthcheck:
test: /bin/bash -c "pgrep oai_mme"
interval: 10s
timeout: 5s
retries: 5
oai_spgwc:
image: oai-spgwc:production
privileged: true
depends_on: [oai_mme]
container_name: prod-oai-spgwc
networks:
public_net:
ipv4_address: 192.168.61.4
environment:
PID_DIRECTORY: /var/run
SGW_INTERFACE_NAME_FOR_S11: eth0
SGW_IP_FOR_S5_S8_CP: 127.0.0.11/8
PGW_IP_FOR_S5_S8_CP: 127.0.0.12/8
PGW_INTERFACE_NAME_FOR_SX: eth0
DEFAULT_APN: oai.ipv4
DEFAULT_DNS_IPV4_ADDRESS: 192.168.18.129
DEFAULT_DNS_SEC_IPV4_ADDRESS: 8.8.4.4
UE_IP_ADDRESS_POOL: '12.1.1.2 - 12.1.1.254'
PUSH_PROTOCOL_OPTION: 'yes'
healthcheck:
test: /bin/bash -c "pgrep oai_spgwc"
interval: 10s
timeout: 5s
retries: 5
oai_spgwu:
image: oai-spgwu-tiny:production
privileged: true
container_name: prod-oai-spgwu-tiny
depends_on: [oai_spgwc]
networks:
public_net:
ipv4_address: 192.168.61.5
environment:
PID_DIRECTORY: /var/run
INSTANCE: 1
SGW_INTERFACE_NAME_FOR_S1U_S12_S4_UP: eth0
PGW_INTERFACE_NAME_FOR_SGI: eth0
SGW_INTERFACE_NAME_FOR_SX: eth0
SPGWC0_IP_ADDRESS: 192.168.61.4
NETWORK_UE_IP: '12.1.1.0/24'
NETWORK_UE_NAT_OPTION: 'yes'
healthcheck:
test: /bin/bash -c "pgrep oai_spgwu"
interval: 10s
timeout: 5s
retries: 5
flexran_rtc:
image: flexran-rtc:production
privileged: true
container_name: prod-flexran-rtc
networks:
public_net:
ipv4_address: 192.168.61.10
healthcheck:
test: /bin/bash -c "pgrep rt_controller"
interval: 10s
timeout: 5s
retries: 5
trf_gen:
image: trf-gen:production
privileged: true
container_name: prod-trf-gen
networks:
public_net:
ipv4_address: 192.168.61.11
entrypoint: /bin/bash -c "ip route add 12.1.1.0/24 via 192.168.61.5 dev eth0; sleep infinity"
healthcheck:
test: /bin/bash -c "ping -c 2 192.168.61.5"
interval: 10s
timeout: 5s
retries: 5
networks:
private_net:
name: prod-oai-private-net
ipam:
config:
- subnet: 192.168.68.0/26
public_net:
name: prod-oai-public-net
ipam:
config:
- subnet: 192.168.61.0/26
......@@ -275,6 +275,23 @@ THREAD_STRUCT = (
}
);
security = {
# preferred ciphering algorithms
# the first one of the list that an UE supports in chosen
# valid values: nea0, nea1, nea2, nea3
ciphering_algorithms = ( "nea0" );
# preferred integrity algorithms
# the first one of the list that an UE supports in chosen
# valid values: nia0, nia1, nia2, nia3
integrity_algorithms = ( "nia2", "nia0" );
# setting 'drb_ciphering' to "no" disables ciphering for DRBs, no matter
# what 'ciphering_algorithms' configures; same thing for 'drb_integrity'
drb_ciphering = "yes";
drb_integrity = "no";
};
log_config :
{
global_log_level ="info";
......
......@@ -49,6 +49,7 @@
#include "SCHED_NR/fapi_nr_l1.h"
#include "PHY/NR_TRANSPORT/nr_transport_proto.h"
#include "PHY/MODULATION/nr_modulation.h"
#include "PHY/NR_TRANSPORT/nr_dlsch.h"
#undef MALLOC //there are two conflicting definitions, so we better make sure we don't use it at all
//#undef FRAME_LENGTH_COMPLEX_SAMPLES //there are two conflicting definitions, so we better make sure we don't use it at all
......@@ -88,6 +89,7 @@
#include "executables/softmodem-common.h"
#include <nfapi/oai_integration/nfapi_pnf.h>
#include <openair1/PHY/NR_TRANSPORT/nr_ulsch.h>
#include <openair1/PHY/NR_TRANSPORT/nr_dlsch.h>
#include <PHY/NR_ESTIMATION/nr_ul_estimation.h>
//#define DEBUG_THREADS 1
......@@ -114,19 +116,36 @@ time_stats_t softmodem_stats_rx_sf; // total rx time
void tx_func(void *param) {
processingData_L1_t *info = (processingData_L1_t *) param;
processingData_L1tx_t *info = (processingData_L1tx_t *) param;
PHY_VARS_gNB *gNB = info->gNB;
int frame_tx = info->frame_tx;
int slot_tx = info->slot_tx;
int frame_tx = info->frame;
int slot_tx = info->slot;
phy_procedures_gNB_TX(info,
frame_tx,
slot_tx,
1);
info->slot = -1;
//if ((frame_tx&127) == 0) dump_pdsch_stats(fd,gNB);
phy_procedures_gNB_TX(gNB, frame_tx,slot_tx, 1);
// If the later of the 2 L1 tx thread finishes first,
// we wait for the earlier one to finish and start the RU thread
// to avoid realtime issues with USRP
// start FH TX processing
// Start RU TX processing.
notifiedFIFO_elt_t *res;
res = pullTpool(gNB->resp_RU_tx, gNB->threadPool);
processingData_RU_t *syncMsg = (processingData_RU_t *)NotifiedFifoData(res);
LOG_D(PHY,"waiting for previous tx to finish, next slot %d,%d\n",syncMsg->next_slot,slot_tx);
while (syncMsg->next_slot != slot_tx) {
pushNotifiedFIFO(gNB->resp_RU_tx, res);
res = pullTpool(gNB->resp_RU_tx, gNB->threadPool);
syncMsg = (processingData_RU_t *)NotifiedFifoData(res);
}
LOG_D(PHY,"previous tx finished, next slot %d,%d\n",syncMsg->next_slot,slot_tx);
syncMsg->frame_tx = frame_tx;
syncMsg->slot_tx = slot_tx;
syncMsg->next_slot = get_next_downlink_slot(gNB, &gNB->gNB_config, frame_tx, slot_tx);
syncMsg->timestamp_tx = info->timestamp_tx;
syncMsg->ru = gNB->RU_list[0];
res->key = slot_tx;
......@@ -184,7 +203,7 @@ void rx_func(void *param) {
int down_removed = 0;
int pucch_removed = 0;
for (int i = 0; i < rnti_to_remove_count; i++) {
LOG_W(PHY, "to remove rnti %d\n", rnti_to_remove[i]);
LOG_W(NR_PHY, "to remove rnti %d\n", rnti_to_remove[i]);
void clean_gNB_ulsch(NR_gNB_ULSCH_t *ulsch);
void clean_gNB_dlsch(NR_gNB_DLSCH_t *dlsch);
int j;
......@@ -201,13 +220,6 @@ void rx_func(void *param) {
}
up_removed++;
}
for (j = 0; j < NUMBER_OF_NR_DLSCH_MAX; j++)
if (gNB->dlsch[j][0]->rnti == rnti_to_remove[i]) {
gNB->dlsch[j][0]->rnti = 0;
gNB->dlsch[j][0]->harq_mask = 0;
//clean_gNB_dlsch(gNB->dlsch[j][0]);
down_removed++;
}
for (j = 0; j < NUMBER_OF_NR_PUCCH_MAX; j++)
if (gNB->pucch[j]->active > 0 &&
gNB->pucch[j]->pucch_pdu.rnti == rnti_to_remove[i]) {
......@@ -224,7 +236,7 @@ void rx_func(void *param) {
gNB->prach_vars.list[j].frame = -1;
#endif
}
if (rnti_to_remove_count) LOG_W(PHY, "to remove rnti_to_remove_count=%d, up_removed=%d down_removed=%d pucch_removed=%d\n", rnti_to_remove_count, up_removed, down_removed, pucch_removed);
if (rnti_to_remove_count) LOG_W(NR_PHY, "to remove rnti_to_remove_count=%d, up_removed=%d down_removed=%d pucch_removed=%d\n", rnti_to_remove_count, up_removed, down_removed, pucch_removed);
rnti_to_remove_count = 0;
if (pthread_mutex_unlock(&rnti_to_remove_mutex)) exit(1);
......@@ -255,7 +267,6 @@ void rx_func(void *param) {
LOG_D(PHY,"%s() Exit proc[rx:%d%d tx:%d%d]\n", __FUNCTION__, frame_rx, slot_rx, frame_tx, slot_tx);
// Call the scheduler
start_meas(&gNB->ul_indication_stats);
pthread_mutex_lock(&gNB->UL_INFO_mutex);
gNB->UL_INFO.frame = frame_rx;
......@@ -266,16 +277,17 @@ void rx_func(void *param) {
pthread_mutex_unlock(&gNB->UL_INFO_mutex);
stop_meas(&gNB->ul_indication_stats);
notifiedFIFO_elt_t *res;
if (tx_slot_type == NR_DOWNLINK_SLOT || tx_slot_type == NR_MIXED_SLOT) {
notifiedFIFO_elt_t *res;
res = pullTpool(gNB->resp_L1_tx, gNB->threadPool);
processingData_L1tx_t *syncMsg = (processingData_L1tx_t *)NotifiedFifoData(res);
while (syncMsg->slot != slot_tx) {
pushNotifiedFIFO(gNB->resp_L1_tx, res);
res = pullTpool(gNB->resp_L1_tx, gNB->threadPool);
processingData_L1_t *syncMsg = (processingData_L1_t *)NotifiedFifoData(res);
syncMsg = (processingData_L1tx_t *)NotifiedFifoData(res);
}
syncMsg->gNB = gNB;
syncMsg->frame_rx = frame_rx;
syncMsg->slot_rx = slot_rx;
syncMsg->frame_tx = frame_tx;
syncMsg->slot_tx = slot_tx;
AssertFatal(syncMsg->slot == slot_tx, "Thread message slot and logical slot number do not match\n");
syncMsg->timestamp_tx = info->timestamp_tx;
res->key = slot_tx;
pushTpool(gNB->threadPool, res);
......@@ -325,7 +337,6 @@ static void *process_stats_thread(void *param) {
PHY_VARS_gNB *gNB = (PHY_VARS_gNB *)param;
reset_meas(&gNB->phy_proc_tx);
reset_meas(&gNB->dlsch_encoding_stats);
reset_meas(&gNB->phy_proc_rx);
reset_meas(&gNB->ul_indication_stats);
......@@ -337,7 +348,8 @@ static void *process_stats_thread(void *param) {
while(!oai_exit)
{
sleep(1);
print_meas(&gNB->phy_proc_tx, "L1 Tx processing", NULL, NULL);
print_meas(gNB->phy_proc_tx_0, "L1 Tx processing thread 0", NULL, NULL);
print_meas(gNB->phy_proc_tx_1, "L1 Tx processing thread 1", NULL, NULL);
print_meas(&gNB->dlsch_encoding_stats, "DLSCH encoding", NULL, NULL);
print_meas(&gNB->phy_proc_rx, "L1 Rx processing", NULL, NULL);
print_meas(&gNB->ul_indication_stats, "UL Indication", NULL, NULL);
......@@ -356,6 +368,7 @@ void *nrL1_stats_thread(void *param) {
fd=fopen("nrL1_stats.log","w");
AssertFatal(fd!=NULL,"Cannot open nrL1_stats.log\n");
dump_nr_I0_stats(fd,gNB);
dump_pdsch_stats(fd,gNB);
dump_pusch_stats(fd,gNB);
// nr_dump_uci_stats(fd,eNB,eNB->proc.L1_proc_tx.frame_tx);
fclose(fd);
......@@ -390,14 +403,38 @@ void init_gNB_Tpool(int inst) {
// L1 RX result FIFO
gNB->resp_L1 = (notifiedFIFO_t*) malloc(sizeof(notifiedFIFO_t));
initNotifiedFIFO(gNB->resp_L1);
notifiedFIFO_elt_t *msg = newNotifiedFIFO_elt(sizeof(processingData_L1_t),0,gNB->resp_L1,rx_func);
pushNotifiedFIFO(gNB->resp_L1,msg); // to unblock the process in the beginning
// L1 TX result FIFO
gNB->resp_L1_tx = (notifiedFIFO_t*) malloc(sizeof(notifiedFIFO_t));
initNotifiedFIFO(gNB->resp_L1_tx);
// we create 2 threads for L1 tx processing
notifiedFIFO_elt_t *msgL1Tx = newNotifiedFIFO_elt(sizeof(processingData_L1tx_t),0,gNB->resp_L1_tx,tx_func);
processingData_L1tx_t *msgDataTx = (processingData_L1tx_t *)NotifiedFifoData(msgL1Tx);
init_DLSCH_struct(gNB, msgDataTx);
msgDataTx->slot = -1;
memset(msgDataTx->ssb, 0, 64*sizeof(NR_gNB_SSB_t));
reset_meas(&msgDataTx->phy_proc_tx);
gNB->phy_proc_tx_0 = &msgDataTx->phy_proc_tx;
pushNotifiedFIFO(gNB->resp_L1_tx,msgL1Tx); // to unblock the process in the beginning
msgL1Tx = newNotifiedFIFO_elt(sizeof(processingData_L1tx_t),0,gNB->resp_L1_tx,tx_func);
msgDataTx = (processingData_L1tx_t *)NotifiedFifoData(msgL1Tx);
init_DLSCH_struct(gNB, msgDataTx);
msgDataTx->slot = -1;
memset(msgDataTx->ssb, 0, 64*sizeof(NR_gNB_SSB_t));
reset_meas(&msgDataTx->phy_proc_tx);
gNB->phy_proc_tx_1 = &msgDataTx->phy_proc_tx;
pushNotifiedFIFO(gNB->resp_L1_tx,msgL1Tx); // to unblock the process in the beginning
// RU TX result FIFO
gNB->resp_RU_tx = (notifiedFIFO_t*) malloc(sizeof(notifiedFIFO_t));
initNotifiedFIFO(gNB->resp_RU_tx);
notifiedFIFO_elt_t *msgRUTx = newNotifiedFIFO_elt(sizeof(processingData_RU_t),0,gNB->resp_RU_tx,ru_tx_func);
processingData_RU_t *msgData = (processingData_RU_t*)msgRUTx->msgData;
msgData->next_slot = sf_ahead*gNB->frame_parms.slots_per_subframe; // first Tx slot
pushNotifiedFIFO(gNB->resp_RU_tx,msgRUTx); // to unblock the process in the beginning
// Stats measurement thread
if(opp_enabled == 1) threadCreate(&proc->process_stats_thread, process_stats_thread,(void *)gNB, "time_meas", -1, OAI_PRIORITY_RT_LOW);
......
This diff is collapsed.
......@@ -329,7 +329,7 @@ void set_options(int CC_id, PHY_VARS_NR_UE *UE){
LOG_I(PHY, "Set UE frame_type %d\n", fp->frame_type);
}
LOG_I(PHY, "Set UE nb_rx_antenna %d, nb_tx_antenna %d, threequarter_fs %d\n", fp->nb_antennas_rx, fp->nb_antennas_tx, fp->threequarter_fs);
LOG_I(PHY, "Set UE nb_rx_antenna %d, nb_tx_antenna %d, threequarter_fs %d, ssb_start_subcarrier %d\n", fp->nb_antennas_rx, fp->nb_antennas_tx, fp->threequarter_fs, fp->ssb_start_subcarrier);
fp->ofdm_offset_divisor = nrUE_params.ofdm_offset_divisor;
......
......@@ -50,7 +50,7 @@
{ NOL2CONNECT_OPT, CONFIG_HLP_NOL2CN, PARAMFLAG_BOOL, uptr:NULL, defuintval:1, TYPE_INT, 0}, \
{ CALIBPRACH_OPT, CONFIG_HLP_CALPRACH, PARAMFLAG_BOOL, uptr:NULL, defuintval:1, TYPE_INT, 0}, \
{ DUMPFRAME_OPT, CONFIG_HLP_DUMPFRAME, PARAMFLAG_BOOL, iptr:&dumpframe, defintval:0, TYPE_INT, 0}, \
{"ue-rxgain", CONFIG_HLP_UERXG, 0, dblptr:&(rx_gain[0][0]), defdblval:0, TYPE_DOUBLE,0}, \
{"ue-rxgain", CONFIG_HLP_UERXG, 0, dblptr:&(rx_gain[0][0]), defdblval:110, TYPE_DOUBLE,0}, \
{"ue-rxgain-off", CONFIG_HLP_UERXGOFF, 0, dblptr:&rx_gain_off, defdblval:0, TYPE_DOUBLE,0}, \
{"ue-txgain", CONFIG_HLP_UETXG, 0, dblptr:&(tx_gain[0][0]), defdblval:0, TYPE_DOUBLE,0}, \
{"ue-nb-ant-rx", CONFIG_HLP_UENANTR, 0, u8ptr:&(fp->nb_antennas_rx), defuintval:1, TYPE_UINT8, 0}, \
......
......@@ -156,7 +156,7 @@ extern int usrp_tx_thread;
{"nbiot-disable", CONFIG_HLP_DISABLNBIOT, PARAMFLAG_BOOL, uptr:&nonbiot, defuintval:0, TYPE_INT, 0}, \
{"use-256qam-table", CONFIG_HLP_256QAM, PARAMFLAG_BOOL, iptr:&USE_256QAM_TABLE, defintval:0, TYPE_INT, 0}, \
{"do-prb-interpolation", CONFIG_HLP_PRBINTER, PARAMFLAG_BOOL, iptr:&PRB_INTERPOLATION, defintval:0, TYPE_INT, 0}, \
{"usrp-tx-thread-config",CONFIG_HLP_USRP_THREAD, 0, iptr:&usrp_tx_thread, defstrval:0, TYPE_INT, 0}, \
{"usrp-tx-thread-config", CONFIG_HLP_USRP_THREAD, 0, iptr:&usrp_tx_thread, defstrval:0, TYPE_INT, 0}, \
{"nfapi", CONFIG_HLP_NFAPI, 0, u8ptr:&nfapi_mode, defintval:0, TYPE_UINT8, 0}, \
{"non-stop", CONFIG_HLP_NONSTOP, PARAMFLAG_BOOL, iptr:&NON_STOP, defintval:0, TYPE_INT, 0}, \
}
......
......@@ -1104,25 +1104,70 @@ void pnf_phy_deallocate_p7_vendor_ext(nfapi_p7_message_header_t *header) {
free(header);
}
notifiedFIFO_elt_t *l1tx_message_extract(PHY_VARS_gNB *gNB, int frame, int slot) {
notifiedFIFO_elt_t *res;
notifiedFIFO_elt_t *freeRes = NULL;
// check first message
res = pullTpool(gNB->resp_L1_tx, gNB->threadPool);
processingData_L1tx_t *msgTx = (processingData_L1tx_t *)NotifiedFifoData(res);
if (msgTx->slot == slot) {
return res;
}
if (msgTx->slot == -1) {
freeRes = res;
}
// check second message
pushNotifiedFIFO(gNB->resp_L1_tx,res);
res = pullTpool(gNB->resp_L1_tx, gNB->threadPool);
msgTx = (processingData_L1tx_t *)NotifiedFifoData(res);
if (msgTx->slot == slot) {
return res;
}
if (msgTx->slot == -1) {
freeRes = res;
}
if (freeRes) {
msgTx = (processingData_L1tx_t *)NotifiedFifoData(res);
msgTx->num_pdsch_slot=0;
msgTx->pdcch_pdu.pdcch_pdu_rel15.numDlDci = 0;
msgTx->ul_pdcch_pdu.pdcch_pdu.pdcch_pdu_rel15.numDlDci = 0;
msgTx->slot = slot;
msgTx->frame = frame;
return freeRes;
}
pushNotifiedFIFO(gNB->resp_L1_tx,res);
AssertFatal(1==0, "It means both L1 Tx messages are still waiting to be processed. This happens when L1 Tx processing is too slow. Message slot %d, scheduled slot %d\n",
msgTx->slot, slot);
}
int pnf_phy_ul_dci_req(gNB_L1_rxtx_proc_t *proc, nfapi_pnf_p7_config_t *pnf_p7, nfapi_nr_ul_dci_request_t *req) {
// LOG_D(PHY,"[PNF] HI_DCI0_REQUEST SFN/SF:%05d dci:%d hi:%d\n", NFAPI_SFNSF2DEC(req->sfn_sf), req->hi_dci0_request_body.number_of_dci, req->hi_dci0_request_body.number_of_hi);
struct PHY_VARS_gNB_s *gNB = RC.gNB[0];
// extract the next available thread message (priority to message with current slot, then free message)
notifiedFIFO_elt_t *res;
res = l1tx_message_extract(gNB, req->SFN, req->Slot);
processingData_L1tx_t *msgTx = (processingData_L1tx_t *)NotifiedFifoData(res);
if (proc ==NULL)
proc = &gNB->proc.L1_proc;
for (int i=0; i<req->numPdus; i++) {
if (req->ul_dci_pdu_list[i].PDUType == 0) {
nfapi_nr_ul_dci_request_pdus_t *ul_dci_req_pdu = &req->ul_dci_pdu_list[i];
handle_nfapi_nr_ul_dci_pdu(gNB, req->SFN, req->Slot, ul_dci_req_pdu);
if (req->numPdus > 0) {
if (req->ul_dci_pdu_list[req->numPdus-1].PDUType == 0) { // copy only the last PDU (PHY can have only one UL PDCCH pdu)
msgTx->ul_pdcch_pdu = req->ul_dci_pdu_list[req->numPdus-1]; // copy the last pdu
}
else {
LOG_E(PHY,"[PNF] UL_DCI_REQ sfn_slot:%d PDU[%d] - unknown pdu type:%d\n", NFAPI_SFNSLOT2DEC(req->SFN, req->Slot), i, req->ul_dci_pdu_list[i].PDUType);
LOG_E(PHY,"[PNF] UL_DCI_REQ sfn_slot:%d PDU[%d] - unknown pdu type:%d\n", NFAPI_SFNSLOT2DEC(req->SFN, req->Slot), req->numPdus-1, req->ul_dci_pdu_list[req->numPdus-1].PDUType);
}
}
pushNotifiedFIFO(gNB->resp_L1_tx,res);
return 0;
}
......@@ -1193,14 +1238,17 @@ int pnf_phy_dl_tti_req(gNB_L1_rxtx_proc_t *proc, nfapi_pnf_p7_config_t *pnf_p7,
for (int i=0; i<req->dl_tti_request_body.nPDUs; i++) {
// NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() sfn/sf:%d PDU[%d] size:%d pdcch_vars->num_dci:%d\n", __FUNCTION__, NFAPI_SFNSF2DEC(req->sfn_sf), i, dl_config_pdu_list[i].pdu_size,pdcch_vars->num_dci);
notifiedFIFO_elt_t *res;
res = l1tx_message_extract(gNB, sfn, slot);
processingData_L1tx_t *msgTx = (processingData_L1tx_t *)NotifiedFifoData(res);
if (dl_tti_pdu_list[i].PDUType == NFAPI_NR_DL_TTI_PDCCH_PDU_TYPE) {
nfapi_nr_dl_tti_request_pdu_t *dl_tti_pdu=&dl_tti_pdu_list[i];
handle_nfapi_nr_pdcch_pdu(gNB, sfn, slot, &dl_tti_pdu->pdcch_pdu);
// we trust the scheduler sends only one PDCCH PDU per slot
msgTx->pdcch_pdu = dl_tti_pdu_list[i].pdcch_pdu; // fills the last received PDCCH PDU
}
else if (dl_tti_pdu_list[i].PDUType == NFAPI_NR_DL_TTI_SSB_PDU_TYPE) {
//NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() PDU:%d BCH: pdu_index:%u pdu_length:%d sdu_length:%d BCH_SDU:%x,%x,%x\n", __FUNCTION__, i, pdu_index, bch_pdu->bch_pdu_rel8.length, tx_request_pdu[sfn][sf][pdu_index]->segments[0].segment_length, sdu[0], sdu[1], sdu[2]);
handle_nr_nfapi_ssb_pdu(gNB, sfn, slot, &dl_tti_pdu_list[i]);
handle_nr_nfapi_ssb_pdu(msgTx, sfn, slot, &dl_tti_pdu_list[i]);
gNB->pbch_configured=1;
}
else if (dl_tti_pdu_list[i].PDUType == NFAPI_NR_DL_TTI_PDSCH_PDU_TYPE) {
......@@ -1209,21 +1257,11 @@ int pnf_phy_dl_tti_req(gNB_L1_rxtx_proc_t *proc, nfapi_pnf_p7_config_t *pnf_p7,
nfapi_nr_pdu_t *tx_data = tx_data_request[sfn][slot][rel15_pdu->pduIndex];
if (tx_data != NULL) {
int UE_id = find_nr_dlsch(rel15_pdu->rnti,gNB,SEARCH_EXIST_OR_FREE);
AssertFatal(UE_id!=-1,"no free or exiting dlsch_context\n");
AssertFatal(UE_id<NUMBER_OF_UE_MAX,"returned UE_id %d >= %d(NUMBER_OF_UE_MAX)\n",UE_id,NUMBER_OF_UE_MAX);
NR_gNB_DLSCH_t *dlsch0 = gNB->dlsch[UE_id][0];
int harq_pid = dlsch0->harq_ids[sfn%2][slot];
if(harq_pid >= dlsch0->Mdlharq) {
LOG_E(PHY,"pnf_phy_dl_config_req illegal harq_pid %d\n", harq_pid);
return(-1);
}
uint8_t *dlsch_sdu = nr_tx_pdus[UE_id][harq_pid];
memcpy(dlsch_sdu, tx_data->TLVs[0].value.direct,tx_data->PDU_length);
uint8_t *dlsch_sdu = (uint8_t *)tx_data->TLVs[0].value.direct;
//NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() DLSCH:pdu_index:%d handle_nfapi_dlsch_pdu(eNB, proc_rxtx, dlsch_pdu, transport_blocks:%d sdu:%p) eNB->pdcch_vars[proc->subframe_tx & 1].num_pdcch_symbols:%d\n", __FUNCTION__, rel8_pdu->pdu_index, rel8_pdu->transport_blocks, dlsch_sdu, eNB->pdcch_vars[proc->subframe_tx & 1].num_pdcch_symbols);
handle_nr_nfapi_pdsch_pdu(gNB, sfn, slot,pdsch_pdu, dlsch_sdu);
AssertFatal(msgTx->num_pdsch_slot < gNB->number_of_nr_dlsch_max,"Number of PDSCH PDUs %d exceeded the limit %d\n",
msgTx->num_pdsch_slot,gNB->number_of_nr_dlsch_max);
handle_nr_nfapi_pdsch_pdu(msgTx, pdsch_pdu, dlsch_sdu);
}
else {
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s() DLSCH NULL TX PDU SFN/SF:%d PDU_INDEX:%d\n", __FUNCTION__, NFAPI_SFNSLOT2DEC(sfn,slot), rel15_pdu->pduIndex);
......@@ -1231,11 +1269,12 @@ int pnf_phy_dl_tti_req(gNB_L1_rxtx_proc_t *proc, nfapi_pnf_p7_config_t *pnf_p7,
}
else if (dl_tti_pdu_list[i].PDUType == NFAPI_NR_DL_TTI_CSI_RS_PDU_TYPE) {
nfapi_nr_dl_tti_csi_rs_pdu *csi_rs_pdu = &dl_tti_pdu_list[i].csi_rs_pdu;
handle_nfapi_nr_csirs_pdu(gNB, sfn, slot, csi_rs_pdu);
handle_nfapi_nr_csirs_pdu(msgTx, sfn, slot, csi_rs_pdu);
}
else {
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s() UNKNOWN:%d\n", __FUNCTION__, dl_tti_pdu_list[i].PDUType);
}
pushNotifiedFIFO(gNB->resp_L1_tx,res);
}
if(req->vendor_extension)
......
......@@ -55,7 +55,6 @@ int32_t nrLDPC_decod(t_nrLDPC_dec_params* p_decParams, int8_t* p_llr, int8_t* p_
t_nrLDPC_lut* p_lut = &lut;
//printf("p_procBuf->cnProcBuf = %p\n", p_procBuf->cnProcBuf);
// Initialize decoder core(s) with correct LUTs
numLLR = nrLDPC_init(p_decParams, p_lut);
......@@ -231,7 +230,7 @@ static inline uint32_t nrLDPC_decoder_core(int8_t* p_llr, int8_t* p_out, t_nrLDP
// First iteration finished
while ( (i < (numMaxIter-1)) && (pcRes != 0) )
while ( (i < numMaxIter) && (pcRes != 0) )
{
// Increase iteration counter
i++;
......
......@@ -258,10 +258,11 @@ static inline void polar_rate_matching(const t_nrPolar_params *polarParams,void
// handle rate matching with a single 128 bit word using bit shuffling
// can be done with SIMD intrisics if needed
if (polarParams->groupsize < 8) {
AssertFatal(polarParams->encoderLength<=128,"Need to handle groupsize<8 and N>128\n");
AssertFatal(polarParams->encoderLength<=512,"Need to handle groupsize(%d)<8 and N(%d)>512\n",polarParams->groupsize,polarParams->encoderLength);
uint128_t *out128=(uint128_t*)out;
uint128_t *in128=(uint128_t*)in;
*out128=0;
for (int i=0;i<polarParams->encoderLength>>7;i++)
out128[i]=0;
uint128_t tmp0;
#ifdef DEBUG_POLAR_ENCODER
uint128_t tmp1;
......@@ -270,11 +271,17 @@ static inline void polar_rate_matching(const t_nrPolar_params *polarParams,void
#ifdef DEBUG_POLAR_ENCODER
printf("%d<-%u : %llx.%llx =>",i,polarParams->rate_matching_pattern[i],((uint64_t *)out)[1],((uint64_t *)out)[0]);
#endif
tmp0 = (*in128&(((uint128_t)1)<<polarParams->rate_matching_pattern[i]));
uint8_t pi=polarParams->rate_matching_pattern[i];
uint8_t pi7=pi>>7;
uint8_t pimod128=pi&127;
uint8_t imod128=i&127;
uint8_t i7=i>>7;
tmp0 = (in128[pi7]&(((uint128_t)1)<<(pimod128)));
if (tmp0!=0) {
*out128 = *out128 | ((uint128_t)1)<<i;
out128[i7] = out128[i7] | ((uint128_t)1)<<imod128;
#ifdef DEBUG_POLAR_ENCODER
tmp1 = ((uint128_t)1)<<i;
printf("%llx.%llx<->%llx.%llx => %llx.%llx\n",
((uint64_t *)&tmp0)[1],((uint64_t *)&tmp0)[0],
((uint64_t *)&tmp1)[1],((uint64_t *)&tmp1)[0],
......
......@@ -92,9 +92,7 @@ if ((Kprime%Kb) > 0)
else
Z = (Kprime/Kb);
#ifdef DEBUG_SEGMENTATION
printf("nr segmetation B %u Bprime %u Kprime %u z %u \n", B, Bprime, Kprime, Z);
#endif
LOG_D(PHY,"nr segmetation B %u Bprime %u Kprime %u z %u \n", B, Bprime, Kprime, Z);
if (Z <= 2) {
*K = 2;
......@@ -148,10 +146,8 @@ else
*F = ((*K) - Kprime);
#ifdef DEBUG_SEGMENTATION
printf("final nr seg output Z %u K %u F %u \n", *Zout, *K, *F);
printf("C %u, K %u, Bprime_bytes %u, Bprime %u, F %u\n",*C,*K,Bprime>>3,Bprime,*F);
#endif
LOG_D(PHY,"final nr seg output Z %u K %u F %u \n", *Zout, *K, *F);
LOG_D(PHY,"C %u, K %u, Bprime_bytes %u, Bprime %u, F %u\n",*C,*K,Bprime>>3,Bprime,*F);
if ((input_buffer) && (output_buffers)) {
......
......@@ -124,6 +124,7 @@ int phy_init_nr_gNB(PHY_VARS_gNB *gNB,
for (int symb=0; symb<fp->symbols_per_slot; symb++) {
pdcch_dmrs[slot][symb] = (uint32_t *)malloc16(NR_MAX_PDCCH_DMRS_INIT_LENGTH_DWORD*sizeof(uint32_t));
LOG_D(PHY,"pdcch_dmrs[%d][%d] %p\n",slot,symb,pdcch_dmrs[slot][symb]);
AssertFatal(pdcch_dmrs[slot][symb]!=NULL, "NR init: pdcch_dmrs for slot %d symbol %d - malloc failed\n", slot, symb);
}
}
......@@ -518,45 +519,38 @@ void nr_phy_config_request(NR_PHY_Config_t *phy_config) {
LOG_I(PHY,"gNB %d configured\n",Mod_id);
}
void init_DLSCH_struct(PHY_VARS_gNB *gNB, processingData_L1tx_t *msg) {
NR_DL_FRAME_PARMS *fp = &gNB->frame_parms;
nfapi_nr_config_request_scf_t *cfg = &gNB->gNB_config;
uint16_t grid_size = cfg->carrier_config.dl_grid_size[fp->numerology_index].value;
msg->num_pdsch_slot = 0;
for (int i=0; i<gNB->number_of_nr_dlsch_max; i++) {
LOG_I(PHY,"Allocating Transport Channel Buffers for DLSCH %d/%d\n",i,gNB->number_of_nr_dlsch_max);
for (int j=0; j<2; j++) {
msg->dlsch[i][j] = new_gNB_dlsch(fp,1,16,NSOFT,0,grid_size);
AssertFatal(msg->dlsch[i][j]!=NULL,"Can't initialize dlsch %d \n", i);
}
}
}
void init_nr_transport(PHY_VARS_gNB *gNB) {
int i;
int j;
NR_DL_FRAME_PARMS *fp = &gNB->frame_parms;
nfapi_nr_config_request_scf_t *cfg = &gNB->gNB_config;
LOG_I(PHY, "Initialise nr transport\n");
uint16_t grid_size = cfg->carrier_config.dl_grid_size[fp->numerology_index].value;
memset(gNB->num_pdsch_rnti, 0, sizeof(uint16_t)*80);
for (i=0; i <NUMBER_OF_NR_PDCCH_MAX; i++) {
LOG_I(PHY,"Initializing PDCCH list for PDCCH %d/%d\n",i,NUMBER_OF_NR_PDCCH_MAX);
gNB->pdcch_pdu[i].frame=-1;
LOG_I(PHY,"Initializing UL PDCCH list for UL PDCCH %d/%d\n",i,NUMBER_OF_NR_PDCCH_MAX);
gNB->ul_pdcch_pdu[i].frame=-1;
}
for (i=0; i<NUMBER_OF_NR_PUCCH_MAX; i++) {
for (int i=0; i<NUMBER_OF_NR_PUCCH_MAX; i++) {
LOG_I(PHY,"Allocating Transport Channel Buffers for PUCCH %d/%d\n",i,NUMBER_OF_NR_PUCCH_MAX);
gNB->pucch[i] = new_gNB_pucch();
AssertFatal(gNB->pucch[i]!=NULL,"Can't initialize pucch %d \n", i);
}
for (i=0; i<gNB->number_of_nr_dlsch_max; i++) {
LOG_I(PHY,"Allocating Transport Channel Buffers for DLSCH %d/%d\n",i,gNB->number_of_nr_dlsch_max);
for (j=0; j<2; j++) {
gNB->dlsch[i][j] = new_gNB_dlsch(fp,1,16,NSOFT,0,grid_size);
AssertFatal(gNB->dlsch[i][j]!=NULL,"Can't initialize dlsch %d \n", i);
}
}
for (i=0; i<gNB->number_of_nr_ulsch_max; i++) {
for (int i=0; i<gNB->number_of_nr_ulsch_max; i++) {
LOG_I(PHY,"Allocating Transport Channel Buffer for ULSCH %d/%d\n",i,gNB->number_of_nr_ulsch_max);
for (j=0; j<2; j++) {
for (int j=0; j<2; j++) {
// ULSCH for data
gNB->ulsch[i][j] = new_gNB_ulsch(MAX_LDPC_ITERATIONS, fp->N_RB_UL, 0);
......
......@@ -60,10 +60,12 @@ int nr_phy_init_RU(RU_t *ru) {
for (i=0; i<ru->nb_tx; i++) {
// Allocate 10 subframes of I/Q TX signal data (time) if not
ru->common.txdata[i] = (int32_t*)malloc16_clear( fp->samples_per_frame*sizeof(int32_t) );
ru->common.txdata[i] = (int32_t*)malloc16_clear( ru->sf_extension + (fp->samples_per_frame*sizeof(int32_t) ));
LOG_I(PHY,"[INIT] common.txdata[%d] = %p (%lu bytes,sf_extension %d)\n",i,ru->common.txdata[i],
(ru->sf_extension + fp->samples_per_frame)*sizeof(int32_t),ru->sf_extension);
ru->common.txdata[i] = &ru->common.txdata[i][ru->sf_extension];
LOG_I(PHY,"[INIT] common.txdata[%d] = %p (%lu bytes)\n",i,ru->common.txdata[i],
fp->samples_per_frame*sizeof(int32_t));
LOG_I(PHY,"[INIT] common.txdata[%d] = %p \n",i,ru->common.txdata[i]);
}
for (i=0;i<ru->nb_rx;i++) {
......@@ -100,8 +102,8 @@ int nr_phy_init_RU(RU_t *ru) {
// allocate FFT output buffers (RX)
ru->common.rxdataF = (int32_t**)malloc16(ru->nb_rx*sizeof(int32_t*) );
for (i=0; i<ru->nb_rx; i++) {
// allocate 2 subframes of I/Q signal data (frequency)
ru->common.rxdataF[i] = (int32_t*)malloc16_clear(sizeof(int32_t)*(2*fp->samples_per_subframe_wCP) );
// allocate 4 slots of I/Q signal data (frequency)
ru->common.rxdataF[i] = (int32_t*)malloc16_clear(sizeof(int32_t)*(4*fp->symbols_per_slot*fp->ofdm_symbol_size) );
LOG_I(PHY,"rxdataF[%d] %p for RU %d\n",i,ru->common.rxdataF[i],ru->idx);
}
......@@ -176,7 +178,11 @@ void nr_phy_free_RU(RU_t *ru)
free_and_zero(ru->frame_parms);
if (ru->if_south <= REMOTE_IF5) { // this means REMOTE_IF5 or LOCAL_RF, so free memory for time-domain signals
for (i = 0; i < ru->nb_tx; i++) free_and_zero(ru->common.txdata[i]);
int32_t *ptr;
for (i = 0; i < ru->nb_tx; i++) {
ptr=&ru->common.txdata[i][-ru->sf_extension];
free_and_zero(ptr);
}
for (i = 0; i < ru->nb_rx; i++) free_and_zero(ru->common.rxdata[i]);
free_and_zero(ru->common.txdata);
free_and_zero(ru->common.rxdata);
......
......@@ -102,7 +102,7 @@ void set_scs_parameters (NR_DL_FRAME_PARMS *fp, int mu, int N_RB_DL)
if (fp->nr_band == 5 || fp->nr_band == 66)
fp->ssb_type = nr_ssb_type_B;
else{
if (fp->nr_band == 41 || ( fp->nr_band > 76 && fp->nr_band < 80) )
if (fp->nr_band == 41 || fp->nr_band == 38 || ( fp->nr_band > 76 && fp->nr_band < 80) )
fp->ssb_type = nr_ssb_type_C;
else
AssertFatal(1==0,"NR Operating Band n%d not available for SS block SCS with mu=%d\n", fp->nr_band, mu);
......@@ -141,6 +141,8 @@ void set_scs_parameters (NR_DL_FRAME_PARMS *fp, int mu, int N_RB_DL)
fp->first_carrier_offset = fp->ofdm_symbol_size - (N_RB_DL * 12 / 2);
fp->nb_prefix_samples = fp->ofdm_symbol_size / 128 * 9;
fp->nb_prefix_samples0 = fp->ofdm_symbol_size / 128 * (9 + (1 << mu));
LOG_I(PHY,"Init: N_RB_DL %d, first_carrier_offset %d, nb_prefix_samples %d,nb_prefix_samples0 %d\n",
N_RB_DL,fp->first_carrier_offset,fp->nb_prefix_samples,fp->nb_prefix_samples0);
}
uint32_t get_samples_per_slot(int slot, NR_DL_FRAME_PARMS* fp)
......
......@@ -409,6 +409,7 @@ void init_nr_transport(PHY_VARS_gNB *gNB);
void init_dfts(void);
void fill_subframe_mask(PHY_VARS_eNB *eNB);
void init_DLSCH_struct(PHY_VARS_gNB *gNB, processingData_L1tx_t *msg);
/** @} */
#endif
......
This diff is collapsed.
......@@ -109,11 +109,11 @@ int nr_slot_fep(PHY_VARS_NR_UE *ue,
// use OFDM symbol from within 1/8th of the CP to avoid ISI
rx_offset -= (nb_prefix_samples / frame_parms->ofdm_offset_divisor);
#ifdef DEBUG_FEP
//#ifdef DEBUG_FEP
// if (ue->frame <100)
printf("slot_fep: slot %d, symbol %d, nb_prefix_samples %u, nb_prefix_samples0 %u, rx_offset %u\n",
Ns, symbol, nb_prefix_samples, nb_prefix_samples0, rx_offset);
#endif
LOG_D(PHY,"slot_fep: slot %d, symbol %d, nb_prefix_samples %u, nb_prefix_samples0 %u, rx_offset %u energy %d\n",
Ns, symbol, nb_prefix_samples, nb_prefix_samples0, rx_offset, dB_fixed(signal_energy(&common_vars->rxdata[0][rx_offset],frame_parms->ofdm_symbol_size)));
//#endif
for (unsigned char aa=0; aa<frame_parms->nb_antennas_rx; aa++) {
memset(&common_vars->common_vars_rx_data_per_thread[proc->thread_id].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],0,frame_parms->ofdm_symbol_size*sizeof(int32_t));
......@@ -355,23 +355,24 @@ void apply_nr_rotation_ul(NR_DL_FRAME_PARMS *frame_parms,
int symb_offset = (slot%frame_parms->slots_per_subframe)*frame_parms->symbols_per_slot;
int soffset = (slot&3)*frame_parms->symbols_per_slot*frame_parms->ofdm_symbol_size;
for (int symbol=first_symbol;symbol<nsymb;symbol++) {
uint32_t rot2 = ((uint32_t*)frame_parms->symbol_rotation[1])[symbol + symb_offset];
((int16_t*)&rot2)[1]=-((int16_t*)&rot2)[1];
LOG_D(PHY,"slot %d, symb_offset %d rotating by %d.%d\n",slot,symb_offset,((int16_t*)&rot2)[0],((int16_t*)&rot2)[1]);
rotate_cpx_vector((int16_t *)&rxdataF[frame_parms->ofdm_symbol_size*symbol],
rotate_cpx_vector((int16_t *)&rxdataF[soffset+(frame_parms->ofdm_symbol_size*symbol)],
(int16_t*)&rot2,
(int16_t *)&rxdataF[frame_parms->ofdm_symbol_size*symbol],
(int16_t *)&rxdataF[soffset+(frame_parms->ofdm_symbol_size*symbol)],
length,
15);
int16_t *shift_rot = frame_parms->timeshift_symbol_rotation;
multadd_cpx_vector((int16_t *)&rxdataF[frame_parms->ofdm_symbol_size*symbol],
multadd_cpx_vector((int16_t *)&rxdataF[soffset+(frame_parms->ofdm_symbol_size*symbol)],
shift_rot,
(int16_t *)&rxdataF[frame_parms->ofdm_symbol_size*symbol],
(int16_t *)&rxdataF[soffset+(frame_parms->ofdm_symbol_size*symbol)],
1,
length,
15);
......
......@@ -73,8 +73,9 @@ void dump_nr_I0_stats(FILE *fd,PHY_VARS_gNB *gNB) {
int min_I0=1000,max_I0=0;
int amin=0,amax=0;
fprintf(fd,"Blacklisted PRBs %d/%d\n",gNB->num_ulprbbl,gNB->frame_parms.N_RB_UL);
for (int i=0; i<gNB->frame_parms.N_RB_UL; i++) {
if (i==(gNB->frame_parms.N_RB_UL>>1) - 1) i+=2;
if (gNB->ulprbbl[i] > 0) continue;
if (gNB->measurements.n0_subband_power_tot_dB[i]<min_I0) {min_I0 = gNB->measurements.n0_subband_power_tot_dB[i]; amin=i;}
......@@ -82,41 +83,46 @@ void dump_nr_I0_stats(FILE *fd,PHY_VARS_gNB *gNB) {
}
for (int i=0; i<gNB->frame_parms.N_RB_UL; i++) {
fprintf(fd,"%2d.",gNB->measurements.n0_subband_power_tot_dB[i]-gNB->measurements.n0_subband_power_avg_dB);
if (gNB->ulprbbl[i] ==0) fprintf(fd,"%2d.",gNB->measurements.n0_subband_power_tot_dB[i]-gNB->measurements.n0_subband_power_avg_dB);
else fprintf(fd," X.");
if (i%25 == 24) fprintf(fd,"\n");
}
fprintf(fd,"\nmax_I0 %d (rb %d), min_I0 %d (rb %d), avg I0 %d\n", max_I0, amax, min_I0, amin, gNB->measurements.n0_subband_power_avg_dB);
fprintf(fd,"PRACH I0 = %d.%d dB\n",gNB->measurements.prach_I0/10,gNB->measurements.prach_I0%10);
fprintf(fd,"\n");
fprintf(fd,"max_IO = %d (%d), min_I0 = %d (%d), avg_I0 = %d dB",max_I0,amax,min_I0,amin,gNB->measurements.n0_subband_power_avg_dB);
if (gNB->frame_parms.nb_antennas_rx>1) {
fprintf(fd,"(");
for (int aarx=0;aarx<gNB->frame_parms.nb_antennas_rx;aarx++)
fprintf(fd,"%d.",gNB->measurements.n0_subband_power_avg_perANT_dB[aarx]);
fprintf(fd,")");
}
fprintf(fd,"\nPRACH I0 = %d.%d dB\n",gNB->measurements.prach_I0/10,gNB->measurements.prach_I0%10);
}
void gNB_I0_measurements(PHY_VARS_gNB *gNB,int first_symb,int num_symb) {
void gNB_I0_measurements(PHY_VARS_gNB *gNB,int slot, int first_symb,int num_symb) {
NR_DL_FRAME_PARMS *frame_parms = &gNB->frame_parms;
NR_gNB_COMMON *common_vars = &gNB->common_vars;
PHY_MEASUREMENTS_gNB *measurements = &gNB->measurements;
uint32_t *rb_mask = gNB->rb_mask_ul;
int rb, offset, offset0, nb_rb, len;
int rb, offset, offset0, nb_symb[275], len;
int32_t *ul_ch;
int32_t n0_power_tot;
int64_t n0_power_tot2;
nb_rb = 0;
n0_power_tot2=0;
for (rb=0; rb<frame_parms->N_RB_UL; rb++) {
n0_power_tot=0;
offset0 = (frame_parms->first_carrier_offset + (rb*12))%frame_parms->ofdm_symbol_size;
if ((rb_mask[rb>>5]&(1<<(rb&31))) == 0) { // check that rb was not used in this subframe
nb_rb++;
for (int aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) {
measurements->n0_subband_power[aarx][rb]=0;
LOG_D(PHY,"slot %d Doing I0 for first_symb %d, num_symb %d\n",slot,first_symb,num_symb);
for (int s=first_symb;s<(first_symb+num_symb);s++) {
for (rb=0; rb<frame_parms->N_RB_UL; rb++) {
if (s==first_symb) {
nb_symb[rb]=0;
for (int aarx=0; aarx<frame_parms->nb_antennas_rx;aarx++)
measurements->n0_subband_power[aarx][rb]=0;
}
offset0 = (slot&3)*(frame_parms->symbols_per_slot * frame_parms->ofdm_symbol_size) + (frame_parms->first_carrier_offset + (rb*12))%frame_parms->ofdm_symbol_size;
if ((gNB->rb_mask_ul[s][rb>>5]&(1<<(rb&31))) == 0) { // check that rb was not used in this subframe
nb_symb[rb]++;
for (int aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) {
offset = offset0 + (s*frame_parms->ofdm_symbol_size);
ul_ch = &common_vars->rxdataF[aarx][offset];
len = 12;
......@@ -126,20 +132,39 @@ void gNB_I0_measurements(PHY_VARS_gNB *gNB,int first_symb,int num_symb) {
}
AssertFatal(ul_ch, "RX signal buffer (freq) problem\n");
measurements->n0_subband_power[aarx][rb] += signal_energy_nodc(ul_ch,len);
} // symbol
measurements->n0_subband_power[aarx][rb]/=num_symb;
measurements->n0_subband_power_dB[aarx][rb] = dB_fixed(measurements->n0_subband_power[aarx][rb]);
n0_power_tot += measurements->n0_subband_power[aarx][rb];
} //antenna
n0_power_tot/=frame_parms->nb_antennas_rx;
n0_power_tot2 += n0_power_tot;
measurements->n0_subband_power_tot_dB[rb] = dB_fixed(n0_power_tot);
measurements->n0_subband_power_tot_dBm[rb] = measurements->n0_subband_power_tot_dB[rb] - gNB->rx_total_gain_dB - dB_fixed(frame_parms->N_RB_UL);
}
} //rb
if (nb_rb>0) measurements->n0_subband_power_avg_dB = dB_fixed(n0_power_tot2/nb_rb);
} // symb
int nb_rb=0;
int32_t n0_subband_tot=0;
int32_t n0_subband_tot_perPRB=0;
int32_t n0_subband_tot_perANT[1+frame_parms->nb_antennas_rx];
for (int rb = 0 ; rb<frame_parms->N_RB_UL;rb++) {
n0_subband_tot_perPRB=0;
if (nb_symb[rb] > 0) {
for (int aarx=0;aarx<frame_parms->nb_antennas_rx;aarx++) {
measurements->n0_subband_power[aarx][rb]/=nb_symb[rb];
measurements->n0_subband_power_dB[aarx][rb] = dB_fixed(measurements->n0_subband_power[aarx][rb]);
n0_subband_tot_perPRB+=measurements->n0_subband_power[aarx][rb];
if (rb==0) n0_subband_tot_perANT[aarx]=measurements->n0_subband_power[aarx][rb];
else n0_subband_tot_perANT[aarx]+=measurements->n0_subband_power[aarx][rb];
}
n0_subband_tot_perPRB/=frame_parms->nb_antennas_rx;
measurements->n0_subband_power_tot_dB[rb] = dB_fixed(n0_subband_tot_perPRB);
measurements->n0_subband_power_tot_dBm[rb] = measurements->n0_subband_power_tot_dB[rb] - gNB->rx_total_gain_dB - dB_fixed(frame_parms->N_RB_UL);
LOG_D(PHY,"n0_subband_power_tot_dB[%d] => %d, over %d symbols\n",rb,measurements->n0_subband_power_tot_dB[rb],nb_symb[rb]);
n0_subband_tot += n0_subband_tot_perPRB;
nb_rb++;
}
}
if (nb_rb>0) {
measurements->n0_subband_power_avg_dB = dB_fixed(n0_subband_tot/nb_rb);
for (int aarx=0;aarx<frame_parms->nb_antennas_rx;aarx++) {
measurements->n0_subband_power_avg_perANT_dB[aarx] = dB_fixed(n0_subband_tot_perANT[aarx]/nb_rb);
}
}
}
......@@ -179,6 +204,7 @@ void nr_gnb_measurements(PHY_VARS_gNB *gNB, uint8_t ulsch_id, unsigned char harq
rx_power[ulsch_id][aarx] += meas->rx_spatial_power[ulsch_id][aatx][aarx];
}
LOG_D(PHY, "[ULSCH ID %d] RX power in antenna %d = %d\n", ulsch_id, aarx, rx_power[ulsch_id][aarx]);
rx_power_tot[ulsch_id] += rx_power[ulsch_id][aarx];
......@@ -190,12 +216,13 @@ void nr_gnb_measurements(PHY_VARS_gNB *gNB, uint8_t ulsch_id, unsigned char harq
meas->wideband_cqi_tot[ulsch_id] = dB_fixed2(rx_power_tot[ulsch_id], meas->n0_power_tot);
meas->rx_rssi_dBm[ulsch_id] = rx_power_avg_dB[ulsch_id] + 30 - 10 * log10(pow(2, 30)) - (rx_gain - rx_gain_offset) - dB_fixed(fp->ofdm_symbol_size);
LOG_D(PHY, "[ULSCH %d] RSSI %d dBm/RE, RSSI (digital) %d dB (N_RB_UL %d), WBand CQI tot %d dB, N0 Power tot %d\n",
LOG_D(PHY, "[ULSCH %d] RSSI %d dBm/RE, RSSI (digital) %d dB (N_RB_UL %d), WBand CQI tot %d dB, N0 Power tot %d, RX Power tot %d\n",
ulsch_id,
meas->rx_rssi_dBm[ulsch_id],
rx_power_avg_dB[ulsch_id],
N_RB_UL,
meas->wideband_cqi_tot[ulsch_id],
meas->n0_power_tot);
meas->n0_power_tot,
rx_power_tot[ulsch_id]);
}
......@@ -68,7 +68,7 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB,
uint8_t nushift;
int **ul_ch_estimates = gNB->pusch_vars[ul_id]->ul_ch_estimates;
int **rxdataF = gNB->common_vars.rxdataF;
int soffset = (Ns&3)*gNB->frame_parms.symbols_per_slot*gNB->frame_parms.ofdm_symbol_size;
nushift = (p>>1)&1;
gNB->frame_parms.nushift = nushift;
......@@ -81,16 +81,14 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB,
uint16_t nb_rb_pusch = pusch_pdu->rb_size;
#ifdef DEBUG_CH
LOG_I(PHY, "In %s: ch_offset %d, symbol_offset %d OFDM size %d, Ns = %d, k = %d symbol %d\n",
LOG_D(PHY, "In %s: ch_offset %d, soffset %d, symbol_offset %d OFDM size %d, Ns = %d, k = %d symbol %d\n",
__FUNCTION__,
ch_offset,
ch_offset, soffset,
symbol_offset,
gNB->frame_parms.ofdm_symbol_size,
Ns,
k,
symbol);
#endif
switch (nushift) {
case 0:
......@@ -174,7 +172,7 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB,
re_offset = k; /* Initializing the Resource element offset for each Rx antenna */
pil = (int16_t *)&pilot[0];
rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+k+nushift)];
rxF = (int16_t *)&rxdataF[aarx][(soffset+symbol_offset+k+nushift)];
ul_ch = (int16_t *)&ul_ch_estimates[p*gNB->frame_parms.nb_antennas_rx+aarx][ch_offset];
re_offset = k;
......@@ -216,7 +214,7 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB,
8);
pil += 2;
re_offset = (re_offset+2) % gNB->frame_parms.ofdm_symbol_size;
rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)];
rxF = (int16_t *)&rxdataF[aarx][(soffset+symbol_offset+nushift+re_offset)];
//for (int i= 0; i<8; i++)
//printf("ul_ch addr %p %d\n", ul_ch+i, *(ul_ch+i));
......@@ -247,7 +245,7 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB,
8);
pil += 2;
re_offset = (re_offset+2) % gNB->frame_parms.ofdm_symbol_size;
rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)];
rxF = (int16_t *)&rxdataF[aarx][(soffset+symbol_offset+nushift+re_offset)];
//printf("ul_ch addr %p\n",ul_ch);
ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
......@@ -281,8 +279,8 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB,
pil += 2;
re_offset = (re_offset+2) % gNB->frame_parms.ofdm_symbol_size;
rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)];
ul_ch += 8;
rxF = (int16_t *)&rxdataF[aarx][(soffset+symbol_offset+nushift+re_offset)];
ul_ch+=8;
for (pilot_cnt=3; pilot_cnt<(6*nb_rb_pusch-3); pilot_cnt += 2) {
......@@ -299,7 +297,7 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB,
8);
pil += 2;
re_offset = (re_offset+2) % gNB->frame_parms.ofdm_symbol_size;
rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)];
rxF = (int16_t *)&rxdataF[aarx][(soffset+symbol_offset+nushift+re_offset)];
//printf("ul_ch addr %p\n",ul_ch);
ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
......@@ -319,9 +317,8 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB,
pil += 2;
re_offset = (re_offset+2) % gNB->frame_parms.ofdm_symbol_size;
rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)];
ul_ch += 8;
rxF = (int16_t *)&rxdataF[aarx][soffset+(symbol_offset+nushift+re_offset)];
ul_ch+=8;
}
// Treat first 2 pilots specially (right edge)
......@@ -341,7 +338,7 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB,
pil += 2;
re_offset = (re_offset+2) % gNB->frame_parms.ofdm_symbol_size;
rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)];
rxF = (int16_t *)&rxdataF[aarx][soffset+(symbol_offset+nushift+re_offset)];
ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
......@@ -357,8 +354,8 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB,
pil += 2;
re_offset = (re_offset+2) % gNB->frame_parms.ofdm_symbol_size;
rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)];
ul_ch += 8;
rxF = (int16_t *)&rxdataF[aarx][soffset+(symbol_offset+nushift+re_offset)];
ul_ch+=8;
ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
......@@ -383,7 +380,7 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB,
ul_ch += (idxDC-4);
ul_ch = memset(ul_ch, 0, sizeof(int16_t)*10);
re_offset = (re_offset+idxDC/2-2) % gNB->frame_parms.ofdm_symbol_size;
rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)];
rxF = (int16_t *)&rxdataF[aarx][soffset+(symbol_offset+nushift+re_offset)];
ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
......@@ -414,7 +411,7 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB,
pil += 4;
re_offset = (re_offset+4) % gNB->frame_parms.ofdm_symbol_size;
rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)];
rxF = (int16_t *)&rxdataF[aarx][soffset+(symbol_offset+nushift+re_offset)];
ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
......@@ -438,7 +435,7 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB,
LOG_D(PHY,"PUSCH estimation DMRS type 2, Freq-domain interpolation");
// Treat first DMRS specially (left edge)
rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)];
rxF = (int16_t *)&rxdataF[aarx][soffset+(symbol_offset+nushift+re_offset)];
ul_ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
ul_ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
......@@ -450,7 +447,7 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB,
for (re_cnt = 1; re_cnt < (nb_rb_pusch*NR_NB_SC_PER_RB) - 5; re_cnt += 6){
rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)];
rxF = (int16_t *)&rxdataF[aarx][soffset+(symbol_offset+nushift+re_offset)];
ch_l[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
ch_l[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
......@@ -468,7 +465,7 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB,
re_offset = (re_offset+5)%gNB->frame_parms.ofdm_symbol_size;
rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)];
rxF = (int16_t *)&rxdataF[aarx][soffset+symbol_offset+nushift+re_offset];
ch_r[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
ch_r[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
......@@ -496,7 +493,7 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB,
// Treat last pilot specially (right edge)
rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)];
rxF = (int16_t *)&rxdataF[aarx][soffset+(symbol_offset+nushift+re_offset)];
ch_l[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
ch_l[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
......
......@@ -49,7 +49,7 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB,
void dump_nr_I0_stats(FILE *fd,PHY_VARS_gNB *gNB);
void gNB_I0_measurements(PHY_VARS_gNB *gNB,int first_symb,int num_symb);
void gNB_I0_measurements(PHY_VARS_gNB *gNB,int slot,int first_symb,int num_symb);
void nr_gnb_measurements(PHY_VARS_gNB *gNB, uint8_t ulsch_id, unsigned char harq_pid, unsigned char symbol, uint8_t nrOfLayers);
......
......@@ -66,7 +66,7 @@ void nr_init_pdcch_dmrs(PHY_VARS_gNB* gNB, uint32_t Nid)
reset = 1;
x2 = ((1<<17) * (fp->symbols_per_slot*slot+symb+1) * ((Nid<<1)+1) + (Nid<<1));
LOG_D(PHY,"PDCCH DMRS slot %d, symb %d, Nid %d, x2 %x\n",slot,symb,Nid,x2);
for (uint32_t n=0; n<NR_MAX_PDCCH_DMRS_INIT_LENGTH_DWORD; n++) {
pdcch_dmrs[slot][symb][n] = lte_gold_generic(&x1, &x2, reset);
reset = 0;
......@@ -92,7 +92,7 @@ void nr_init_pdsch_dmrs(PHY_VARS_gNB* gNB, uint32_t Nid)
for (uint8_t symb=0; symb<fp->symbols_per_slot; symb++) {
reset = 1;
x2 = ((1<<17) * (fp->symbols_per_slot*slot+symb+1) * ((N_n_scid[n_scid]<<1)+1) +((N_n_scid[n_scid]<<1)+n_scid));
LOG_D(PHY,"DMRS slot %d, symb %d x2 %x\n",slot,symb,x2);
LOG_D(PHY,"PDSCH DMRS slot %d, symb %d x2 %x, N_n_scid %d,n_scid %d\n",slot,symb,x2,N_n_scid[n_scid],n_scid);
for (uint32_t n=0; n<NR_MAX_PDSCH_DMRS_INIT_LENGTH_DWORD; n++) {
pdsch_dmrs[slot][symb][0][n] = lte_gold_generic(&x1, &x2, reset);
reset = 0;
......
......@@ -102,7 +102,9 @@ void nr_generate_dci(PHY_VARS_gNB *gNB,
// DMRS length is per OFDM symbol
uint32_t dmrs_length = n_rb*6; //2(QPSK)*3(per RB)*6(REG per CCE)
uint32_t encoded_length = dci_pdu->AggregationLevel*108; //2(QPSK)*9(per RB)*6(REG per CCE)
LOG_D(PHY, "DMRS length per symbol %d\t DCI encoded length %d (precoder_granularity %d,reg_mapping %d)\n", dmrs_length, encoded_length,pdcch_pdu_rel15->precoderGranularity,pdcch_pdu_rel15->CceRegMappingType);
LOG_D(PHY, "DL_DCI : rb_offset %d, nb_rb %d, DMRS length per symbol %d\t DCI encoded length %d (precoder_granularity %d,reg_mapping %d),Scrambling_Id %d,ScramblingRNTI %x,PayloadSizeBits %d\n",
rb_offset, n_rb,dmrs_length, encoded_length,pdcch_pdu_rel15->precoderGranularity,pdcch_pdu_rel15->CceRegMappingType,
dci_pdu->ScramblingId,dci_pdu->ScramblingRNTI,dci_pdu->PayloadSizeBits);
dmrs_length += rb_offset*6; // To accommodate more DMRS symbols in case of rb offset
/// DMRS QPSK modulation
......@@ -111,11 +113,11 @@ void nr_generate_dci(PHY_VARS_gNB *gNB,
nr_modulation(gold_pdcch_dmrs[symb], dmrs_length, DMRS_MOD_ORDER, mod_dmrs[symb]); //Qm = 2 as DMRS is QPSK modulated
#ifdef DEBUG_PDCCH_DMRS
if(dci_pdu->RNTI!=0xFFFF) {
for (int i=0; i<dmrs_length>>1; i++)
printf("symb %d i %d gold seq 0x%08x mod_dmrs %d %d\n", symb, i,
gold_pdcch_dmrs[symb][i>>5], mod_dmrs[symb][i<<1], mod_dmrs[symb][(i<<1)+1] );
printf("symb %d i %d %p gold seq 0x%08x mod_dmrs %d %d\n", symb, i,
&gold_pdcch_dmrs[symb][i>>5],gold_pdcch_dmrs[symb][i>>5], mod_dmrs[symb][i<<1], mod_dmrs[symb][(i<<1)+1] );
}
#endif
}
......@@ -132,8 +134,8 @@ void nr_generate_dci(PHY_VARS_gNB *gNB,
dci_pdu->AggregationLevel,
0,NULL);
polar_encoder_fast((uint64_t*)dci_pdu->Payload, (void*)encoder_output, n_RNTI,1,currentPtr);
#ifdef DEBUG_CHANNEL_CODING
printf("polar rnti %x,length %d, L %d\n",n_RNTI, dci_pdu->PayloadSizeBits,pdcch_pdu_rel15->dci_pdu.AggregationLevel[d]);
#if DEBUG_CHANNEL_CODING
printf("polar rnti %x,length %d, L %d\n",n_RNTI, dci_pdu->PayloadSizeBits,dci_pdu->AggregationLevel);
printf("DCI PDU: [0]->0x%lx \t [1]->0x%lx\n",
((uint64_t*)dci_pdu->Payload)[0], ((uint64_t*)dci_pdu->Payload)[1]);
printf("Encoded Payload (length:%d dwords):\n", encoded_length>>5);
......@@ -211,7 +213,7 @@ void nr_generate_dci(PHY_VARS_gNB *gNB,
(amp * mod_dmrs[l][(dmrs_idx << 1) + 1]) >> 15;
#ifdef DEBUG_PDCCH_DMRS
printf("PDCCH DMRS: l %d position %d => (%d,%d)\n",l,k,((int16_t *)txdataF)[(l*frame_parms->ofdm_symbol_size + k)<<1],
LOG_D(PHY,"PDCCH DMRS %d: l %d position %d => (%d,%d)\n",dmrs_idx,l,k,((int16_t *)txdataF)[(l*frame_parms->ofdm_symbol_size + k)<<1],
((int16_t *)txdataF)[((l*frame_parms->ofdm_symbol_size + k)<<1)+1]);
#endif
......@@ -223,7 +225,7 @@ void nr_generate_dci(PHY_VARS_gNB *gNB,
((int16_t *) txdataF)[((l * frame_parms->ofdm_symbol_size + k) << 1) + 1] =
(amp * mod_dci[(dci_idx << 1) + 1]) >> 15;
#ifdef DEBUG_DCI
printf("PDCCH: l %d position %d => (%d,%d)\n",l,k,((int16_t *)txdataF)[(l*frame_parms->ofdm_symbol_size + k)<<1],
LOG_D(PHY,"PDCCH: l %d position %d => (%d,%d)\n",l,k,((int16_t *)txdataF)[(l*frame_parms->ofdm_symbol_size + k)<<1],
((int16_t *)txdataF)[((l*frame_parms->ofdm_symbol_size + k)<<1)+1]);
#endif
......
......@@ -153,7 +153,7 @@ void nr_fill_cce_list(PHY_VARS_gNB *gNB, uint8_t m, nfapi_nr_dl_tti_pdcch_pdu_r
C = N_reg/(bsize*R);
}
LOG_D(PHY, "CCE list generation for candidate %d: bundle size %d ilv size %d CceIndex %d\n", m, bsize, R, pdcch_pdu_rel15->dci_pdu[d].CceIndex);
if (pdcch_pdu_rel15->dci_pdu[d].RNTI != 0xFFFF) LOG_D(PHY, "CCE list generation for candidate %d: bundle size %d ilv size %d CceIndex %d\n", m, bsize, R, pdcch_pdu_rel15->dci_pdu[d].CceIndex);
for (uint8_t cce_idx=0; cce_idx<L; cce_idx++) {
cce = &gNB->cce_list[d][cce_idx];
cce->cce_idx = pdcch_pdu_rel15->dci_pdu[d].CceIndex + cce_idx;
......@@ -202,107 +202,3 @@ void nr_fill_cce_list(PHY_VARS_gNB *gNB, uint8_t m, nfapi_nr_dl_tti_pdcch_pdu_r
ret |= ((field>>i)&1)<<(size-i-1);
return ret;
}*/
int16_t find_nr_pdcch(int frame,int slot, PHY_VARS_gNB *gNB,find_type_t type) {
uint16_t i;
int16_t first_free_index=-1;
AssertFatal(gNB!=NULL,"gNB is null\n");
for (i=0; i<NUMBER_OF_NR_PDCCH_MAX; i++) {
LOG_D(PHY,"searching for frame.slot %d.%d : pdcch_index %d frame.slot %d.%d, first_free_index %d\n", frame,slot,i,gNB->pdcch_pdu[i].frame,gNB->pdcch_pdu[i].slot,first_free_index);
if ((gNB->pdcch_pdu[i].frame == frame) &&
(gNB->pdcch_pdu[i].slot==slot)) return i;
else if ( gNB->pdcch_pdu[i].frame==-1 && first_free_index==-1) first_free_index=i;
}
if (type == SEARCH_EXIST) return -1;
return first_free_index;
}
void nr_fill_dci(PHY_VARS_gNB *gNB,
int frame,
int slot,
nfapi_nr_dl_tti_pdcch_pdu *pdcch_pdu) {
nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu_rel15 = &pdcch_pdu->pdcch_pdu_rel15;
NR_gNB_DLSCH_t *dlsch;
int pdcch_id = find_nr_pdcch(frame,slot,gNB,SEARCH_EXIST_OR_FREE);
AssertFatal(pdcch_id>=0 && pdcch_id<NUMBER_OF_NR_PDCCH_MAX,"Cannot find space for PDCCH, exiting\n");
memcpy((void*)&gNB->pdcch_pdu[pdcch_id].pdcch_pdu,(void*)pdcch_pdu,sizeof(*pdcch_pdu));
gNB->pdcch_pdu[pdcch_id].frame = frame;
gNB->pdcch_pdu[pdcch_id].slot = slot;
for (int i=0;i<pdcch_pdu_rel15->numDlDci;i++) {
//uint64_t *dci_pdu = (uint64_t*)pdcch_pdu_rel15->dci_pdu[i].Payload;
int dlsch_id = find_nr_dlsch(pdcch_pdu_rel15->dci_pdu[i].RNTI,gNB,SEARCH_EXIST_OR_FREE);
if( (dlsch_id<0) || (dlsch_id>=gNB->number_of_nr_dlsch_max) ){
LOG_E(PHY,"illegal dlsch_id found!!! rnti %04x dlsch_id %d\n",(unsigned int)pdcch_pdu_rel15->dci_pdu[i].RNTI,dlsch_id);
return;
}
dlsch = gNB->dlsch[dlsch_id][0];
int harq_pid = 0;
dlsch->slot_tx[slot] = 1;
dlsch->harq_ids[frame % 2][slot] = 0;
AssertFatal(harq_pid < 8 && harq_pid >= 0,
"illegal harq_pid %d\n",harq_pid);
dlsch->harq_mask |= (1<<harq_pid);
dlsch->rnti = pdcch_pdu_rel15->dci_pdu[i].RNTI;
// nr_fill_cce_list(gNB,0);
}
}
int16_t find_nr_ul_dci(int frame,int slot, PHY_VARS_gNB *gNB,find_type_t type) {
uint16_t i;
int16_t first_free_index=-1;
AssertFatal(gNB!=NULL,"gNB is null\n");
for (i=0; i<NUMBER_OF_NR_PDCCH_MAX; i++) {
LOG_D(PHY,"searching for frame.slot %d.%d : ul_pdcch_index %d frame.slot %d.%d, first_free_index %d\n", frame,slot,i,gNB->ul_pdcch_pdu[i].frame,gNB->ul_pdcch_pdu[i].slot,first_free_index);
if ((gNB->ul_pdcch_pdu[i].frame == frame) &&
(gNB->ul_pdcch_pdu[i].slot==slot)) return i;
else if (gNB->ul_pdcch_pdu[i].frame==-1 && first_free_index==-1) first_free_index=i;
}
if (type == SEARCH_EXIST) return -1;
return first_free_index;
}
void nr_fill_ul_dci(PHY_VARS_gNB *gNB,
int frame,
int slot,
nfapi_nr_ul_dci_request_pdus_t *pdcch_pdu) {
nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu_rel15 = &pdcch_pdu->pdcch_pdu.pdcch_pdu_rel15;
int pdcch_id = find_nr_ul_dci(frame,slot,gNB,SEARCH_EXIST_OR_FREE);
AssertFatal(pdcch_id>=0 && pdcch_id<NUMBER_OF_NR_PDCCH_MAX,"Cannot find space for UL PDCCH, exiting\n");
memcpy((void*)&gNB->ul_pdcch_pdu[pdcch_id].pdcch_pdu,(void*)pdcch_pdu,sizeof(*pdcch_pdu));
gNB->ul_pdcch_pdu[pdcch_id].frame = frame;
gNB->ul_pdcch_pdu[pdcch_id].slot = slot;
for (int i=0;i<pdcch_pdu_rel15->numDlDci;i++) {
//uint64_t *dci_pdu = (uint64_t*)pdcch_pdu_rel15->dci_pdu[i].Payload;
// if there's no DL DCI then generate CCE list
// nr_fill_cce_list(gNB,0);
/*
LOG_D(PHY, "DCI PDU: [0]->0x%lx \t [1]->0x%lx \n",dci_pdu[0], dci_pdu[1]);
LOG_D(PHY, "DCI type %d payload (size %d) generated on candidate %d\n", dci_alloc->pdcch_params.dci_format, dci_alloc->size, cand_idx);
*/
}
}
......@@ -111,10 +111,11 @@ void nr_pdsch_codeword_scrambling_optim(uint8_t *in,
}
uint8_t nr_generate_pdsch(PHY_VARS_gNB *gNB,
uint8_t nr_generate_pdsch(processingData_L1tx_t *msgTx,
int frame,
int slot) {
PHY_VARS_gNB *gNB = msgTx->gNB;
NR_gNB_DLSCH_t *dlsch;
uint32_t ***pdsch_dmrs = gNB->nr_gold_pdsch_dmrs[slot];
int32_t** txdataF = gNB->common_vars.txdataF;
......@@ -132,9 +133,8 @@ uint8_t nr_generate_pdsch(PHY_VARS_gNB *gNB,
time_stats_t *dlsch_interleaving_stats=&gNB->dlsch_interleaving_stats;
time_stats_t *dlsch_segmentation_stats=&gNB->dlsch_segmentation_stats;
for (int dlsch_id=0;dlsch_id<gNB->number_of_nr_dlsch_max;dlsch_id++) {
dlsch = gNB->dlsch[dlsch_id][0];
if (dlsch->slot_tx[slot] == 0) continue;
for (int dlsch_id=0; dlsch_id<msgTx->num_pdsch_slot; dlsch_id++) {
dlsch = msgTx->dlsch[dlsch_id][0];
NR_DL_gNB_HARQ_t *harq = &dlsch->harq_process;
nfapi_nr_dl_tti_pdsch_pdu_rel15_t *rel15 = &harq->pdsch_pdu.pdsch_pdu_rel15;
......@@ -527,15 +527,17 @@ uint8_t nr_generate_pdsch(PHY_VARS_gNB *gNB,
return 0;
}
void dump_pdsch_stats(PHY_VARS_gNB *gNB) {
void dump_pdsch_stats(FILE *fd,PHY_VARS_gNB *gNB) {
for (int i=0;i<NUMBER_OF_NR_SCH_STATS_MAX;i++)
if (gNB->dlsch_stats[i].rnti > 0)
LOG_D(PHY,"DLSCH RNTI %x: current_Qm %d, current_RI %d, total_bytes TX %d\n",
if (gNB->dlsch_stats[i].rnti > 0 && gNB->dlsch_stats[i].frame != gNB->dlsch_stats[i].dump_frame) {
gNB->dlsch_stats[i].dump_frame = gNB->dlsch_stats[i].frame;
fprintf(fd,"DLSCH RNTI %x: current_Qm %d, current_RI %d, total_bytes TX %d\n",
gNB->dlsch_stats[i].rnti,
gNB->dlsch_stats[i].current_Qm,
gNB->dlsch_stats[i].current_RI,
gNB->dlsch_stats[i].total_bytes_tx);
}
}
......
This diff is collapsed.
This diff is collapsed.
......@@ -46,11 +46,11 @@ uint32_t nr_get_E(uint32_t G, uint8_t C, uint8_t Qm, uint8_t Nl, uint8_t r) {
AssertFatal(Nl>0,"Nl is 0\n");
AssertFatal(Qm>0,"Qm is 0\n");
LOG_D(PHY,"nr_get_E : (G %d, C %d, Qm %d, Nl %d, r %d)\n",G, C, Qm, Nl, r);
if (r <= Cprime - ((G/(Nl*Qm))%Cprime) - 1)
E = Nl*Qm*(G/(Nl*Qm*Cprime));
else
E = Nl*Qm*((G/(Nl*Qm*Cprime))+1);
LOG_D(PHY,"nr_get_E : (G %d, C %d, Qm %d, Nl %d, r %d), E %d\n",G, C, Qm, Nl, r, E);
return E;
}
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
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