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

Conflicts:
	common/utils/msc/msc.h
	openair2/X2AP/x2ap_eNB.c
This commit is contained in:
Cedric Roux
2019-02-01 14:27:55 +01:00
94 changed files with 10003 additions and 10866 deletions
-17
View File
@@ -1,17 +0,0 @@
job1:
script:
- date
- pwd
- echo $OAI_TEST_CASE_GROUP
- echo $MACHINELIST
- echo $MACHINELISTGENERIC
- echo $RESULT_DIR
- echo $NRUNS_LTE_SOFTMODEM
- source oaienv
- rm -rf cmake_targets/autotests/log
- mkdir cmake_targets/autotests/log
- cd cmake_targets/autotests/v2
- python main.py
- date
only:
- triggers
+27 -10
View File
@@ -9,26 +9,36 @@ Please see NOTICE.txt for third party software that is included in the sources.
The OpenAirInterface (OAI) software is composed of the following parts:
openairinterface5g
├── cmake_targets: build utilities to compile (simulation, emulation and real-time platforms), and generated build files
├── common : some common OAI utilities, other tools can be found at openair2/UTILS
├── ci-scripts: Meta-scripts used by the OSA CI process. Contains also configuration files used day-to-day by CI.
├── cmake_targets: Build utilities to compile (simulation, emulation and real-time platforms), and generated build files
├── common : Some common OAI utilities, other tools can be found at openair2/UTILS
├── doc : Contains an up-to-date feature set list
├── LICENSE
├── maketags : script to generate emacs tags
├── openair1 : 3GPP LTE Rel-10 PHY layer + PHY RF simulation and a subset of Rel 12 Features.
├── openair2 :3GPP LTE Rel-10 RLC/MAC/PDCP/RRC/X2AP implementation.
├── maketags : Script to generate emacs tags
├── nfapi : Contains the NFAPI code. A local Readme file provides more details.
├── openair1 : 3GPP LTE Rel-10/12 PHY layer + PHY RF simulation. A local Readme file provides more details.
├── openair2 : 3GPP LTE Rel-10 RLC/MAC/PDCP/RRC/X2AP implementation.
├── COMMON
├── DOCS
├── ENB_APP
├── LAYER2/RLC/ with the following subdirectories: UM_v9.3.0, TM_v9.3.0, and AM_v9.3.0.
├── LAYER2/PDCP/PDCP_v10.1.0.
├── RRC/LITE
├── LAYER2/PDCP/PDCP_v10.1.0.
├── NETWORK_DRIVER
├── PHY_INTERFACE
├── RRC/LITE
├── UTIL
├── X2AP
├── ENB_APP
├── openair3: 3GPP LTE Rel10 for S1AP, NAS GTPV1-U for both ENB and UE.
├── COMMON
├── DOCS
├── GTPV1-U
├── NAS
├── NAS
├── S1AP
├── SCTP
├── SECU
├── UDP
└── targets: top level wrapper for unitary simulation for PHY channels, system-level emulation (eNB-UE with and without S1), and realtime eNB and UE and RRH GW.
├── UTILS
└── targets: Top-level wrappers for unitary simulation for PHY channels, system-level emulation (eNB-UE with and without S1), and realtime eNB and UE and RRH GW.
RELEASE NOTES:
@@ -44,3 +54,10 @@ v0.6 -> RRH functionality, UE greatly improved, better TDD support,
a lot of bugs fixed. WARNING: oaisim in PHY abstraction mode does not
work, you need to use v0.5.2 for that.
v0.6.1 -> Mostly bugfixes. This is the last version without NFAPI.
v1.0.0 -> January 2019. This version first implements the architectural split described in doc/oai_lte_enb_func_split_arch.png picture.
Only FAPI, nFAPI and IF4.5 interfaces are implemented.
Repository tree structure prepares future integrations of features such as LTE-M, nbIOT or 5G-NR.
Preliminary X2 support has been implemented.
S1-flex has been introduced.
New tools: config library, telnet server, ...
A lot of bugfixes and a proper automated Continuous Integration process validates contributions.
+30 -4
View File
@@ -41,7 +41,7 @@ pipeline {
disableConcurrentBuilds()
timestamps()
gitLabConnection('OAI GitLab')
gitlabBuilds(builds: ["Build eNb-USRP", "Build basic-sim", "Build phy-sim", "Build eNb-ethernet", "Build UE-ethernet", "Analysis with cppcheck", "Test phy-sim", "Test basic-sim", "Test-FDD-Band7", "Test-TDD-Band40", "Test-IF4p5-FDD-Band7", "Test-IF4p5-TDD-Band40"])
gitlabBuilds(builds: ["Build eNb-USRP", "Build basic-sim", "Build phy-sim", "Build eNb-ethernet", "Build UE-ethernet", "Analysis with cppcheck", "Test phy-sim", "Test basic-sim", "Test L2-sim", "Test-FDD-Band7", "Test-TDD-Band40", "Test-IF4p5-FDD-Band7", "Test-IF4p5-TDD-Band40"])
ansiColor('xterm')
}
@@ -166,6 +166,14 @@ pipeline {
}
}
stage ("Start VM -- L2-Sim") {
steps {
timeout (time: 5, unit: 'MINUTES') {
sh "./ci-scripts/oai-ci-vm-tool build --workspace $WORKSPACE --variant l2-sim --job-name ${JOB_NAME} --build-id ${BUILD_ID} --daemon"
}
}
}
stage ("Start VM -- phy-sim") {
steps {
timeout (time: 5, unit: 'MINUTES') {
@@ -215,7 +223,7 @@ pipeline {
steps {
gitlabCommitStatus(name: "Build eNb-ethernet") {
timeout (time: 20, unit: 'MINUTES') {
sh "./ci-scripts/oai-ci-vm-tool wait --workspace $WORKSPACE --variant enb-ethernet --job-name ${JOB_NAME} --build-id ${BUILD_ID} --keep-vm-alive"
sh "./ci-scripts/oai-ci-vm-tool wait --workspace $WORKSPACE --variant enb-ethernet --job-name ${JOB_NAME} --build-id ${BUILD_ID}"
}
}
}
@@ -224,11 +232,20 @@ pipeline {
steps {
gitlabCommitStatus(name: "Build UE-ethernet") {
timeout (time: 20, unit: 'MINUTES') {
sh "./ci-scripts/oai-ci-vm-tool wait --workspace $WORKSPACE --variant ue-ethernet --job-name ${JOB_NAME} --build-id ${BUILD_ID} --keep-vm-alive"
sh "./ci-scripts/oai-ci-vm-tool wait --workspace $WORKSPACE --variant ue-ethernet --job-name ${JOB_NAME} --build-id ${BUILD_ID}"
}
}
}
}
stage ("Build L2-Simulator-eNB") {
steps {
//gitlabCommitStatus(name: "Build UE-ethernet") {
timeout (time: 20, unit: 'MINUTES') {
sh "./ci-scripts/oai-ci-vm-tool wait --workspace $WORKSPACE --variant l2-sim --job-name ${JOB_NAME} --build-id ${BUILD_ID} --keep-vm-alive"
}
//}
}
}
stage ("Build physical simulators") {
steps {
gitlabCommitStatus(name: "Build phy-sim") {
@@ -313,6 +330,15 @@ pipeline {
}
}
}
stage ("Test L2 simulator") {
steps {
gitlabCommitStatus(name: "Test L2-sim") {
timeout (time: 30, unit: 'MINUTES') {
sh "./ci-scripts/oai-ci-vm-tool test --workspace $WORKSPACE --variant l2-sim --job-name ${JOB_NAME} --build-id ${BUILD_ID}"
}
}
}
}
stage ("Build Flexran Controller") {
when {
expression {doFlexranCtrlTest}
@@ -508,7 +534,7 @@ pipeline {
always {
script {
dir ('archives') {
sh "if [ -d basic_sim/test ] || [ -d phy_sim/test ]; then zip -r -qq vm_tests_logs.zip */test ; fi"
sh "if [ -d basic_sim/test ] || [ -d phy_sim/test ] || [ -d l2_sim/test ]; then zip -r -qq vm_tests_logs.zip */test ; fi"
}
if(fileExists('archives/vm_tests_logs.zip')) {
archiveArtifacts artifacts: 'archives/vm_tests_logs.zip'
@@ -0,0 +1,236 @@
Active_eNBs = ( "eNB-Eurecom-LTEBox");
# Asn1_verbosity, choice in: none, info, annoying
Asn1_verbosity = "none";
eNBs =
(
{
////////// Identification parameters:
eNB_ID = 0xe00;
cell_type = "CELL_MACRO_ENB";
eNB_name = "eNB-Eurecom-LTEBox";
// Tracking area code, 0x0000 and 0xfffe are reserved values
tracking_area_code = 1;
plmn_list = ( { mcc = 208; mnc = 93; mnc_length = 2; } );
tr_s_preference = "local_mac"
////////// Physical parameters:
component_carriers = (
{
node_function = "3GPP_eNODEB";
node_timing = "synch_to_ext_device";
node_synch_ref = 0;
frame_type = "FDD";
tdd_config = 3;
tdd_config_s = 0;
prefix_type = "NORMAL";
eutra_band = 7;
downlink_frequency = 2685000000L;
uplink_frequency_offset = -120000000;
Nid_cell = 0;
N_RB_DL = 50;
Nid_cell_mbsfn = 0;
nb_antenna_ports = 1;
nb_antennas_tx = 1;
nb_antennas_rx = 1;
tx_gain = 90;
rx_gain = 125;
pbch_repetition = "FALSE";
prach_root = 0;
prach_config_index = 0;
prach_high_speed = "DISABLE";
prach_zero_correlation = 1;
prach_freq_offset = 2;
pucch_delta_shift = 1;
pucch_nRB_CQI = 0;
pucch_nCS_AN = 0;
pucch_n1_AN = 0;
pdsch_referenceSignalPower = -27;
pdsch_p_b = 0;
pusch_n_SB = 1;
pusch_enable64QAM = "DISABLE";
pusch_hoppingMode = "interSubFrame";
pusch_hoppingOffset = 0;
pusch_groupHoppingEnabled = "ENABLE";
pusch_groupAssignment = 0;
pusch_sequenceHoppingEnabled = "DISABLE";
pusch_nDMRS1 = 1;
phich_duration = "NORMAL";
phich_resource = "ONESIXTH";
srs_enable = "DISABLE";
/* srs_BandwidthConfig =;
srs_SubframeConfig =;
srs_ackNackST =;
srs_MaxUpPts =;*/
pusch_p0_Nominal = -96;
pusch_alpha = "AL1";
pucch_p0_Nominal = -104;
msg3_delta_Preamble = 6;
pucch_deltaF_Format1 = "deltaF2";
pucch_deltaF_Format1b = "deltaF3";
pucch_deltaF_Format2 = "deltaF0";
pucch_deltaF_Format2a = "deltaF0";
pucch_deltaF_Format2b = "deltaF0";
rach_numberOfRA_Preambles = 64;
rach_preamblesGroupAConfig = "DISABLE";
/*
rach_sizeOfRA_PreamblesGroupA = ;
rach_messageSizeGroupA = ;
rach_messagePowerOffsetGroupB = ;
*/
rach_powerRampingStep = 4;
rach_preambleInitialReceivedTargetPower = -108;
rach_preambleTransMax = 10;
rach_raResponseWindowSize = 10;
rach_macContentionResolutionTimer = 48;
rach_maxHARQ_Msg3Tx = 4;
pcch_default_PagingCycle = 128;
pcch_nB = "oneT";
bcch_modificationPeriodCoeff = 2;
ue_TimersAndConstants_t300 = 1000;
ue_TimersAndConstants_t301 = 1000;
ue_TimersAndConstants_t310 = 1000;
ue_TimersAndConstants_t311 = 10000;
ue_TimersAndConstants_n310 = 20;
ue_TimersAndConstants_n311 = 1;
ue_TransmissionMode = 1;
//Parameters for SIB18
rxPool_sc_CP_Len = "normal";
rxPool_sc_Period = "sf40";
rxPool_data_CP_Len = "normal";
rxPool_ResourceConfig_prb_Num = 20;
rxPool_ResourceConfig_prb_Start = 5;
rxPool_ResourceConfig_prb_End = 44;
rxPool_ResourceConfig_offsetIndicator_present = "prSmall";
rxPool_ResourceConfig_offsetIndicator_choice = 0;
rxPool_ResourceConfig_subframeBitmap_present = "prBs40";
rxPool_ResourceConfig_subframeBitmap_choice_bs_buf = "00000000000000000000";
rxPool_ResourceConfig_subframeBitmap_choice_bs_size = 5;
rxPool_ResourceConfig_subframeBitmap_choice_bs_bits_unused = 0;
/* rxPool_dataHoppingConfig_hoppingParameter = 0;
rxPool_dataHoppingConfig_numSubbands = "ns1";
rxPool_dataHoppingConfig_rbOffset = 0;
rxPool_commTxResourceUC-ReqAllowed = "TRUE";
*/
// Parameters for SIB19
discRxPool_cp_Len = "normal"
discRxPool_discPeriod = "rf32"
discRxPool_numRetx = 1;
discRxPool_numRepetition = 2;
discRxPool_ResourceConfig_prb_Num = 5;
discRxPool_ResourceConfig_prb_Start = 3;
discRxPool_ResourceConfig_prb_End = 21;
discRxPool_ResourceConfig_offsetIndicator_present = "prSmall";
discRxPool_ResourceConfig_offsetIndicator_choice = 0;
discRxPool_ResourceConfig_subframeBitmap_present = "prBs40";
discRxPool_ResourceConfig_subframeBitmap_choice_bs_buf = "f0ffffffff";
discRxPool_ResourceConfig_subframeBitmap_choice_bs_size = 5;
discRxPool_ResourceConfig_subframeBitmap_choice_bs_bits_unused = 0;
}
);
srb1_parameters :
{
# timer_poll_retransmit = (ms) [5, 10, 15, 20,... 250, 300, 350, ... 500]
timer_poll_retransmit = 80;
# timer_reordering = (ms) [0,5, ... 100, 110, 120, ... ,200]
timer_reordering = 35;
# timer_reordering = (ms) [0,5, ... 250, 300, 350, ... ,500]
timer_status_prohibit = 0;
# poll_pdu = [4, 8, 16, 32 , 64, 128, 256, infinity(>10000)]
poll_pdu = 4;
# poll_byte = (kB) [25,50,75,100,125,250,375,500,750,1000,1250,1500,2000,3000,infinity(>10000)]
poll_byte = 99999;
# max_retx_threshold = [1, 2, 3, 4 , 6, 8, 16, 32]
max_retx_threshold = 4;
}
# ------- SCTP definitions
SCTP :
{
# Number of streams to use in input/output
SCTP_INSTREAMS = 2;
SCTP_OUTSTREAMS = 2;
};
////////// MME parameters:
mme_ip_address = ( { ipv4 = "CI_MME_IP_ADDR";
ipv6 = "192:168:30::17";
active = "yes";
preference = "ipv4";
}
);
NETWORK_INTERFACES :
{
ENB_INTERFACE_NAME_FOR_S1_MME = "ens3";
ENB_IPV4_ADDRESS_FOR_S1_MME = "CI_ENB_IP_ADDR";
ENB_INTERFACE_NAME_FOR_S1U = "ens3";
ENB_IPV4_ADDRESS_FOR_S1U = "CI_ENB_IP_ADDR";
ENB_PORT_FOR_S1U = 2152; # Spec 2152
ENB_IPV4_ADDRESS_FOR_X2C = "CI_ENB_IP_ADDR";
ENB_PORT_FOR_X2C = 36422; # Spec 36422
};
}
);
MACRLCs = (
{
num_cc = 1;
local_s_if_name = "lo:";
remote_s_address = "127.0.0.1";
local_s_address = "127.0.0.2";
local_s_portc = 50001;
remote_s_portc = 50000;
local_s_portd = 50011;
remote_s_portd = 50010;
tr_s_preference = "nfapi";
tr_n_preference = "local_RRC";
}
);
THREAD_STRUCT = (
{
#three config for level of parallelism "PARALLEL_SINGLE_THREAD", "PARALLEL_RU_L1_SPLIT", or "PARALLEL_RU_L1_TRX_SPLIT"
parallel_config = "PARALLEL_RU_L1_TRX_SPLIT";
#two option for worker "WORKER_DISABLE" or "WORKER_ENABLE"
worker_config = "WORKER_ENABLE";
}
);
log_config =
{
global_log_level ="info";
global_log_verbosity ="medium";
hw_log_level ="info";
hw_log_verbosity ="medium";
phy_log_level ="info";
phy_log_verbosity ="medium";
mac_log_level ="info";
mac_log_verbosity ="high";
rlc_log_level ="info";
rlc_log_verbosity ="medium";
pdcp_log_level ="info";
pdcp_log_verbosity ="medium";
rrc_log_level ="info";
rrc_log_verbosity ="medium";
};
+44
View File
@@ -0,0 +1,44 @@
log_config = {
global_log_level ="info";
global_log_verbosity ="medium";
hw_log_level ="info";
hw_log_verbosity ="medium";
phy_log_level ="info";
phy_log_verbosity ="medium";
mac_log_level ="info";
mac_log_verbosity ="medium";
rlc_log_level ="info";
rlc_log_verbosity ="medium";
pdcp_log_level ="info";
pdcp_log_verbosity ="medium";
rrc_log_level ="info";
rrc_log_verbosity ="full";
};
L1s = (
{
num_cc = 1;
tr_n_preference = "nfapi";
local_n_if_name = "lo";
remote_n_address = "127.0.0.2";
local_n_address = "127.0.0.1";
local_n_portc = 50000;
remote_n_portc = 50001;
local_n_portd = 50010;
remote_n_portd = 50011;
}
);
RUs = (
{
local_rf = "yes"
nb_tx = 1
nb_rx = 1
att_tx = 90
att_rx = 0;
bands = [7,38,42,43];
max_pdschReferenceSignalPower = -27;
max_rxgain = 125;
}
);
+4 -4
View File
@@ -214,7 +214,7 @@ class SSHConnection():
copy_status = False
logging.debug('scp '+ username + '@' + ipaddress + ':' + source + ' ' + destination)
while count < 10:
scp_spawn = pexpect.spawn('scp '+ username + '@' + ipaddress + ':' + source + ' ' + destination, timeout = 5)
scp_spawn = pexpect.spawn('scp '+ username + '@' + ipaddress + ':' + source + ' ' + destination, timeout = 100)
scp_response = scp_spawn.expect(['Are you sure you want to continue connecting (yes/no)?', 'password:', pexpect.EOF, pexpect.TIMEOUT])
if scp_response == 0:
scp_spawn.sendline('yes')
@@ -253,7 +253,7 @@ class SSHConnection():
copy_status = False
logging.debug('scp ' + source + ' ' + username + '@' + ipaddress + ':' + destination)
while count < 4:
scp_spawn = pexpect.spawn('scp ' + source + ' ' + username + '@' + ipaddress + ':' + destination, timeout = 5)
scp_spawn = pexpect.spawn('scp ' + source + ' ' + username + '@' + ipaddress + ':' + destination, timeout = 100)
scp_response = scp_spawn.expect(['Are you sure you want to continue connecting (yes/no)?', 'password:', pexpect.EOF, pexpect.TIMEOUT])
if scp_response == 0:
scp_spawn.sendline('yes')
@@ -1977,8 +1977,8 @@ class SSHConnection():
if result is not None:
self.eNBKernelVersion = result.group('kernel_version')
logging.debug('Kernel Version is: ' + self.eNBKernelVersion)
self.command('dpkg --list | egrep --color=never uhd-host', '\$', 5)
result = re.search('uhd-host *(?P<uhd_version>[0-9\.]+)', str(self.ssh.before))
self.command('dpkg --list | egrep --color=never libuhd003', '\$', 5)
result = re.search('libuhd003:amd64 *(?P<uhd_version>[0-9\.]+)', str(self.ssh.before))
if result is not None:
self.eNBUhdVersion = result.group('uhd_version')
logging.debug('UHD Version is: ' + self.eNBUhdVersion)
+24
View File
@@ -40,6 +40,7 @@ function variant_usage {
echo " --variant cppcheck OR -v4"
echo " --variant enb-ethernet OR -v7"
echo " --variant ue-ethernet OR -v8"
echo " --variant l2-sim OR -v9"
echo " --variant flexran-rtc OR -v10"
}
@@ -285,6 +286,18 @@ case $key in
NBARGS=$[$NBARGS+256]
shift
;;
-v9)
VM_NAME=ci-l2-sim
VM_MEMORY=8192
VM_CPU=8
ARCHIVES_LOC=l2_sim
LOG_PATTERN=.Rel14.txt
NB_PATTERN_FILES=4
BUILD_OPTIONS="--eNB -t ETHERNET"
RUN_OPTIONS="complex"
NBARGS=$[$NBARGS+256]
shift
;;
-v10)
VM_NAME=ci-flexran-rtc
ARCHIVES_LOC=flexran
@@ -350,6 +363,17 @@ case $key in
BUILD_OPTIONS="--UE -t ETHERNET --noS1"
NBARGS=$[$NBARGS+256]
;;
l2-sim)
VM_NAME=ci-l2-sim
VM_MEMORY=8192
VM_CPU=8
ARCHIVES_LOC=l2_sim
LOG_PATTERN=.Rel14.txt
NB_PATTERN_FILES=4
BUILD_OPTIONS="--eNB -t ETHERNET"
RUN_OPTIONS="complex"
NBARGS=$[$NBARGS+256]
;;
flexran-rtc)
VM_NAME=ci-flexran-rtc
ARCHIVES_LOC=flexran
+124
View File
@@ -417,6 +417,130 @@ function report_test {
echo " </div>" >> ./test_simulator_results.html
fi
ARCHIVES_LOC=archives/l2_sim/test
if [ -d $ARCHIVES_LOC ]
then
echo " <h3>L2-NFAPI Simulator Check</h3>" >> ./test_simulator_results.html
if [ -f $ARCHIVES_LOC/test_final_status.log ]
then
if [ `grep -c TEST_OK $ARCHIVES_LOC/test_final_status.log` -eq 1 ]
then
echo " <div class=\"alert alert-success\">" >> ./test_simulator_results.html
echo " <strong>TEST was SUCCESSFUL <span class=\"glyphicon glyphicon-ok-circle\"></span></strong>" >> ./test_simulator_results.html
echo " </div>" >> ./test_simulator_results.html
else
echo " <div class=\"alert alert-danger\">" >> ./test_simulator_results.html
echo " <strong>TEST was a FAILURE! <span class=\"glyphicon glyphicon-ban-circle\"></span></strong>" >> ./test_simulator_results.html
echo " </div>" >> ./test_simulator_results.html
fi
else
echo " <div class=\"alert alert-danger\">" >> ./test_simulator_results.html
echo " <strong>COULD NOT DETERMINE TEST FINAL STATUS! <span class=\"glyphicon glyphicon-ban-circle\"></span></strong>" >> ./test_simulator_results.html
echo " </div>" >> ./test_simulator_results.html
fi
echo " <button data-toggle=\"collapse\" data-target=\"#oai-l2-sim-test-details\">More details on L2-NFAPI Simulator test results</button>" >> ./test_simulator_results.html
echo " <div id=\"oai-l2-sim-test-details\" class=\"collapse\">" >> ./test_simulator_results.html
echo " <table border = \"1\">" >> ./test_simulator_results.html
echo " <tr bgcolor = \"#33CCFF\" >" >> ./test_simulator_results.html
echo " <th>Log File Name</th>" >> ./test_simulator_results.html
echo " <th>Command</th>" >> ./test_simulator_results.html
echo " <th>Status</th>" >> ./test_simulator_results.html
echo " <th>Statistics</th>" >> ./test_simulator_results.html
echo " </tr>" >> ./test_simulator_results.html
TRANS_MODES=("fdd")
BW_CASES=(05)
for TMODE in ${TRANS_MODES[@]}
do
for BW in ${BW_CASES[@]}
do
ENB_LOG=$ARCHIVES_LOC/${TMODE}_${BW}MHz_enb.log
UE_LOG=`echo $ENB_LOG | sed -e "s#enb#ue#"`
if [ -f $ENB_LOG ] && [ -f $UE_LOG ]
then
NAME_ENB=`echo $ENB_LOG | sed -e "s#$ARCHIVES_LOC/##"`
NAME_UE=`echo $UE_LOG | sed -e "s#$ARCHIVES_LOC/##"`
echo " <tr>" >> ./test_simulator_results.html
echo " <td>$NAME_ENB --- $NAME_UE</td>" >> ./test_simulator_results.html
echo " <td>N/A</td>" >> ./test_simulator_results.html
NB_ENB_GOT_SYNC=`egrep -c "got sync" $ENB_LOG`
NB_UE_GOT_SYNC=`egrep -c "got sync" $UE_LOG`
NB_ENB_SYNCED_WITH_UE=`egrep -c "Sending NFAPI_START_RESPONSE" $UE_LOG`
if [ $NB_ENB_GOT_SYNC -eq 1 ] && [ $NB_UE_GOT_SYNC -eq 3 ] && [ $NB_ENB_SYNCED_WITH_UE -eq 1 ]
then
echo " <td bgcolor = \"green\" >OK</td>" >> ./test_simulator_results.html
else
echo " <td bgcolor = \"red\" >KO</td>" >> ./test_simulator_results.html
fi
echo " <td><pre>" >> ./test_simulator_results.html
if [ $NB_ENB_GOT_SYNC -eq 1 ]
then
echo "<font color = \"blue\">- eNB --> got sync</font>" >> ./test_simulator_results.html
else
echo "<font color = \"red\"><b>- eNB NEVER got sync</b></font>" >> ./test_simulator_results.html
fi
if [ $NB_UE_GOT_SYNC -eq 3 ]
then
echo "<font color = \"blue\">- UE --> got sync</font>" >> ./test_simulator_results.html
else
echo "<font color = \"red\"><b>- UE NEVER got sync</b></font>" >> ./test_simulator_results.html
fi
if [ $NB_ENB_SYNCED_WITH_UE -eq 1 ]
then
echo "<font color = \"blue\">- UE attached to eNB</font>" >> ./test_simulator_results.html
else
echo "<font color = \"red\"><b>- UE NEVER attached to eNB</b></font>" >> ./test_simulator_results.html
fi
echo " </pre></td>" >> ./test_simulator_results.html
echo " </tr>" >> ./test_simulator_results.html
fi
PING_CASE=$ARCHIVES_LOC/${TMODE}_${BW}MHz_ping_epc.txt
if [ -f $PING_CASE ]
then
echo " <tr>" >> ./test_simulator_results.html
NAME=`echo $PING_CASE | sed -e "s#$ARCHIVES_LOC/##"`
echo " <td>$NAME</td>" >> ./test_simulator_results.html
CMD=`egrep "COMMAND IS" $PING_CASE | sed -e "s#COMMAND IS: ##"`
echo " <td>$CMD</td>" >> ./test_simulator_results.html
FILE_COMPLETE=`egrep -c "ping statistics" $PING_CASE`
if [ $FILE_COMPLETE -eq 0 ]
then
echo " <td bgcolor = \"red\" >KO</td>" >> ./test_simulator_results.html
echo " <td>N/A</td>" >> ./test_simulator_results.html
else
NB_TR_PACKETS=`egrep "packets transmitted" $PING_CASE | sed -e "s# packets transmitted.*##"`
NB_RC_PACKETS=`egrep "packets transmitted" $PING_CASE | sed -e "s#^.*packets transmitted, ##" -e "s# received,.*##"`
if [ $NB_TR_PACKETS -eq $NB_RC_PACKETS ]
then
echo " <td bgcolor = \"green\" >OK</td>" >> ./test_simulator_results.html
else
echo " <td bgcolor = \"red\" >KO</td>" >> ./test_simulator_results.html
fi
echo " <td>" >> ./test_simulator_results.html
echo " <pre>" >> ./test_simulator_results.html
STATS=`egrep "packets transmitted" $PING_CASE | sed -e "s#^.*received, ##" -e "s#, time.*##" -e "s# packet loss##"`
echo "Packet Loss : $STATS" >> ./test_simulator_results.html
RTTMIN=`egrep "rtt min" $PING_CASE | awk '{split($4,a,"/"); print a[1] " " $5}'`
echo "RTT Minimal : $RTTMIN" >> ./test_simulator_results.html
RTTAVG=`egrep "rtt min" $PING_CASE | awk '{split($4,a,"/"); print a[2] " " $5}'`
echo "RTT Average : $RTTAVG" >> ./test_simulator_results.html
RTTMAX=`egrep "rtt min" $PING_CASE | awk '{split($4,a,"/"); print a[3] " " $5}'`
echo "RTT Maximal : $RTTMAX" >> ./test_simulator_results.html
echo " </pre>" >> ./test_simulator_results.html
echo " </td>" >> ./test_simulator_results.html
fi
echo " </tr>" >> ./test_simulator_results.html
fi
done
done
echo " </table>" >> ./test_simulator_results.html
echo " </div>" >> ./test_simulator_results.html
fi
ARCHIVES_LOC=archives/phy_sim/test
if [ -d $ARCHIVES_LOC ]
then
+416 -158
View File
@@ -148,6 +148,15 @@ function ping_ue_ip_addr {
rm -f $1
}
function ping_epc_ip_addr {
echo "echo \"COMMAND IS: ping -I oip1 -c 20 $3\" > $4" > $1
echo "rm -f $4" >> $1
echo "ping -I oip1 -c 20 $3 | tee -a $4" >> $1
cat $1
ssh -o StrictHostKeyChecking=no ubuntu@$2 < $1
rm -f $1
}
function check_ping_result {
local LOC_PING_FILE=$1
local LOC_NB_PINGS=$2
@@ -157,16 +166,19 @@ function check_ping_result {
if [ $FILE_COMPLETE -eq 0 ]
then
PING_STATUS=-1
echo "ping file incomplete"
else
local ALL_PACKET_RECEIVED=`egrep -c "$LOC_NB_PINGS received" $LOC_PING_FILE`
if [ $ALL_PACKET_RECEIVED -eq 1 ]
then
echo "got all ping packets"
else
echo "got NOT all ping packets"
PING_STATUS=-1
fi
fi
else
echo "ping file not present"
PING_STATUS=-1
fi
}
@@ -280,17 +292,171 @@ function recover_core_dump {
fi
}
function terminate_ltebox_epc {
echo "echo \"cd /opt/ltebox/tools\"" > $1
echo "cd /opt/ltebox/tools" >> $1
echo "echo \"sudo ./stop_ltebox\"" >> $1
echo "sudo ./stop_ltebox" >> $1
echo "echo \"sudo daemon --name=simulated_hss --stop\"" >> $1
echo "sudo daemon --name=simulated_hss --stop" >> $1
echo "echo \"sudo killall --signal SIGKILL hss_sim\"" >> $1
echo "sudo killall --signal SIGKILL hss_sim" >> $1
ssh -o StrictHostKeyChecking=no ubuntu@$2 < $1
rm $1
function install_epc_on_vm {
local LOC_EPC_VM_NAME=$1
local LOC_EPC_VM_CMDS=$2
if [ -d /opt/ltebox-archives/ ]
then
# Checking if all ltebox archives are available to run ltebx epc on a brand new VM
if [ -f /opt/ltebox-archives/ltebox_2.2.70_16_04_amd64.deb ] && [ -f /opt/ltebox-archives/etc-conf.zip ] && [ -f /opt/ltebox-archives/hss-sim.zip ]
then
echo "############################################################"
echo "Test EPC on VM ($EPC_VM_NAME) will be using ltebox"
echo "############################################################"
LTEBOX=1
fi
fi
# Here we could have other types of EPC detection
# Do we need to start the EPC VM
echo "EPC_VM_CMD_FILE = $LOC_EPC_VM_CMDS"
IS_EPC_VM_ALIVE=`uvt-kvm list | grep -c $LOC_EPC_VM_NAME`
if [ $IS_EPC_VM_ALIVE -eq 0 ]
then
echo "############################################################"
echo "Creating test EPC VM ($LOC_EPC_VM_NAME) on Ubuntu Cloud Image base"
echo "############################################################"
uvt-kvm create $LOC_EPC_VM_NAME release=xenial --unsafe-caching
fi
uvt-kvm wait $LOC_EPC_VM_NAME --insecure
local LOC_EPC_VM_IP_ADDR=`uvt-kvm ip $LOC_EPC_VM_NAME`
echo "$LOC_EPC_VM_NAME has for IP addr = $LOC_EPC_VM_IP_ADDR"
scp -o StrictHostKeyChecking=no /etc/apt/apt.conf.d/01proxy ubuntu@$LOC_EPC_VM_IP_ADDR:/home/ubuntu
# ltebox specific actions (install and start)
LTE_BOX_TO_INSTALL=1
if [ $LTEBOX -eq 1 ]
then
echo "ls -ls /opt/ltebox/tools/start_ltebox" > $LOC_EPC_VM_CMDS
RESPONSE=`ssh -o StrictHostKeyChecking=no ubuntu@$LOC_EPC_VM_IP_ADDR < $LOC_EPC_VM_CMDS`
NB_EXES=`echo $RESPONSE | grep -c ltebox`
if [ $NB_EXES -eq 1 ]; then LTE_BOX_TO_INSTALL=0; fi
fi
if [ $LTEBOX -eq 1 ] && [ $LTE_BOX_TO_INSTALL -eq 1 ]
then
echo "############################################################"
echo "Copying ltebox archives into EPC VM ($LOC_EPC_VM_NAME)"
echo "############################################################"
scp -o StrictHostKeyChecking=no /opt/ltebox-archives/ltebox_2.2.70_16_04_amd64.deb ubuntu@$LOC_EPC_VM_IP_ADDR:/home/ubuntu
scp -o StrictHostKeyChecking=no /opt/ltebox-archives/etc-conf.zip ubuntu@$LOC_EPC_VM_IP_ADDR:/home/ubuntu
scp -o StrictHostKeyChecking=no /opt/ltebox-archives/hss-sim.zip ubuntu@$LOC_EPC_VM_IP_ADDR:/home/ubuntu
echo "############################################################"
echo "Install EPC on EPC VM ($LOC_EPC_VM_NAME)"
echo "############################################################"
echo "sudo cp 01proxy /etc/apt/apt.conf.d/" > $LOC_EPC_VM_CMDS
echo "touch /home/ubuntu/.hushlogin" >> $LOC_EPC_VM_CMDS
echo "echo \"sudo apt-get --yes --quiet install zip openjdk-8-jre libconfuse-dev libreadline-dev liblog4c-dev libgcrypt-dev libsctp-dev python2.7 python2.7-dev daemon iperf\"" >> $LOC_EPC_VM_CMDS
echo "sudo apt-get update > zip-install.txt 2>&1" >> $LOC_EPC_VM_CMDS
echo "sudo apt-get --yes install zip openjdk-8-jre libconfuse-dev libreadline-dev liblog4c-dev libgcrypt-dev libsctp-dev python2.7 python2.7-dev daemon iperf >> zip-install.txt 2>&1" >> $LOC_EPC_VM_CMDS
# Installing HSS
echo "echo \"cd /opt\"" >> $LOC_EPC_VM_CMDS
echo "cd /opt" >> $LOC_EPC_VM_CMDS
echo "echo \"sudo unzip -qq /home/ubuntu/hss-sim.zip\"" >> $LOC_EPC_VM_CMDS
echo "sudo unzip -qq /home/ubuntu/hss-sim.zip" >> $LOC_EPC_VM_CMDS
echo "echo \"cd /opt/hss_sim0609\"" >> $LOC_EPC_VM_CMDS
echo "cd /opt/hss_sim0609" >> $LOC_EPC_VM_CMDS
# Installing ltebox
echo "echo \"cd /home/ubuntu\"" >> $LOC_EPC_VM_CMDS
echo "cd /home/ubuntu" >> $LOC_EPC_VM_CMDS
echo "echo \"sudo dpkg -i ltebox_2.2.70_16_04_amd64.deb \"" >> $LOC_EPC_VM_CMDS
echo "sudo dpkg -i ltebox_2.2.70_16_04_amd64.deb >> zip-install.txt 2>&1" >> $LOC_EPC_VM_CMDS
echo "echo \"cd /opt/ltebox/etc/\"" >> $LOC_EPC_VM_CMDS
echo "cd /opt/ltebox/etc/" >> $LOC_EPC_VM_CMDS
echo "echo \"sudo unzip -qq -o /home/ubuntu/etc-conf.zip\"" >> $LOC_EPC_VM_CMDS
echo "sudo unzip -qq -o /home/ubuntu/etc-conf.zip" >> $LOC_EPC_VM_CMDS
echo "sudo sed -i -e 's#EPC_VM_IP_ADDRESS#$LOC_EPC_VM_IP_ADDR#' gw.conf" >> $LOC_EPC_VM_CMDS
echo "sudo sed -i -e 's#EPC_VM_IP_ADDRESS#$LOC_EPC_VM_IP_ADDR#' mme.conf" >> $LOC_EPC_VM_CMDS
ssh -o StrictHostKeyChecking=no ubuntu@$LOC_EPC_VM_IP_ADDR < $LOC_EPC_VM_CMDS
rm -f $LOC_EPC_VM_CMDS
fi
}
function start_epc {
local LOC_EPC_VM_NAME=$1
local LOC_EPC_VM_CMDS=$2
local LOC_EPC_VM_IP_ADDR=$3
if [ $LTEBOX -eq 1 ]
then
echo "############################################################"
echo "Start EPC on EPC VM ($LOC_EPC_VM_NAME)"
echo "############################################################"
echo "echo \"cd /opt/hss_sim0609\"" > $LOC_EPC_VM_CMDS
echo "cd /opt/hss_sim0609" >> $LOC_EPC_VM_CMDS
echo "echo \"sudo daemon --unsafe --name=simulated_hss --chdir=/opt/hss_sim0609 ./starthss_real\"" >> $LOC_EPC_VM_CMDS
echo "sudo daemon --unsafe --name=simulated_hss --chdir=/opt/hss_sim0609 ./starthss_real" >> $LOC_EPC_VM_CMDS
echo "echo \"cd /opt/ltebox/tools/\"" >> $LOC_EPC_VM_CMDS
echo "cd /opt/ltebox/tools/" >> $LOC_EPC_VM_CMDS
echo "echo \"sudo ./start_ltebox\"" >> $LOC_EPC_VM_CMDS
echo "nohup sudo ./start_ltebox > /home/ubuntu/ltebox.txt" >> $LOC_EPC_VM_CMDS
ssh -o StrictHostKeyChecking=no ubuntu@$LOC_EPC_VM_IP_ADDR < $LOC_EPC_VM_CMDS
rm -f $LOC_EPC_VM_CMDS
i="0"
echo "ifconfig tun5 | egrep -c \"inet addr\"" > $LOC_EPC_VM_CMDS
while [ $i -lt 10 ]
do
sleep 2
CONNECTED=`ssh -o StrictHostKeyChecking=no ubuntu@$LOC_EPC_VM_IP_ADDR < $LOC_EPC_VM_CMDS`
if [ $CONNECTED -eq 1 ]
then
i="100"
else
i=$[$i+1]
fi
done
rm $LOC_EPC_VM_CMDS
if [ $i -lt 50 ]
then
echo "Problem w/ starting ltebox EPC"
echo "TEST_KO" > $ARCHIVES_LOC/test_final_status.log
exit -1
fi
fi
# HERE ADD ANY INSTALL ACTIONS FOR ANOTHER EPC
}
function retrieve_real_epc_ip_addr {
local LOC_EPC_VM_NAME=$1
local LOC_EPC_VM_CMDS=$2
local LOC_EPC_VM_IP_ADDR=$3
if [ $LTEBOX -eq 1 ]
then
# in our configuration file, we are using pool 5
echo "ifconfig tun5 | egrep \"inet addr\" | sed -e 's#^.*inet addr:##' -e 's# P-t-P:.*\$##'" > $LOC_EPC_VM_CMDS
REAL_EPC_IP_ADDR=`ssh -o StrictHostKeyChecking=no ubuntu@$LOC_EPC_VM_IP_ADDR < $LOC_EPC_VM_CMDS`
echo "EPC IP Address is : $REAL_EPC_IP_ADDR"
rm $LOC_EPC_VM_CMDS
fi
}
function terminate_epc {
if [ $LTEBOX -eq 1 ]
then
echo "echo \"cd /opt/ltebox/tools\"" > $1
echo "cd /opt/ltebox/tools" >> $1
echo "echo \"sudo ./stop_ltebox\"" >> $1
echo "sudo ./stop_ltebox" >> $1
echo "echo \"sudo daemon --name=simulated_hss --stop\"" >> $1
echo "sudo daemon --name=simulated_hss --stop" >> $1
echo "echo \"sudo killall --signal SIGKILL hss_sim\"" >> $1
echo "sudo killall --signal SIGKILL hss_sim" >> $1
ssh -o StrictHostKeyChecking=no ubuntu@$2 < $1
rm $1
fi
}
function start_flexran_ctrl {
@@ -322,6 +488,130 @@ function query_flexran_ctrl_status {
rm $1
}
function build_ue_on_separate_folder {
echo "mkdir tmp-ue" > $1
echo "cd tmp-ue" >> $1
echo "echo \"unzip -qq -DD ../localZip.zip\"" >> $1
echo "unzip -qq -DD ../localZip.zip" >> $1
# We may have some adaptation to do
if [ -f /opt/ltebox-archives/adapt_ue_l2_sim.txt ]
then
echo "############################################################"
echo "Doing some adaptation on UE side"
echo "############################################################"
cat /opt/ltebox-archives/adapt_ue_l2_sim.txt >> $1
fi
echo "echo \"source oaienv\"" >> $1
echo "source oaienv" >> $1
echo "cd cmake_targets/" >> $1
echo "mkdir log" >> $1
echo "chmod 777 log" >> $1
echo "echo \"./build_oai --UE -t ETHERNET \"" >> $1
echo "./build_oai --UE -t ETHERNET > log/ue-build.txt 2>&1" >> $1
echo "cd tools" >> $1
echo "sudo ifconfig lo: 127.0.0.2 netmask 255.0.0.0 up" >> $1
echo "sudo chmod 666 /etc/iproute2/rt_tables" >> $1
echo "source init_nas_s1 UE" >> $1
echo "ifconfig" >> $1
ssh -o StrictHostKeyChecking=no ubuntu@$2 < $1
rm -f $1
}
function start_l2_sim_enb {
local LOC_VM_IP_ADDR=$2
local LOC_EPC_IP_ADDR=$3
local LOC_LOG_FILE=$4
local LOC_NB_RBS=$5
local LOC_CONF_FILE=$6
echo "cd /home/ubuntu/tmp" > $1
echo "echo \"sudo apt-get --yes --quiet install daemon \"" >> $1
echo "sudo apt-get --yes install daemon >> /home/ubuntu/tmp/cmake_targets/log/daemon-install.txt 2>&1" >> $1
echo "echo \"source oaienv\"" >> $1
echo "source oaienv" >> $1
echo "cd ci-scripts/conf_files/" >> $1
echo "cp $LOC_CONF_FILE ci-$LOC_CONF_FILE" >> $1
echo "sed -i -e 's#N_RB_DL.*=.*;#N_RB_DL = $LOC_NB_RBS;#' -e 's#CI_MME_IP_ADDR#$LOC_EPC_IP_ADDR#' -e 's#CI_ENB_IP_ADDR#$LOC_VM_IP_ADDR#' ci-$LOC_CONF_FILE" >> $1
echo "echo \"grep N_RB_DL ci-$LOC_CONF_FILE\"" >> $1
echo "grep N_RB_DL ci-$LOC_CONF_FILE | sed -e 's#N_RB_DL.*=#N_RB_DL =#'" >> $1
echo "echo \"cd /home/ubuntu/tmp/cmake_targets/lte_build_oai/build/\"" >> $1
echo "sudo chmod 777 /home/ubuntu/tmp/cmake_targets/lte_build_oai/build/" >> $1
echo "cd /home/ubuntu/tmp/cmake_targets/lte_build_oai/build/" >> $1
echo "echo \"ulimit -c unlimited && ./lte-softmodem -O /home/ubuntu/tmp/ci-scripts/conf_files/ci-$LOC_CONF_FILE\" > ./my-lte-softmodem-run.sh " >> $1
echo "chmod 775 ./my-lte-softmodem-run.sh" >> $1
echo "cat ./my-lte-softmodem-run.sh" >> $1
echo "if [ -e /home/ubuntu/tmp/cmake_targets/log/$LOC_LOG_FILE ]; then sudo sudo rm -f /home/ubuntu/tmp/cmake_targets/log/$LOC_LOG_FILE; fi" >> $1
echo "sudo -E daemon --inherit --unsafe --name=enb_daemon --chdir=/home/ubuntu/tmp/cmake_targets/lte_build_oai/build/ -o /home/ubuntu/tmp/cmake_targets/log/$LOC_LOG_FILE ./my-lte-softmodem-run.sh" >> $1
ssh -o StrictHostKeyChecking=no ubuntu@$LOC_VM_IP_ADDR < $1
rm $1
local i="0"
echo "egrep -c \"Waiting for PHY_config_req\" /home/ubuntu/tmp/cmake_targets/log/$LOC_LOG_FILE" > $1
while [ $i -lt 10 ]
do
sleep 5
CONNECTED=`ssh -o StrictHostKeyChecking=no ubuntu@$LOC_VM_IP_ADDR < $1`
if [ $CONNECTED -ne 0 ]
then
i="100"
else
i=$[$i+1]
fi
done
rm $1
if [ $i -lt 50 ]
then
ENB_SYNC=0
echo "L2-SIM eNB is NOT sync'ed: process still alive?"
else
ENB_SYNC=1
echo "L2-SIM eNB is sync'ed: waiting for UE(s) to connect"
fi
}
function start_l2_sim_ue {
local LOC_VM_IP_ADDR=$2
local LOC_LOG_FILE=$3
local LOC_CONF_FILE=$4
echo "echo \"cd /home/ubuntu/tmp-ue/cmake_targets/lte_build_oai/build/\"" >> $1
echo "sudo chmod 777 /home/ubuntu/tmp-ue/cmake_targets/lte_build_oai/build/" >> $1
echo "cd /home/ubuntu/tmp-ue/cmake_targets/lte_build_oai/build/" >> $1
echo "echo \"ulimit -c unlimited && ./lte-uesoftmodem -O /home/ubuntu/tmp-ue/ci-scripts/conf_files/$LOC_CONF_FILE --L2-emul 3 --num-ues 1\" > ./my-lte-softmodem-run.sh " >> $1
echo "chmod 775 ./my-lte-softmodem-run.sh" >> $1
echo "cat ./my-lte-softmodem-run.sh" >> $1
echo "if [ -e /home/ubuntu/tmp/cmake_targets/log/$LOC_LOG_FILE ]; then sudo sudo rm -f /home/ubuntu/tmp/cmake_targets/log/$LOC_LOG_FILE; fi" >> $1
echo "sudo -E daemon --inherit --unsafe --name=ue_daemon --chdir=/home/ubuntu/tmp-ue/cmake_targets/lte_build_oai/build/ -o /home/ubuntu/tmp/cmake_targets/log/$LOC_LOG_FILE ./my-lte-softmodem-run.sh" >> $1
ssh -o StrictHostKeyChecking=no ubuntu@$LOC_VM_IP_ADDR < $1
rm $1
local i="0"
echo "egrep -c \"Received NFAPI_START_REQ\" /home/ubuntu/tmp/cmake_targets/log/$LOC_LOG_FILE" > $1
while [ $i -lt 10 ]
do
sleep 5
CONNECTED=`ssh -o StrictHostKeyChecking=no ubuntu@$LOC_VM_IP_ADDR < $1`
if [ $CONNECTED -eq 1 ]
then
i="100"
else
i=$[$i+1]
fi
done
rm $1
if [ $i -lt 50 ]
then
UE_SYNC=0
echo "L2-SIM UE is NOT sync'ed w/eNB"
else
UE_SYNC=1
echo "L2-SIM UE is sync'ed w/eNB"
fi
sleep 10
}
function run_test_on_vm {
echo "############################################################"
echo "OAI CI VM script"
@@ -459,148 +749,26 @@ function run_test_on_vm {
fi
mkdir --parents $ARCHIVES_LOC
# Creating a VM for EPC and installing SW
EPC_VM_NAME=`echo $VM_NAME | sed -e "s#basic-sim#epc#"`
EPC_VM_CMDS=${EPC_VM_NAME}_cmds.txt
LTEBOX=0
if [ -d /opt/ltebox-archives/ ]
then
# Checking if all ltebox archives are available to run ltebx epc on a brand new VM
if [ -f /opt/ltebox-archives/ltebox_2.2.70_16_04_amd64.deb ] && [ -f /opt/ltebox-archives/etc-conf.zip ] && [ -f /opt/ltebox-archives/hss-sim.zip ]
then
echo "############################################################"
echo "Test EPC on VM ($EPC_VM_NAME) will be using ltebox"
echo "############################################################"
LTEBOX=1
fi
fi
# Here we could have other types of EPC detection
# Do we need to start the EPC VM
EPC_VM_CMDS=`echo $VM_CMDS | sed -e "s#cmds#epc-cmds#"`
echo "EPC_VM_CMD_FILE = $EPC_VM_CMDS"
IS_EPC_VM_ALIVE=`uvt-kvm list | grep -c $EPC_VM_NAME`
if [ $IS_EPC_VM_ALIVE -eq 0 ]
then
echo "############################################################"
echo "Creating test EPC VM ($EPC_VM_NAME) on Ubuntu Cloud Image base"
echo "############################################################"
uvt-kvm create $EPC_VM_NAME release=xenial --unsafe-caching
fi
uvt-kvm wait $EPC_VM_NAME --insecure
install_epc_on_vm $EPC_VM_NAME $EPC_VM_CMDS
EPC_VM_IP_ADDR=`uvt-kvm ip $EPC_VM_NAME`
echo "$EPC_VM_NAME has for IP addr = $EPC_VM_IP_ADDR"
scp -o StrictHostKeyChecking=no /etc/apt/apt.conf.d/01proxy ubuntu@$EPC_VM_IP_ADDR:/home/ubuntu
# ltebox specific actions (install and start)
LTE_BOX_TO_INSTALL=1
if [ $LTEBOX -eq 1 ]
then
echo "ls -ls /opt/ltebox/tools/start_ltebox" > $EPC_VM_CMDS
RESPONSE=`ssh -o StrictHostKeyChecking=no ubuntu@$EPC_VM_IP_ADDR < $EPC_VM_CMDS`
NB_EXES=`echo $RESPONSE | grep -c ltebox`
if [ $NB_EXES -eq 1 ]; then LTE_BOX_TO_INSTALL=0; fi
fi
if [ $LTEBOX -eq 1 ] && [ $LTE_BOX_TO_INSTALL -eq 1 ]
then
echo "############################################################"
echo "Copying ltebox archives into EPC VM ($EPC_VM_NAME)"
echo "############################################################"
scp -o StrictHostKeyChecking=no /opt/ltebox-archives/ltebox_2.2.70_16_04_amd64.deb ubuntu@$EPC_VM_IP_ADDR:/home/ubuntu
scp -o StrictHostKeyChecking=no /opt/ltebox-archives/etc-conf.zip ubuntu@$EPC_VM_IP_ADDR:/home/ubuntu
scp -o StrictHostKeyChecking=no /opt/ltebox-archives/hss-sim.zip ubuntu@$EPC_VM_IP_ADDR:/home/ubuntu
echo "############################################################"
echo "Install EPC on EPC VM ($EPC_VM_NAME)"
echo "############################################################"
echo "sudo cp 01proxy /etc/apt/apt.conf.d/" > $EPC_VM_CMDS
echo "touch /home/ubuntu/.hushlogin" >> $EPC_VM_CMDS
echo "echo \"sudo apt-get --yes --quiet install zip openjdk-8-jre libconfuse-dev libreadline-dev liblog4c-dev libgcrypt-dev libsctp-dev python2.7 python2.7-dev daemon iperf\"" >> $EPC_VM_CMDS
echo "sudo apt-get update > zip-install.txt 2>&1" >> $EPC_VM_CMDS
echo "sudo apt-get --yes install zip openjdk-8-jre libconfuse-dev libreadline-dev liblog4c-dev libgcrypt-dev libsctp-dev python2.7 python2.7-dev daemon iperf >> zip-install.txt 2>&1" >> $EPC_VM_CMDS
# Installing HSS
echo "echo \"cd /opt\"" >> $EPC_VM_CMDS
echo "cd /opt" >> $EPC_VM_CMDS
echo "echo \"sudo unzip -qq /home/ubuntu/hss-sim.zip\"" >> $EPC_VM_CMDS
echo "sudo unzip -qq /home/ubuntu/hss-sim.zip" >> $EPC_VM_CMDS
echo "echo \"cd /opt/hss_sim0609\"" >> $EPC_VM_CMDS
echo "cd /opt/hss_sim0609" >> $EPC_VM_CMDS
# Installing ltebox
echo "echo \"cd /home/ubuntu\"" >> $EPC_VM_CMDS
echo "cd /home/ubuntu" >> $EPC_VM_CMDS
echo "echo \"sudo dpkg -i ltebox_2.2.70_16_04_amd64.deb \"" >> $EPC_VM_CMDS
echo "sudo dpkg -i ltebox_2.2.70_16_04_amd64.deb >> zip-install.txt 2>&1" >> $EPC_VM_CMDS
echo "echo \"cd /opt/ltebox/etc/\"" >> $EPC_VM_CMDS
echo "cd /opt/ltebox/etc/" >> $EPC_VM_CMDS
echo "echo \"sudo unzip -qq -o /home/ubuntu/etc-conf.zip\"" >> $EPC_VM_CMDS
echo "sudo unzip -qq -o /home/ubuntu/etc-conf.zip" >> $EPC_VM_CMDS
echo "sudo sed -i -e 's#EPC_VM_IP_ADDRESS#$EPC_VM_IP_ADDR#' gw.conf" >> $EPC_VM_CMDS
echo "sudo sed -i -e 's#EPC_VM_IP_ADDRESS#$EPC_VM_IP_ADDR#' mme.conf" >> $EPC_VM_CMDS
fi
# Starting EPC
if [ $LTEBOX -eq 1 ]
then
echo "############################################################"
echo "Start EPC on EPC VM ($EPC_VM_NAME)"
echo "############################################################"
echo "echo \"cd /opt/hss_sim0609\"" >> $EPC_VM_CMDS
echo "cd /opt/hss_sim0609" >> $EPC_VM_CMDS
echo "echo \"sudo daemon --unsafe --name=simulated_hss --chdir=/opt/hss_sim0609 ./starthss_real\"" >> $EPC_VM_CMDS
echo "sudo daemon --unsafe --name=simulated_hss --chdir=/opt/hss_sim0609 ./starthss_real" >> $EPC_VM_CMDS
echo "echo \"cd /opt/ltebox/tools/\"" >> $EPC_VM_CMDS
echo "cd /opt/ltebox/tools/" >> $EPC_VM_CMDS
echo "echo \"sudo ./start_ltebox\"" >> $EPC_VM_CMDS
echo "nohup sudo ./start_ltebox > /home/ubuntu/ltebox.txt" >> $EPC_VM_CMDS
ssh -o StrictHostKeyChecking=no ubuntu@$EPC_VM_IP_ADDR < $EPC_VM_CMDS
rm -f $EPC_VM_CMDS
# We may have some adaptation to do
if [ -f /opt/ltebox-archives/adapt_ue_sim.txt ]
then
echo "############################################################"
echo "Doing some adaptation on UE side"
echo "############################################################"
ssh -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR < /opt/ltebox-archives/adapt_ue_sim.txt
fi
i="0"
echo "ifconfig tun5 | egrep -c \"inet addr\"" > $EPC_VM_CMDS
while [ $i -lt 10 ]
do
sleep 2
CONNECTED=`ssh -o StrictHostKeyChecking=no ubuntu@$EPC_VM_IP_ADDR < $EPC_VM_CMDS`
if [ $CONNECTED -eq 1 ]
then
i="100"
else
i=$[$i+1]
fi
done
rm $EPC_VM_CMDS
if [ $i -lt 50 ]
then
echo "Problem w/ starting ltebox EPC"
echo "TEST_KO" > $ARCHIVES_LOC/test_final_status.log
exit -1
fi
fi
# HERE ADD ANY INSTALL ACTIONS FOR ANOTHER EPC
start_epc $EPC_VM_NAME $EPC_VM_CMDS $EPC_VM_IP_ADDR
# Retrieve EPC real IP address
if [ $LTEBOX -eq 1 ]
retrieve_real_epc_ip_addr $EPC_VM_NAME $EPC_VM_CMDS $EPC_VM_IP_ADDR
# We may have some adaptation to do
if [ -f /opt/ltebox-archives/adapt_ue_sim.txt ]
then
# in our configuration file, we are using pool 5
echo "ifconfig tun5 | egrep \"inet addr\" | sed -e 's#^.*inet addr:##' -e 's# P-t-P:.*\$##'" > $EPC_VM_CMDS
REAL_EPC_IP_ADDR=`ssh -o StrictHostKeyChecking=no ubuntu@$EPC_VM_IP_ADDR < $EPC_VM_CMDS`
echo "EPC IP Address is : $REAL_EPC_IP_ADDR"
rm $EPC_VM_CMDS
echo "############################################################"
echo "Doing some adaptation on UE side"
echo "############################################################"
ssh -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR < /opt/ltebox-archives/adapt_ue_sim.txt
fi
echo "############################################################"
@@ -621,7 +789,7 @@ function run_test_on_vm {
scp -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/$CURRENT_ENB_LOG_FILE $ARCHIVES_LOC
scp -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/$CURRENT_UE_LOG_FILE $ARCHIVES_LOC
recover_core_dump $VM_CMDS $VM_IP_ADDR $ARCHIVES_LOC/$CURRENT_ENB_LOG_FILE $ARCHIVES_LOC
terminate_ltebox_epc $EPC_VM_CMDS $EPC_VM_IP_ADDR
terminate_epc $EPC_VM_CMDS $EPC_VM_IP_ADDR
echo "TEST_KO" > $ARCHIVES_LOC/test_final_status.log
exit -1
fi
@@ -680,7 +848,7 @@ function run_test_on_vm {
scp -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/$CURRENT_ENB_LOG_FILE $ARCHIVES_LOC
scp -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/$CURRENT_UE_LOG_FILE $ARCHIVES_LOC
recover_core_dump $VM_CMDS $VM_IP_ADDR $ARCHIVES_LOC/$CURRENT_ENB_LOG_FILE $ARCHIVES_LOC
terminate_ltebox_epc $EPC_VM_CMDS $EPC_VM_IP_ADDR
terminate_epc $EPC_VM_CMDS $EPC_VM_IP_ADDR
echo "TEST_KO" > $ARCHIVES_LOC/test_final_status.log
exit -1
fi
@@ -739,7 +907,7 @@ function run_test_on_vm {
scp -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/$CURRENT_ENB_LOG_FILE $ARCHIVES_LOC
scp -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/$CURRENT_UE_LOG_FILE $ARCHIVES_LOC
recover_core_dump $VM_CMDS $VM_IP_ADDR $ARCHIVES_LOC/$CURRENT_ENB_LOG_FILE $ARCHIVES_LOC
terminate_ltebox_epc $EPC_VM_CMDS $EPC_VM_IP_ADDR
terminate_epc $EPC_VM_CMDS $EPC_VM_IP_ADDR
echo "TEST_KO" > $ARCHIVES_LOC/test_final_status.log
exit -1
fi
@@ -791,7 +959,7 @@ function run_test_on_vm {
if [ $j -lt 50 ]
then
echo "ERROR: compiling flexran controller on vm went wrong"
terminate_ltebox_epc $EPC_VM_CMDS $EPC_VM_IP_ADDR
terminate_epc $EPC_VM_CMDS $EPC_VM_IP_ADDR
echo "TEST_KO" > $ARCHIVES_LOC/test_final_status.log
exit -1
fi
@@ -801,7 +969,7 @@ function run_test_on_vm {
if [ $IS_FLEXRAN_VM_ALIVE -eq 0 ]
then
echo "ERROR: Flexran Ctl VM is not alive"
terminate_ltebox_epc $EPC_VM_CMDS $EPC_VM_IP_ADDR
terminate_epc $EPC_VM_CMDS $EPC_VM_IP_ADDR
echo "TEST_KO" > $ARCHIVES_LOC/test_final_status.log
exit -1
fi
@@ -835,7 +1003,7 @@ function run_test_on_vm {
scp -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/$CURRENT_ENB_LOG_FILE $ARCHIVES_LOC
scp -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/$CURRENT_UE_LOG_FILE $ARCHIVES_LOC
recover_core_dump $VM_CMDS $VM_IP_ADDR $ARCHIVES_LOC/$CURRENT_ENB_LOG_FILE $ARCHIVES_LOC
terminate_ltebox_epc $EPC_VM_CMDS $EPC_VM_IP_ADDR
terminate_epc $EPC_VM_CMDS $EPC_VM_IP_ADDR
stop_flexran_ctrl $FLEXRAN_CTL_VM_CMDS $FLEXRAN_CTL_VM_IP_ADDR
echo "TEST_KO" > $ARCHIVES_LOC/test_final_status.log
exit -1
@@ -878,7 +1046,7 @@ function run_test_on_vm {
scp -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/$CURRENT_ENB_LOG_FILE $ARCHIVES_LOC
scp -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/$CURRENT_UE_LOG_FILE $ARCHIVES_LOC
recover_core_dump $VM_CMDS $VM_IP_ADDR $ARCHIVES_LOC/$CURRENT_ENB_LOG_FILE $ARCHIVES_LOC
terminate_ltebox_epc $EPC_VM_CMDS $EPC_VM_IP_ADDR
terminate_epc $EPC_VM_CMDS $EPC_VM_IP_ADDR
echo "TEST_KO" > $ARCHIVES_LOC/test_final_status.log
exit -1
fi
@@ -929,7 +1097,7 @@ function run_test_on_vm {
scp -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/$CURRENT_ENB_LOG_FILE $ARCHIVES_LOC
scp -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/$CURRENT_UE_LOG_FILE $ARCHIVES_LOC
recover_core_dump $VM_CMDS $VM_IP_ADDR $ARCHIVES_LOC/$CURRENT_ENB_LOG_FILE $ARCHIVES_LOC
terminate_ltebox_epc $EPC_VM_CMDS $EPC_VM_IP_ADDR
terminate_epc $EPC_VM_CMDS $EPC_VM_IP_ADDR
echo "TEST_KO" > $ARCHIVES_LOC/test_final_status.log
exit -1
fi
@@ -980,7 +1148,7 @@ function run_test_on_vm {
# scp -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/$CURRENT_ENB_LOG_FILE $ARCHIVES_LOC
# scp -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/$CURRENT_UE_LOG_FILE $ARCHIVES_LOC
# recover_core_dump $VM_CMDS $VM_IP_ADDR $ARCHIVES_LOC/$CURRENT_ENB_LOG_FILE $ARCHIVES_LOC
# terminate_ltebox_epc $EPC_VM_CMDS $EPC_VM_IP_ADDR
# terminate_epc $EPC_VM_CMDS $EPC_VM_IP_ADDR
# echo "TEST_KO" > $ARCHIVES_LOC/test_final_status.log
# exit -1
# fi
@@ -1016,10 +1184,7 @@ function run_test_on_vm {
echo "Terminate EPC"
echo "############################################################"
if [ $LTEBOX -eq 1 ]
then
terminate_ltebox_epc $EPC_VM_CMDS $EPC_VM_IP_ADDR
fi
terminate_epc $EPC_VM_CMDS $EPC_VM_IP_ADDR
if [ $KEEP_VM_ALIVE -eq 0 ]
then
@@ -1051,4 +1216,97 @@ function run_test_on_vm {
echo "TEST_KO" > $ARCHIVES_LOC/test_final_status.log
fi
fi
if [[ "$RUN_OPTIONS" == "complex" ]] && [[ $VM_NAME =~ .*-l2-sim.* ]]
then
PING_STATUS=0
IPERF_STATUS=0
if [ -d $ARCHIVES_LOC ]
then
rm -Rf $ARCHIVES_LOC
fi
mkdir --parents $ARCHIVES_LOC
# Building UE elsewhere in VM
build_ue_on_separate_folder $VM_CMDS $VM_IP_ADDR
# Creating a VM for EPC and installing SW
EPC_VM_NAME=`echo $VM_NAME | sed -e "s#l2-sim#l2-epc#"`
EPC_VM_CMDS=${EPC_VM_NAME}_cmds.txt
LTEBOX=0
install_epc_on_vm $EPC_VM_NAME $EPC_VM_CMDS
EPC_VM_IP_ADDR=`uvt-kvm ip $EPC_VM_NAME`
# Starting EPC
start_epc $EPC_VM_NAME $EPC_VM_CMDS $EPC_VM_IP_ADDR
# Retrieve EPC real IP address
retrieve_real_epc_ip_addr $EPC_VM_NAME $EPC_VM_CMDS $EPC_VM_IP_ADDR
echo "############################################################"
echo "Starting the eNB in FDD-5MHz mode"
echo "############################################################"
CURRENT_ENB_LOG_FILE=fdd_05MHz_enb.log
start_l2_sim_enb $VM_CMDS $VM_IP_ADDR $EPC_VM_IP_ADDR $CURRENT_ENB_LOG_FILE 25 rcc.band7.tm1.nfapi.conf
echo "############################################################"
echo "Starting the UEs"
echo "############################################################"
CURRENT_UE_LOG_FILE=fdd_05MHz_ue.log
start_l2_sim_ue $VM_CMDS $VM_IP_ADDR $CURRENT_UE_LOG_FILE ue.nfapi.conf
if [ $UE_SYNC -eq 0 ]
then
echo "Problem w/ eNB and UE not syncing"
terminate_enb_ue_basic_sim $VM_CMDS $VM_IP_ADDR
scp -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/$CURRENT_ENB_LOG_FILE $ARCHIVES_LOC
scp -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/$CURRENT_UE_LOG_FILE $ARCHIVES_LOC
terminate_epc $EPC_VM_CMDS $EPC_VM_IP_ADDR
echo "TEST_KO" > $ARCHIVES_LOC/test_final_status.log
exit -1
fi
echo "############################################################"
echo "Pinging the EPC from UE"
echo "############################################################"
PING_LOG_FILE=fdd_05MHz_ping_epc.txt
ping_epc_ip_addr $VM_CMDS $VM_IP_ADDR $REAL_EPC_IP_ADDR $PING_LOG_FILE
scp -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR:/home/ubuntu/$PING_LOG_FILE $ARCHIVES_LOC
check_ping_result $ARCHIVES_LOC/$PING_LOG_FILE 20
echo "############################################################"
echo "Terminate enb/ue simulators"
echo "############################################################"
terminate_enb_ue_basic_sim $VM_CMDS $VM_IP_ADDR
scp -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/$CURRENT_ENB_LOG_FILE $ARCHIVES_LOC
scp -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/$CURRENT_UE_LOG_FILE $ARCHIVES_LOC
echo "############################################################"
echo "Terminate EPC"
echo "############################################################"
terminate_epc $EPC_VM_CMDS $EPC_VM_IP_ADDR
if [ $KEEP_VM_ALIVE -eq 0 ]
then
echo "############################################################"
echo "Destroying VMs"
echo "############################################################"
uvt-kvm destroy $VM_NAME
ssh-keygen -R $VM_IP_ADDR
uvt-kvm destroy $EPC_VM_NAME
ssh-keygen -R $EPC_VM_IP_ADDR
fi
echo "############################################################"
echo "Checking run status"
echo "############################################################"
if [ $PING_STATUS -ne 0 ]; then STATUS=-1; fi
if [ $STATUS -eq 0 ]
then
echo "TEST_OK" > $ARCHIVES_LOC/test_final_status.log
else
echo "TEST_KO" > $ARCHIVES_LOC/test_final_status.log
fi
fi
}
+1
View File
@@ -615,6 +615,7 @@ add_boolean_option(MESSAGE_CHART_GENERATOR_PHY False "trace some PHY exchang
add_boolean_option(UE_EXPANSION False "enable UE_EXPANSION with max 256 UE")
add_boolean_option(PHY_TX_THREAD False "enable UE_EXPANSION with max 256 UE")
add_boolean_option(PRE_SCD_THREAD False "enable UE_EXPANSION with max 256 UE")
add_boolean_option(UESIM_EXPANSION False "enable UESIM_EXPANSION with max 256 UE")
########################
# Include order
+6
View File
@@ -43,6 +43,7 @@ conf_nvram_path=$OPENAIR_DIR/openair3/NAS/TOOLS/ue_eurecom_test_sfr.conf
MSC_GEN=0
XFORMS="True"
UE_EXPANSION="False"
UESIM_EXPANSION="False"
PRINT_STATS="False"
VCD_TIMING="False"
DEADLINE_SCHEDULER_FLAG_USER="False"
@@ -218,6 +219,10 @@ function main() {
UE_EXPANSION="True"
echo_info "Will compile with UE_EXPANSION"
shift;;
--musim)
UESIM_EXPANSION="True"
echo_info "Will compile with UESIM_EXPANSION"
shift;;
--UE-conf-nvram)
conf_nvram_path=$(readlink -f $2)
shift 2;;
@@ -551,6 +556,7 @@ function main() {
echo "set ( UE_EXPANSION $UE_EXPANSION )" >> $cmake_file
# echo "set ( PHY_TX_THREAD $UE_EXPANSION )" >> $cmake_file
echo "set ( PRE_SCD_THREAD $UE_EXPANSION )" >> $cmake_file
echo "set ( UESIM_EXPANSION $UESIM_EXPANSION )" >> $cmake_file
echo "set ( RRC_ASN1_VERSION \"${REL}\")" >> $cmake_file
echo "set ( ENABLE_VCD_FIFO $VCD_TIMING )" >> $cmake_file
echo "set ( RF_BOARD \"${HW}\")" >> $cmake_file
+2 -2
View File
@@ -32,8 +32,8 @@ OS_DISTRO=$(grep "^ID=" /etc/os-release | sed "s/ID=//" | sed "s/\"//g")
OS_RELEASE=$(grep "^VERSION_ID=" /etc/os-release | sed "s/VERSION_ID=//" | sed "s/\"//g")
case "$OS_DISTRO" in
fedora) OS_BASEDISTRO="fedora"; INSTALLER="dnf"; CMAKE="cmake" ;;
rhel) OS_BASEDISTRO="fedora"; INSTALLER="yum"; CMAKE="cmake3" ;;
centos) OS_BASEDISTRO="fedora"; INSTALLER="yum"; CMAKE="cmake3" ;;
rhel) OS_BASEDISTRO="fedora"; INSTALLER="yum --skip-broken"; CMAKE="cmake3" ;;
centos) OS_BASEDISTRO="fedora"; INSTALLER="yum --skip-broken"; CMAKE="cmake3" ;;
debian) OS_BASEDISTRO="debian"; INSTALLER="apt-get"; CMAKE="cmake" ;;
ubuntu) OS_BASEDISTRO="debian"; INSTALLER="apt-get"; CMAKE="cmake" ;;
esac
+7 -7
View File
@@ -52,20 +52,20 @@ load_module ../../targets/bin/ue_ip.ko
if [ "$1" = "UE" ]; then
echo "bring up $LTEIF interface for UE"
ifconfig $LTEIF up
sudo ifconfig $LTEIF up
fi
ip route flush cache
sudo ip route flush cache
sleep 1
sysctl -w net.ipv4.conf.all.log_martians=1
sudo sysctl -w net.ipv4.conf.all.log_martians=1
echo "Disabling reverse path filtering"
sysctl -w net.ipv4.conf.all.rp_filter=0
ip route flush cache
sudo sysctl -w net.ipv4.conf.all.rp_filter=0
sudo ip route flush cache
# Check table 200 lte in /etc/iproute2/rt_tables
fgrep lte /etc/iproute2/rt_tables > /dev/null
if [ $? -ne 0 ]; then
echo "200 lte " >> /etc/iproute2/rt_tables
fi
ip rule add fwmark 1 table lte
ip route add default dev $LTEIF table lte
sudo ip rule add fwmark 1 table lte
sudo ip route add default dev $LTEIF table lte
+1 -1
View File
@@ -1,6 +1,6 @@
# OAI configuration module
The configuration module provides an api that other oai components can use to get parameters at init time. It defines a parameter structure, used to describe parameters attributes (for example name and type). The same structure includes a pointer to the variable where the configuration module writes the parameter value, at run time, when calling config_get or config_getlist functions. For each parameter a function to check the value can be specified and pre-defined functions are provided for some common parameter validations (integer in a range or in a list, string in a list). The module also include a mechanism to check that no unknown options have been entered on the command line
The configuration module provides an api that other oai components can use to get parameters at init time. It defines a parameter structure, used to describe parameters attributes (for example name and type). The same structure includes a pointer to the variable where the configuration module writes the parameter value, at run time, when calling config_get or config_getlist functions. For each parameter a function to check the value can be specified and pre-defined functions are provided for some common parameter validations (integer in a range or in a list, string in a list). The module also include an api to check that no unknown options have been entered on the command line and a a mechanism to display a help text for suppoted parameters.
## Documentation
+3 -2
View File
@@ -1,11 +1,12 @@
```c
configmodule_interface_t *load_configmodule(int argc, char **argv)
configmodule_interface_t *load_configmodule(int argc, char **argv, uint32_t initflags)
```
* Parses the command line options, looking for the –O argument
* Loads the `libparams_<configsource>.so` (today `libparams_libconfig.so`) shared library
* Looks for `config_<config source>_init` symbol and calls it , passing it an array of string corresponding to the « : » separated strings used in the –O option
* Looks for `config_<config source>_get`, `config_<config source>_getlist` and `config_<config source>_end` symbols which are the three functions a configuration library should implement. Get and getlist are mandatory, end is optional.
* Stores all the necessary information in a `configmodule_interface_t structure`, which is of no use for caller as long as we only use one configuration source.
* Stores all the necessary information in a `configmodule_interface_t structure`, which is of no use for caller as long as we only use one configuration source.
* if the bit CONFIG_ENABLECMDLINEONLY is set in `initflags` then the module allows parameters to be set only via the command line. This is used for the oai UE.
```c
void End_configmodule(void)
+57
View File
@@ -27,6 +27,63 @@ $ ./lte-softmodem -O libconfig:<config>:dbgl1
```bash
$ ./lte-uesoftmodem -O cmdlineonly:dbgl1
```
To get help on supported parameters you can use specific options:
* ---help: print help for command line only parameters and for parameters not defined in a specific section
* ---help_< prefix > : print help for parameters defined under the section < prefix >
```
./lte-softmodem -O libconfig:/usr/local/oai/conf/enb.nbiot.band7.tm1.50PRB.usrpb210.conf --help
[CONFIG] get parameters from libconfig /usr/local/oai/conf/enb.nbiot.band7.tm1.50PRB.usrpb210.conf , debug flags: 0x00000000
.............................................
[LIBCONFIG] (root): 19/19 parameters successfully set, (16 to default value)
-----Help for section (root section) : 019 entries------
--rf-config-file: Configuration file for front-end (e.g. LMS7002M)
--ulsch-max-errors: set the eNodeB max ULSCH erros
--phy-test: test UE phy layer, mac disabled
--usim-test: use XOR autentication algo in case of test usim mode
--emulate-rf: Emulated RF enabled(disable by defult)
--clock: tells hardware to use a clock reference (0:internal, 1:external, 2:gpsdo)
--wait-for-sync: Help string not specified
--single-thread-enable: Disables single-thread mode in lte-softmodem
-C: Set the downlink frequency for all component carriers
-a: Channel id offset
-d: Enable soft scope and L1 and L2 stats (Xforms)
-q: Enable processing timing measurement of lte softmodem on per subframe basis
-S: Skip the missed slots/subframes
--numerology: adding numerology for 5G
--parallel-config: three config for level of parallelism 'PARALLEL_SINGLE_THREAD', 'PARALLEL_RU_L1_SPLIT', or 'PARALLEL_RU_L1_TRX_SPLIT'
--worker-config: two option for worker 'WORKER_DISABLE' or 'WORKER_ENABLE'
--nbiot-disable: disable nb-iot, even if defined in config
--noS1: Disable s1 interface
--nokrnmod: (noS1 only): Use tun instead of namesh module
--------------------------------------------------------------------
[LIBCONFIG] (root): 4/4 parameters successfully set, (4 to default value)
-----Help for section (root section) : 004 entries------
-R: Enable online log
-g: Set the global log level, valide options: (4:trace, 3:debug, 2:info, 1:warn, (0:error))
--telnetsrv: Start embedded telnet server
--msc: Enable the MSC tracing utility
--------------------------------------------------------------------
[LIBCONFIG] loader: 2/2 parameters successfully set, (2 to default value)
[LIBCONFIG] loader.telnetsrv: 2/2 parameters successfully set, (1 to default value)
[LOADER] library libtelnetsrv.so is not loaded: libtelnetsrv.so: cannot open shared object file: No such file or directory
Getting ENBSParams
[LIBCONFIG] (root): 3/3 parameters successfully set, (1 to default value)
-----Help for section (root section) : 003 entries------
--Asn1_verbosity: Help string not specified
--Active_eNBs: Help string not specified
--noS1: Help string not specified
--------------------------------------------------------------------
/usr/local/oai/issue390_configmodule_cmdlinebug/openairinterface5g/common/config/config_cmdline.c:224 config_process_cmdline() Exiting OAI softmodem: [CONFIG] Exiting after displaying help
```
For the lte-softmodem (the eNodeB) The config source parameter defaults to libconfig, preserving the initial -O option format. In this case you cannot specify the debug level.
```bash
+33 -26
View File
@@ -37,7 +37,7 @@
#include <errno.h>
#include <platform_types.h>
#include "config_userapi.h"
#include "../utils/LOG/log.h"
int parse_stringlist(paramdef_t *cfgoptions, char *val) {
char *atoken;
@@ -74,15 +74,15 @@ int processoption(paramdef_t *cfgoptions, char *value) {
if ( value == NULL) {
if( (cfgoptions->paramflags &PARAMFLAG_BOOL) == 0 ) { /* not a boolean, argument required */
fprintf(stderr,"[CONFIG] command line, option %s requires an argument\n",cfgoptions->optname);
exit_fun("[CONFIG] command line parsing fatal error");
return 0;
CONFIG_PRINTF_ERROR("[CONFIG] command line, option %s requires an argument\n",cfgoptions->optname);
} else { /* boolean value option without argument, set value to true*/
tmpval = defbool;
}
}
switch(cfgoptions->type) {
char *charptr;
case TYPE_STRING:
if (cfgoptions->numelt == 0 ) {
config_check_valptr(cfgoptions, cfgoptions->strptr, strlen(tmpval)+1);
@@ -106,14 +106,24 @@ int processoption(paramdef_t *cfgoptions, char *value) {
case TYPE_UINT8:
case TYPE_INT8:
config_check_valptr(cfgoptions, (char **)&(cfgoptions->iptr),sizeof(int32_t));
config_assign_int(cfgoptions,cfgoptions->optname,(int32_t)strtol(tmpval,NULL,0));
config_assign_int(cfgoptions,cfgoptions->optname,(int32_t)strtol(tmpval,&charptr,0));
if( *charptr != 0) {
CONFIG_PRINTF_ERROR("[CONFIG] command line, option %s requires an integer argument\n",cfgoptions->optname);
}
optisset=1;
break;
case TYPE_UINT64:
case TYPE_INT64:
config_check_valptr(cfgoptions, (char **)&(cfgoptions->i64ptr),sizeof(uint64_t));
*(cfgoptions->i64ptr)=strtoll(tmpval,NULL,0);
*(cfgoptions->i64ptr)=strtoll(tmpval,&charptr,0);
if( *charptr != 0) {
CONFIG_PRINTF_ERROR("[CONFIG] command line, option %s requires an integer argument\n",cfgoptions->optname);
}
printf_cmdl("[CONFIG] %s set to %lli from command line\n", cfgoptions->optname, (long long)*(cfgoptions->i64ptr));
optisset=1;
break;
@@ -124,7 +134,12 @@ int processoption(paramdef_t *cfgoptions, char *value) {
case TYPE_DOUBLE:
config_check_valptr(cfgoptions, (char **)&(cfgoptions->dblptr),sizeof(double));
*(cfgoptions->dblptr) = strtof(tmpval,NULL);
*(cfgoptions->dblptr) = strtof(tmpval,&charptr);
if( *charptr != 0) {
CONFIG_PRINTF_ERROR("[CONFIG] command line, option %s requires a double argument\n",cfgoptions->optname);
}
printf_cmdl("[CONFIG] %s set to %lf from command line\n", cfgoptions->optname, *(cfgoptions->dblptr));
optisset=1;
break;
@@ -133,7 +148,7 @@ int processoption(paramdef_t *cfgoptions, char *value) {
break;
default:
fprintf(stderr,"[CONFIG] command line, %s type %i not supported\n",cfgoptions->optname, cfgoptions->type);
CONFIG_PRINTF_ERROR("[CONFIG] command line, %s type %i not supported\n",cfgoptions->optname, cfgoptions->type);
break;
} /* switch on param type */
@@ -149,14 +164,15 @@ int processoption(paramdef_t *cfgoptions, char *value) {
*/
int config_check_unknown_cmdlineopt(char *prefix) {
int unknowndetected=0;
char testprefix[CONFIG_MAXOPTLENGTH]="";
char testprefix[CONFIG_MAXOPTLENGTH];
int finalcheck = 0;
memset(testprefix,0,sizeof(testprefix));
if (prefix != NULL) {
if (strcmp(prefix,CONFIG_CHECKALLSECTIONS) == 0)
finalcheck = 1;
else if (strlen(prefix) > 0) {
sprintf(testprefix,"--%s.",prefix);
sprintf(testprefix,"--%.*s.",CONFIG_MAXOPTLENGTH-1,prefix);
}
}
@@ -176,8 +192,11 @@ int config_check_unknown_cmdlineopt(char *prefix) {
}
}
printf_cmdl("[CONFIG] %i unknown option(s) in command line starting with %s (section %s)\n",
unknowndetected,testprefix,((prefix==NULL)?"":prefix));
if (unknowndetected > 0) {
CONFIG_PRINTF_ERROR("[CONFIG] %i unknown option(s) in command line starting with %s (section %s)\n",
unknowndetected,testprefix,((prefix==NULL)?"":prefix));
}
return unknowndetected;
} /* config_check_unknown_cmdlineopt */
@@ -200,7 +219,7 @@ int config_process_cmdline(paramdef_t *cfgoptions,int numoptions, char *prefix)
if (pp == NULL || strcasecmp(pp,config_get_if()->argv[i] ) == 0 ) {
if( prefix == NULL) {
config_printhelp(cfgoptions,numoptions);
config_printhelp(cfgoptions,numoptions,"(root section)");
if ( ! ( CONFIG_ISFLAGSET(CONFIG_NOEXITONHELP)))
exit_fun("[CONFIG] Exiting after displaying help\n");
@@ -209,8 +228,7 @@ int config_process_cmdline(paramdef_t *cfgoptions,int numoptions, char *prefix)
pp=strtok_r(NULL, " ",&tokctx);
if ( prefix != NULL && pp != NULL && strncasecmp(prefix,pp,strlen(pp)) == 0 ) {
printf ("Help for %s section:\n",prefix);
config_printhelp(cfgoptions,numoptions);
config_printhelp(cfgoptions,numoptions,prefix);
if ( ! (CONFIG_ISFLAGSET(CONFIG_NOEXITONHELP))) {
fprintf(stderr,"[CONFIG] %s %i section %s:", __FILE__, __LINE__, prefix);
@@ -273,16 +291,5 @@ int config_process_cmdline(paramdef_t *cfgoptions,int numoptions, char *prefix)
} /* fin du while */
printf_cmdl("[CONFIG] %s %i options set from command line\n",((prefix == NULL) ? "(root)":prefix),j);
if ( !(CONFIG_ISFLAGSET( CONFIG_NOCHECKUNKOPT )) ) {
i=config_check_unknown_cmdlineopt(prefix);
if (i > 0) {
fprintf(stderr,"[CONFIG] %i unknown options for section %s detected in command line\n",
i,((prefix==NULL)?"\"root section\"":prefix));
exit_fun(" Exiting after detecting errors in command line \n");
}
}
return j;
} /* parse_cmdline*/
+6 -3
View File
@@ -36,12 +36,15 @@
#include <unistd.h>
#include <errno.h>
#include <dlfcn.h>
#include <platform_types.h>
#define CONFIG_LOADCONFIG_MAIN
#include "config_load_configmodule.h"
#include "config_userapi.h"
#include "../utils/LOG/log.h"
#define CONFIG_SHAREDLIBFORMAT "libparams_%s.so"
int load_config_sharedlib(configmodule_interface_t *cfgptr) {
void *lib_handle;
char fname[128];
@@ -198,7 +201,7 @@ configmodule_interface_t *load_configmodule(int argc, char **argv, uint32_t init
}
if ( strstr(argv[i], "help_config") != NULL ) {
config_printhelp(Config_Params,CONFIG_PARAMLENGTH(Config_Params));
config_printhelp(Config_Params,CONFIG_PARAMLENGTH(Config_Params),CONFIG_SECTIONNAME);
exit(0);
}
@@ -304,7 +307,7 @@ configmodule_interface_t *load_configmodule(int argc, char **argv, uint32_t init
if (cfgmode != NULL) free(cfgmode);
if (CONFIG_ISFLAGSET(CONFIG_ABORT)) {
config_printhelp(Config_Params,CONFIG_PARAMLENGTH(Config_Params));
config_printhelp(Config_Params,CONFIG_PARAMLENGTH(Config_Params),CONFIG_SECTIONNAME );
// exit(-1);
}
@@ -342,7 +345,7 @@ void free_configmodule(void) {
if( cfgptr->cfgmode != NULL) free(cfgptr->cfgmode);
printf ("[CONFIG] free %u config parameter pointers\n",cfgptr->num_cfgP);
printf ("[CONFIG] free %i config parameter pointers\n",cfgptr->num_cfgP);
for (int i=0; i<cfgptr->num_cfgP; i++) {
if ( cfgptr->cfgP[i] != NULL) free(cfgptr->cfgP[i]);
+2 -1
View File
@@ -51,7 +51,6 @@
#define CONFIG_PRINTPARAMS 1 // print parameters values while processing
#define CONFIG_DEBUGPTR (1<<1) // print memory allocation/free debug messages
#define CONFIG_DEBUGCMDLINE (1<<2) // print command line processing messages
#define CONFIG_NOCHECKUNKOPT (1<<3) // disable check unprocessed (so invalid) command line options
#define CONFIG_NOABORTONCHKF (1<<4) // disable abort execution when parameter checking function fails
#define CONFIG_NOEXITONHELP (1<<19) // do not exit after printing help
#define CONFIG_HELP (1<<20) // print help message
@@ -109,5 +108,7 @@ extern configmodule_interface_t *cfgptr;
#define CONFIG_ENABLECMDLINEONLY (1<<1)
extern configmodule_interface_t *load_configmodule(int argc, char **argv, uint32_t initflags);
extern void end_configmodule(void);
#define CONFIG_PRINTF_ERROR(f, x... ) if (isLogInitDone ()) { LOG_E(ENB_APP,f,x);} else {printf(f,x);}; if ( !CONFIG_ISFLAGSET(CONFIG_NOABORTONCHKF) ) exit_fun("exit because configuration failed\n");
#endif /* INCLUDE_CONFIG_LOADCONFIGMODULE_H */
+20 -27
View File
@@ -39,15 +39,13 @@
#include <errno.h>
#include <dlfcn.h>
#include <arpa/inet.h>
#include <platform_types.h>
#include "config_userapi.h"
#include "../utils/LOG/log.h"
configmodule_interface_t *config_get_if(void) {
if (cfgptr == NULL) {
fprintf(stderr,"[CONFIG] %s %d config module not initialized\n",__FILE__, __LINE__);
exit(-1);
CONFIG_PRINTF_ERROR("[CONFIG] %s %d config module not initialized\n",__FILE__,__LINE__);
}
return cfgptr;
@@ -66,9 +64,8 @@ char *config_check_valptr(paramdef_t *cfgoptions, char **ptr, int length) {
config_get_if()->numptrs++;
}
} else {
fprintf(stderr, "[CONFIG] %s %d option %s, cannot allocate pointer: %s \n",
__FILE__, __LINE__, cfgoptions->optname, strerror(errno));
exit(-1);
CONFIG_PRINTF_ERROR("[CONFIG] %s %d option %s, cannot allocate pointer: %s \n",
__FILE__, __LINE__, cfgoptions->optname, strerror(errno));
}
}
@@ -78,9 +75,8 @@ char *config_check_valptr(paramdef_t *cfgoptions, char **ptr, int length) {
if (*ptr != NULL) {
return *ptr;
} else {
fprintf(stderr,"[CONFIG] %s %d option %s, definition error: value pointer is NULL, declared as %i bytes allocated\n",
__FILE__, __LINE__,cfgoptions->optname, cfgoptions->numelt);
exit(-1);
CONFIG_PRINTF_ERROR("[CONFIG] %s %d option %s, definition error: value pointer is NULL, declared as %i bytes allocated\n",
__FILE__, __LINE__,cfgoptions->optname, cfgoptions->numelt);
}
}
@@ -95,8 +91,7 @@ char *config_check_valptr(paramdef_t *cfgoptions, char **ptr, int length) {
config_get_if()->numptrs++;
}
} else {
fprintf (stderr,"[CONFIG] %s %d malloc error\n",__FILE__, __LINE__);
exit(-1);
CONFIG_PRINTF_ERROR("[CONFIG] %s %d malloc error\n",__FILE__, __LINE__);
}
}
@@ -157,8 +152,7 @@ void config_assign_processedint(paramdef_t *cfgoption, int val) {
if ( cfgoption->processedvalue != NULL) {
*(cfgoption->processedvalue) = val;
} else {
fprintf (stderr,"[CONFIG] %s %d malloc error\n",__FILE__, __LINE__);
exit(-1);
CONFIG_PRINTF_ERROR("[CONFIG] %s %d malloc error\n",__FILE__, __LINE__);
}
}
@@ -177,15 +171,17 @@ int config_get_processedint(paramdef_t *cfgoption) {
return ret;
}
void config_printhelp(paramdef_t *params,int numparams) {
void config_printhelp(paramdef_t *params,int numparams, char *prefix) {
printf("\n-----Help for section %-26s: %03i entries------\n",(prefix==NULL)?"(root section)":prefix ,numparams);
for (int i=0 ; i<numparams ; i++) {
if ( params[i].helpstr != NULL) {
printf("%s%s: %s",
(strlen(params[i].optname) <= 1) ? "-" : "--",
params[i].optname,
params[i].helpstr);
}
}
printf(" %s%s: %s",
(strlen(params[i].optname) <= 1) ? "-" : "--",
params[i].optname,
(params[i].helpstr != NULL)?params[i].helpstr:"Help string not specified\n");
} /* for on params entries */
printf("--------------------------------------------------------------------\n\n");
}
int config_execcheck(paramdef_t *params,int numparams, char *prefix) {
@@ -202,11 +198,7 @@ int config_execcheck(paramdef_t *params,int numparams, char *prefix) {
}
if (st != 0) {
fprintf(stderr,"[CONFIG] config_execcheck: section %s %i parameters with wrong value\n", prefix, -st);
if ( CONFIG_ISFLAGSET(CONFIG_NOABORTONCHKF) == 0) {
exit_fun("exit because configuration failed\n");
}
CONFIG_PRINTF_ERROR("[CONFIG] config_execcheck: section %s %i parameters with wrong value\n", prefix, -st);
}
return st;
@@ -263,6 +255,7 @@ int config_getlist(paramlist_def_t *ParamList, paramdef_t *params, int numparams
for (int i = 0; i < ParamList->numelt; ++i) {
// TODO config_process_cmdline?
sprintf(cfgpath, "%s.[%i]", newprefix, i);
config_process_cmdline(ParamList->paramarray[i],numparams,cfgpath);
config_execcheck(ParamList->paramarray[i], numparams, cfgpath);
}
+1 -1
View File
@@ -49,7 +49,7 @@ extern "C"
/* utility functions, to be used by configuration module and/or configuration libraries */
extern configmodule_interface_t *config_get_if(void);
extern char *config_check_valptr(paramdef_t *cfgoptions, char **ptr, int length) ;
extern void config_printhelp(paramdef_t *,int numparams);
extern void config_printhelp(paramdef_t *,int numparams, char *prefix);
extern int config_process_cmdline(paramdef_t *params,int numparams, char *prefix);
extern void config_assign_processedint(paramdef_t *cfgoption, int val);
extern void config_assign_int(paramdef_t *cfgoptions, char *fullname, int val);
+1 -2
View File
@@ -219,7 +219,6 @@ void log_getconfig(log_t *g_log) {
paramdef_t logparams_logfile[MAX_LOG_PREDEF_COMPONENTS];
paramdef_t logparams_debug[sizeof(log_maskmap)/sizeof(mapping)];
paramdef_t logparams_dump[sizeof(log_maskmap)/sizeof(mapping)];
CONFIG_SETRTFLAG(CONFIG_NOCHECKUNKOPT);
int ret = config_get( logparams_defaults,sizeof(logparams_defaults)/sizeof(paramdef_t),CONFIG_STRING_LOG_PREFIX);
if (ret <0) {
@@ -305,8 +304,8 @@ void log_getconfig(log_t *g_log) {
}
config_get( logparams_debug,(sizeof(log_maskmap)/sizeof(mapping)) - 1 ,CONFIG_STRING_LOG_PREFIX);
CONFIG_CLEARRTFLAG(CONFIG_NOCHECKUNKOPT);
config_get( logparams_dump,(sizeof(log_maskmap)/sizeof(mapping)) - 1 ,CONFIG_STRING_LOG_PREFIX);
config_check_unknown_cmdlineopt(CONFIG_STRING_LOG_PREFIX);
/* set the debug mask according to the debug parameters values */
for (int i=0; log_maskmap[i].name != NULL ; i++) {
+4
View File
@@ -145,6 +145,7 @@ extern "C" {
#define DEBUG_CTRLSOCKET (1<<10)
#define DEBUG_SECURITY (1<<11)
#define DEBUG_NAS (1<<12)
#define DEBUG_RLC (1<<13)
#define UE_TIMING (1<<20)
@@ -162,6 +163,7 @@ extern "C" {
{"CTRLSOCKET", DEBUG_CTRLSOCKET},\
{"SECURITY", DEBUG_SECURITY},\
{"NAS", DEBUG_NAS},\
{"RLC", DEBUG_RLC},\
{"UE_TIMING", UE_TIMING},\
{NULL,-1}\
}
@@ -345,6 +347,8 @@ int32_t write_file_matlab(const char *fname, const char *vname, void *data, int
}
#define LOG_OPTIONS_IDX 2
/*----------------------------------------------------------------------------------*/
/** @defgroup _debugging debugging macros
* @ingroup _macro
+97 -67
View File
@@ -12,15 +12,17 @@
#include "common/config/config_userapi.h"
#define QUIT(x) do { \
printf("T tracer: QUIT: %s\n", x); \
exit(1); \
} while (0)
printf("T tracer: QUIT: %s\n", x); \
exit(1); \
} while (0)
/* array used to activate/disactivate a log */
static int T_IDs[T_NUMBER_OF_IDS];
int *T_active = T_IDs;
int T_stdout = 1;
static int T_socket;
/* T_cache
@@ -32,125 +34,159 @@ volatile int *T_freelist_head = &_T_freelist_head;
T_cache_t *T_cache;
#if BASIC_SIMULATOR
/* global variables used by T_GET_SLOT, see in T.h */
volatile uint64_t T_next_id;
volatile uint64_t T_active_id;
/* global variables used by T_GET_SLOT, see in T.h */
volatile uint64_t T_next_id;
volatile uint64_t T_active_id;
#endif
static void get_message(int s)
{
static void get_message(int s) {
char t;
int l;
int id;
int is_on;
if (read(s, &t, 1) != 1) QUIT("get_message fails");
printf("T tracer: got mess %d\n", t);
printf("T tracer: got mess %d\n", t);
switch (t) {
case 0:
/* toggle all those IDs */
/* optimze? (too much syscalls) */
if (read(s, &l, sizeof(int)) != sizeof(int)) QUIT("get_message fails");
while (l) {
if (read(s, &id, sizeof(int)) != sizeof(int)) QUIT("get_message fails");
T_IDs[id] = 1 - T_IDs[id];
l--;
}
break;
case 1:
/* set IDs as given */
/* optimize? */
if (read(s, &l, sizeof(int)) != sizeof(int)) QUIT("get_message fails");
id = 0;
while (l) {
if (read(s, &is_on, sizeof(int)) != sizeof(int))
QUIT("get_message fails");
T_IDs[id] = is_on;
id++;
l--;
}
break;
case 2: break; /* do nothing, this message is to wait for local tracer */
case 0:
/* toggle all those IDs */
/* optimze? (too much syscalls) */
if (read(s, &l, sizeof(int)) != sizeof(int)) QUIT("get_message fails");
while (l) {
if (read(s, &id, sizeof(int)) != sizeof(int)) QUIT("get_message fails");
T_IDs[id] = 1 - T_IDs[id];
l--;
}
break;
case 1:
/* set IDs as given */
/* optimize? */
if (read(s, &l, sizeof(int)) != sizeof(int)) QUIT("get_message fails");
id = 0;
while (l) {
if (read(s, &is_on, sizeof(int)) != sizeof(int))
QUIT("get_message fails");
T_IDs[id] = is_on;
id++;
l--;
}
break;
case 2:
break; /* do nothing, this message is to wait for local tracer */
}
}
static void *T_receive_thread(void *_)
{
static void *T_receive_thread(void *_) {
while (1) get_message(T_socket);
return NULL;
}
static void new_thread(void *(*f)(void *), void *data)
{
static void new_thread(void *(*f)(void *), void *data) {
pthread_t t;
pthread_attr_t att;
if (pthread_attr_init(&att))
{ fprintf(stderr, "pthread_attr_init err\n"); exit(1); }
if (pthread_attr_setdetachstate(&att, PTHREAD_CREATE_DETACHED))
{ fprintf(stderr, "pthread_attr_setdetachstate err\n"); exit(1); }
if (pthread_create(&t, &att, f, data))
{ fprintf(stderr, "pthread_create err\n"); exit(1); }
if (pthread_attr_destroy(&att))
{ fprintf(stderr, "pthread_attr_destroy err\n"); exit(1); }
if (pthread_attr_init(&att)) {
fprintf(stderr, "pthread_attr_init err\n");
exit(1);
}
if (pthread_attr_setdetachstate(&att, PTHREAD_CREATE_DETACHED)) {
fprintf(stderr, "pthread_attr_setdetachstate err\n");
exit(1);
}
if (pthread_create(&t, &att, f, data)) {
fprintf(stderr, "pthread_create err\n");
exit(1);
}
if (pthread_attr_destroy(&att)) {
fprintf(stderr, "pthread_attr_destroy err\n");
exit(1);
}
}
/* defined in local_tracer.c */
void T_local_tracer_main(int remote_port, int wait_for_tracer,
int local_socket, void *shm_array);
int local_socket, void *shm_array);
/* We monitor the tracee and the local tracer processes.
* When one dies we forcefully kill the other.
*/
#include <sys/types.h>
#include <sys/wait.h>
static void monitor_and_kill(int child1, int child2)
{
static void monitor_and_kill(int child1, int child2) {
int child;
int status;
child = wait(&status);
if (child == -1) perror("wait");
kill(child1, SIGKILL);
kill(child2, SIGKILL);
exit(0);
}
void T_init(int remote_port, int wait_for_tracer, int dont_fork)
{
void T_init(int remote_port, int wait_for_tracer, int dont_fork) {
int socket_pair[2];
int s;
int child1, child2;
int i;
if (socketpair(AF_UNIX, SOCK_STREAM, 0, socket_pair))
{ perror("socketpair"); abort(); }
if (socketpair(AF_UNIX, SOCK_STREAM, 0, socket_pair)) {
perror("socketpair");
abort();
}
/* setup shared memory */
T_cache = mmap(NULL, T_CACHE_SIZE * sizeof(T_cache_t),
PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, -1, 0);
if (T_cache == MAP_FAILED)
{ perror("mmap"); abort(); }
if (T_cache == MAP_FAILED) {
perror("mmap");
abort();
}
/* let's garbage the memory to catch some potential problems
* (think multiprocessor sync issues, barriers, etc.)
*/
memset(T_cache, 0x55, T_CACHE_SIZE * sizeof(T_cache_t));
for (i = 0; i < T_CACHE_SIZE; i++) T_cache[i].busy = 0;
/* child1 runs the local tracer and child2 (or main) runs the tracee */
child1 = fork();
if (child1 == -1) abort();
child1 = fork(); if (child1 == -1) abort();
if (child1 == 0) {
close(socket_pair[1]);
T_local_tracer_main(remote_port, wait_for_tracer, socket_pair[0],
T_cache);
exit(0);
}
close(socket_pair[0]);
if (dont_fork == 0) {
child2 = fork(); if (child2 == -1) abort();
child2 = fork();
if (child2 == -1) abort();
if (child2 != 0) {
close(socket_pair[1]);
munmap(T_cache, T_CACHE_SIZE * sizeof(T_cache_t));
@@ -161,27 +197,21 @@ void T_init(int remote_port, int wait_for_tracer, int dont_fork)
s = socket_pair[1];
/* wait for first message - initial list of active T events */
get_message(s);
T_socket = s;
new_thread(T_receive_thread, NULL);
}
void T_Config_Init(void)
{
int T_port; /* by default we wait for the tracer */
int T_nowait; /* default port to listen to to wait for the tracer */
int T_dont_fork; /* default is to fork, see 'T_init' to understand */
void T_Config_Init(void) {
int T_port=TTRACER_DEFAULT_PORTNUM; /* by default we wait for the tracer */
int T_nowait=0; /* default port to listen to to wait for the tracer */
int T_dont_fork=0; /* default is to fork, see 'T_init' to understand */
paramdef_t ttraceparams[] = CMDLINE_TTRACEPARAMS_DESC;
/* for a cleaner config file, TTracer params should be defined in a
* specific section...
*/
config_get(ttraceparams,
sizeof(ttraceparams) / sizeof(paramdef_t),
TTRACER_CONFIG_PREFIX);
/* compatibility: look for TTracer command line options in root section */
config_process_cmdline(ttraceparams,
sizeof(ttraceparams) / sizeof(paramdef_t),
+41 -40
View File
@@ -8,7 +8,7 @@
#include "T_defs.h"
#ifdef T_SEND_TIME
#include <time.h>
#include <time.h>
#endif
/* T message IDs */
@@ -76,13 +76,13 @@
T_BUFFER_MAX - T_LOCAL_size, T_PUT_printf_deref x); \
if (T_PUT_len < 0) { \
printf("%s:%d:%s: you can't read this, or can you?", \
__FILE__, __LINE__, __FUNCTION__); \
__FILE__, __LINE__, __FUNCTION__); \
abort(); \
} \
if (T_PUT_len >= T_BUFFER_MAX - T_LOCAL_size) { \
printf("%s:%d:%s: cannot put argument %d in T macro, not enough space" \
", consider increasing T_BUFFER_MAX (%d)\n", \
__FILE__, __LINE__, __FUNCTION__, argnum, T_BUFFER_MAX); \
", consider increasing T_BUFFER_MAX (%d)\n", \
__FILE__, __LINE__, __FUNCTION__, argnum, T_BUFFER_MAX); \
abort(); \
} \
T_LOCAL_size += T_PUT_len + 1; \
@@ -97,9 +97,9 @@ struct T_header;
/* T macro tricks */
extern int T_stdout;
#define TN(...) TN_N(__VA_ARGS__,33,32,31,30,29,28,27,26,25,24,23,22,21,\
20,19,18,17,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0)(__VA_ARGS__)
20,19,18,17,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0)(__VA_ARGS__)
#define TN_N(n0,n1,n2,n3,n4,n5,n6,n7,n8,n9,n10,n11,n12,n13,n14,n15,n16,n17,\
n18,n19,n20,n21,n22,n23,n24,n25,n26,n27,n28,n29,n30,n31,n32,n,...) T##n
n18,n19,n20,n21,n22,n23,n24,n25,n26,n27,n28,n29,n30,n31,n32,n,...) T##n
#define T(...) do { if (T_stdout == 0) TN(__VA_ARGS__); } while (0)
/* type used to send arbitrary buffer data */
@@ -119,30 +119,30 @@ extern int *T_active;
*/
#if BASIC_SIMULATOR
# define T_GET_SLOT \
do { \
extern volatile uint64_t T_next_id; \
extern volatile uint64_t T_active_id; \
uint64_t id; \
/* get a ticket */ \
id = __sync_fetch_and_add(&T_next_id, 1); \
/* wait for our turn */ \
while (id != __sync_fetch_and_add(&T_active_id, 0)) /* busy wait */; \
/* this is our turn, try to acquire the slot until it's free */ \
do { \
T_LOCAL_busy = __sync_fetch_and_or(&T_cache[T_LOCAL_slot].busy, 0x01); \
if (T_LOCAL_busy & 0x01) usleep(100); \
} while (T_LOCAL_busy & 0x01); \
/* check that there are still some tickets */ \
if (__sync_fetch_and_add(&T_active_id, 0) == 0xffffffffffffffff) { \
printf("T: reached the end of times, bye...\n"); \
abort(); \
} \
/* free our ticket, which signals the next waiter that it's its turn */ \
(void)__sync_fetch_and_add(&T_active_id, 1); \
} while (0)
do { \
extern volatile uint64_t T_next_id; \
extern volatile uint64_t T_active_id; \
uint64_t id; \
/* get a ticket */ \
id = __sync_fetch_and_add(&T_next_id, 1); \
/* wait for our turn */ \
while (id != __sync_fetch_and_add(&T_active_id, 0)) /* busy wait */; \
/* this is our turn, try to acquire the slot until it's free */ \
do { \
T_LOCAL_busy = __sync_fetch_and_or(&T_cache[T_LOCAL_slot].busy, 0x01); \
if (T_LOCAL_busy & 0x01) usleep(100); \
} while (T_LOCAL_busy & 0x01); \
/* check that there are still some tickets */ \
if (__sync_fetch_and_add(&T_active_id, 0) == 0xffffffffffffffff) { \
printf("T: reached the end of times, bye...\n"); \
abort(); \
} \
/* free our ticket, which signals the next waiter that it's its turn */ \
(void)__sync_fetch_and_add(&T_active_id, 1); \
} while (0)
#else
# define T_GET_SLOT \
T_LOCAL_busy = __sync_fetch_and_or(&T_cache[T_LOCAL_slot].busy, 0x01);
T_LOCAL_busy = __sync_fetch_and_or(&T_cache[T_LOCAL_slot].busy, 0x01);
#endif
/* used at header of Tn, allocates buffer */
@@ -172,8 +172,8 @@ extern int *T_active;
#define T_CHECK_SIZE(len, argnum) \
if (T_LOCAL_size + (len) > T_BUFFER_MAX) { \
printf("%s:%d:%s: cannot put argument %d in T macro, not enough space" \
", consider increasing T_BUFFER_MAX (%d)\n", \
__FILE__, __LINE__, __FUNCTION__, argnum, T_BUFFER_MAX); \
", consider increasing T_BUFFER_MAX (%d)\n", \
__FILE__, __LINE__, __FUNCTION__, argnum, T_BUFFER_MAX); \
abort(); \
}
@@ -598,20 +598,21 @@ extern int *T_active;
#define TTRACER_CONFIG_PREFIX "TTracer"
/*------------------------------------------------------------------------------------------------------------------------------------------*/
/* configuration parameters for TTRACE utility */
/* optname helpstr paramflags XXXptr defXXXval type numelt */
/*------------------------------------------------------------------------------------------------------------------------------------------*/
/*-------------------------------------------------------------------------------------------------------------------------------------------------*/
/* configuration parameters for TTRACE utility */
/* optname helpstr paramflags XXXptr defXXXval type numelt */
/*-------------------------------------------------------------------------------------------------------------------------------------------------*/
#define TTRACER_DEFAULT_PORTNUM 2021
#define CMDLINE_TTRACEPARAMS_DESC { \
{"T_port", CONFIG_HLP_TPORT, 0, iptr:&T_port, defintval:2021, TYPE_INT, 0}, \
{"T_nowait", CONFIG_HLP_NOTWAIT, PARAMFLAG_BOOL, iptr:&T_nowait, defintval:0, TYPE_INT, 0}, \
{"T_dont_fork", CONFIG_HLP_TNOFORK, PARAMFLAG_BOOL, iptr:&T_dont_fork, defintval:0, TYPE_INT, 0}, \
{"T_stdout", CONFIG_HLP_STDOUT, PARAMFLAG_BOOL, iptr:&T_stdout, defintval:1, TYPE_INT, 0}, \
}
{"T_port", CONFIG_HLP_TPORT, 0, iptr:&T_port, defintval:TTRACER_DEFAULT_PORTNUM, TYPE_INT, 0},\
{"T_nowait", CONFIG_HLP_NOTWAIT, PARAMFLAG_BOOL, iptr:&T_nowait, defintval:0, TYPE_INT, 0},\
{"T_dont_fork", CONFIG_HLP_TNOFORK, PARAMFLAG_BOOL, iptr:&T_dont_fork, defintval:0, TYPE_INT, 0},\
{"T_stdout", CONFIG_HLP_STDOUT, PARAMFLAG_BOOL, iptr:&T_stdout, defintval:1, TYPE_INT, 0},\
}
/* log on stdout */
/* log on stdout */
void T_init(int remote_port, int wait_for_tracer, int dont_fork);
void T_Config_Init(void);
#else /* T_TRACER */
+300 -119
View File
@@ -49,7 +49,7 @@
//-------------------------------
FILE* g_msc_fd;
FILE *g_msc_fd;
char g_msc_proto2str[MAX_MSC_PROTOS][MSC_MAX_PROTO_NAME_LENGTH];
@@ -70,15 +70,11 @@ void *msc_task(void *args_p)
//------------------------------------------------------------------------------
{
MessageDef *received_message_p = NULL;
// const char *msg_name = NULL;
// instance_t instance = 0;
// const char *msg_name = NULL;
// instance_t instance = 0;
long timer_id;
itti_mark_task_ready(TASK_MSC);
msc_start_use();
timer_setup(0, // seconds
50000, // usec
TASK_MSC,
@@ -91,20 +87,18 @@ void *msc_task(void *args_p)
itti_receive_msg(TASK_MSC, &received_message_p);
if (received_message_p != NULL) {
// msg_name = ITTI_MSG_NAME (received_message_p);
// instance = ITTI_MSG_INSTANCE (received_message_p);
// msg_name = ITTI_MSG_NAME (received_message_p);
// instance = ITTI_MSG_INSTANCE (received_message_p);
switch (ITTI_MSG_ID(received_message_p)) {
case TIMER_HAS_EXPIRED: {
msc_flush_messages();
msc_flush_messages();
}
break;
case TERMINATE_MESSAGE: {
fprintf(stderr, " *** Exiting MSC thread\n");
timer_remove(timer_id);
msc_end();
msc_end();
itti_exit_task();
}
break;
@@ -119,6 +113,7 @@ void *msc_task(void *args_p)
}
}
}
fprintf(stderr, "Task MSC exiting\n");
return NULL;
}
@@ -132,15 +127,16 @@ int msc_init(const msc_env_t envP, const int max_threadsP)
void *pointer_p;
char msc_filename[256];
fprintf(stderr, "Initializing MSC logs\n");
rv = snprintf(msc_filename, 256, "/tmp/openair.msc.%i.log", envP); // TODO NAME
rv = snprintf(msc_filename, 256, "/tmp/openair.msc.%u.log", envP); // TODO NAME
if ((0 >= rv) || (256 < rv)){
if ((0 >= rv) || (256 < rv)) {
fprintf(stderr, "Error in MSC log file name");
}
g_msc_fd = fopen(msc_filename,"w");
AssertFatal(g_msc_fd != NULL, "Could not open MSC log file %s : %s", msc_filename, strerror(errno));
rv = lfds611_stack_new(&g_msc_memory_stack_p, (lfds611_atom_t)max_threadsP + 2);
if (0 >= rv) {
AssertFatal (0, "lfds611_stack_new failed!\n");
}
@@ -153,7 +149,7 @@ int msc_init(const msc_env_t envP, const int max_threadsP)
for (i=0; i < max_threadsP * 30; i++) {
pointer_p = malloc(MSC_MAX_MESSAGE_LENGTH);
AssertFatal (pointer_p, "malloc failed!\n");
rv = lfds611_stack_guaranteed_push( g_msc_memory_stack_p, pointer_p );
rv = lfds611_stack_guaranteed_push( g_msc_memory_stack_p, pointer_p );
AssertFatal (rv, "lfds611_stack_guaranteed_push failed for item %u\n", i);
}
@@ -161,182 +157,335 @@ int msc_init(const msc_env_t envP, const int max_threadsP)
switch (i) {
case MSC_IP_UE:
rv = snprintf(&g_msc_proto2str[i][0], MSC_MAX_PROTO_NAME_LENGTH, "IP_UE");
if (rv >= MSC_MAX_PROTO_NAME_LENGTH) {g_msc_proto2str[i][MSC_MAX_PROTO_NAME_LENGTH-1] = 0;}
if (rv >= MSC_MAX_PROTO_NAME_LENGTH) {
g_msc_proto2str[i][MSC_MAX_PROTO_NAME_LENGTH-1] = 0;
}
if ((envP == MSC_E_UTRAN) || (envP == MSC_E_UTRAN_LIPA)) {
msc_log_declare_proto(i);
}
break;
case MSC_IP_ENB:
rv = snprintf(&g_msc_proto2str[i][0], MSC_MAX_PROTO_NAME_LENGTH, "IP_ENB");
if (rv >= MSC_MAX_PROTO_NAME_LENGTH) {g_msc_proto2str[i][MSC_MAX_PROTO_NAME_LENGTH-1] = 0;}
if (rv >= MSC_MAX_PROTO_NAME_LENGTH) {
g_msc_proto2str[i][MSC_MAX_PROTO_NAME_LENGTH-1] = 0;
}
if (envP == MSC_E_UTRAN_LIPA) {
msc_log_declare_proto(i);
}
break;
case MSC_NAS_UE:
rv = snprintf(&g_msc_proto2str[i][0], MSC_MAX_PROTO_NAME_LENGTH, "NAS_UE");
if (rv >= MSC_MAX_PROTO_NAME_LENGTH) {g_msc_proto2str[i][MSC_MAX_PROTO_NAME_LENGTH-1] = 0;}
if (rv >= MSC_MAX_PROTO_NAME_LENGTH) {
g_msc_proto2str[i][MSC_MAX_PROTO_NAME_LENGTH-1] = 0;
}
if ((envP == MSC_E_UTRAN) || (envP == MSC_E_UTRAN_LIPA)) {
msc_log_declare_proto(i);
}
break;
case MSC_RRC_UE:
rv = snprintf(&g_msc_proto2str[i][0], MSC_MAX_PROTO_NAME_LENGTH, "RRC_UE");
if (rv >= MSC_MAX_PROTO_NAME_LENGTH) {g_msc_proto2str[i][MSC_MAX_PROTO_NAME_LENGTH-1] = 0;}
if (rv >= MSC_MAX_PROTO_NAME_LENGTH) {
g_msc_proto2str[i][MSC_MAX_PROTO_NAME_LENGTH-1] = 0;
}
if ((envP == MSC_E_UTRAN) || (envP == MSC_E_UTRAN_LIPA)) {
msc_log_declare_proto(i);
}
break;
case MSC_PDCP_UE:
rv = snprintf(&g_msc_proto2str[i][0], MSC_MAX_PROTO_NAME_LENGTH, "PDCP_UE");
if (rv >= MSC_MAX_PROTO_NAME_LENGTH) {g_msc_proto2str[i][MSC_MAX_PROTO_NAME_LENGTH-1] = 0;}
if (rv >= MSC_MAX_PROTO_NAME_LENGTH) {
g_msc_proto2str[i][MSC_MAX_PROTO_NAME_LENGTH-1] = 0;
}
if ((envP == MSC_E_UTRAN) || (envP == MSC_E_UTRAN_LIPA)) {
msc_log_declare_proto(i);
}
break;
case MSC_RLC_UE:
rv = snprintf(&g_msc_proto2str[i][0], MSC_MAX_PROTO_NAME_LENGTH, "RLC_UE");
if (rv >= MSC_MAX_PROTO_NAME_LENGTH) {g_msc_proto2str[i][MSC_MAX_PROTO_NAME_LENGTH-1] = 0;}
if ((envP == MSC_E_UTRAN) || (envP == MSC_E_UTRAN_LIPA)) {
rv = snprintf(&g_msc_proto2str[i][0], MSC_MAX_PROTO_NAME_LENGTH, "RLC_UE");
if (rv >= MSC_MAX_PROTO_NAME_LENGTH) {
g_msc_proto2str[i][MSC_MAX_PROTO_NAME_LENGTH-1] = 0;
}
if ((envP == MSC_E_UTRAN) || (envP == MSC_E_UTRAN_LIPA)) {
msc_log_declare_proto(i);
}
break;
case MSC_MAC_UE:
rv = snprintf(&g_msc_proto2str[i][0], MSC_MAX_PROTO_NAME_LENGTH, "MAC_UE");
if (rv >= MSC_MAX_PROTO_NAME_LENGTH) {g_msc_proto2str[i][MSC_MAX_PROTO_NAME_LENGTH-1] = 0;}
if ((envP == MSC_E_UTRAN) || (envP == MSC_E_UTRAN_LIPA)) {
msc_log_declare_proto(i);
if (rv >= MSC_MAX_PROTO_NAME_LENGTH) {
g_msc_proto2str[i][MSC_MAX_PROTO_NAME_LENGTH-1] = 0;
}
if ((envP == MSC_E_UTRAN) || (envP == MSC_E_UTRAN_LIPA)) {
msc_log_declare_proto(i);
}
break;
case MSC_PHY_UE:
rv = snprintf(&g_msc_proto2str[i][0], MSC_MAX_PROTO_NAME_LENGTH, "PHY_UE");
if (rv >= MSC_MAX_PROTO_NAME_LENGTH) {g_msc_proto2str[i][MSC_MAX_PROTO_NAME_LENGTH-1] = 0;}
if (rv >= MSC_MAX_PROTO_NAME_LENGTH) {
g_msc_proto2str[i][MSC_MAX_PROTO_NAME_LENGTH-1] = 0;
}
if ((envP == MSC_E_UTRAN) || (envP == MSC_E_UTRAN_LIPA)) {
msc_log_declare_proto(i);
}
break;
case MSC_PHY_ENB:
rv = snprintf(&g_msc_proto2str[i][0], MSC_MAX_PROTO_NAME_LENGTH, "PHY_ENB");
if (rv >= MSC_MAX_PROTO_NAME_LENGTH) {g_msc_proto2str[i][MSC_MAX_PROTO_NAME_LENGTH-1] = 0;}
if (rv >= MSC_MAX_PROTO_NAME_LENGTH) {
g_msc_proto2str[i][MSC_MAX_PROTO_NAME_LENGTH-1] = 0;
}
if ((envP == MSC_E_UTRAN) || (envP == MSC_E_UTRAN_LIPA)) {
msc_log_declare_proto(i);
}
break;
case MSC_MAC_ENB:
rv = snprintf(&g_msc_proto2str[i][0], MSC_MAX_PROTO_NAME_LENGTH, "MAC_ENB");
if (rv >= MSC_MAX_PROTO_NAME_LENGTH) {g_msc_proto2str[i][MSC_MAX_PROTO_NAME_LENGTH-1] = 0;}
if (rv >= MSC_MAX_PROTO_NAME_LENGTH) {
g_msc_proto2str[i][MSC_MAX_PROTO_NAME_LENGTH-1] = 0;
}
if ((envP == MSC_E_UTRAN) || (envP == MSC_E_UTRAN_LIPA)) {
msc_log_declare_proto(i);
}
break;
case MSC_RLC_ENB:
rv = snprintf(&g_msc_proto2str[i][0], MSC_MAX_PROTO_NAME_LENGTH, "RLC_ENB");
if (rv >= MSC_MAX_PROTO_NAME_LENGTH) {g_msc_proto2str[i][MSC_MAX_PROTO_NAME_LENGTH-1] = 0;}
if (rv >= MSC_MAX_PROTO_NAME_LENGTH) {
g_msc_proto2str[i][MSC_MAX_PROTO_NAME_LENGTH-1] = 0;
}
if ((envP == MSC_E_UTRAN) || (envP == MSC_E_UTRAN_LIPA)) {
msc_log_declare_proto(i);
}
break;
case MSC_PDCP_ENB:
rv = snprintf(&g_msc_proto2str[i][0], MSC_MAX_PROTO_NAME_LENGTH, "PDCP_ENB");
if (rv >= MSC_MAX_PROTO_NAME_LENGTH) {g_msc_proto2str[i][MSC_MAX_PROTO_NAME_LENGTH-1] = 0;}
if (rv >= MSC_MAX_PROTO_NAME_LENGTH) {
g_msc_proto2str[i][MSC_MAX_PROTO_NAME_LENGTH-1] = 0;
}
if ((envP == MSC_E_UTRAN) || (envP == MSC_E_UTRAN_LIPA)) {
msc_log_declare_proto(i);
}
break;
case MSC_RRC_ENB:
rv = snprintf(&g_msc_proto2str[i][0], MSC_MAX_PROTO_NAME_LENGTH, "RRC_ENB");
if (rv >= MSC_MAX_PROTO_NAME_LENGTH) {g_msc_proto2str[i][MSC_MAX_PROTO_NAME_LENGTH-1] = 0;}
if (rv >= MSC_MAX_PROTO_NAME_LENGTH) {
g_msc_proto2str[i][MSC_MAX_PROTO_NAME_LENGTH-1] = 0;
}
if ((envP == MSC_E_UTRAN) || (envP == MSC_E_UTRAN_LIPA)) {
msc_log_declare_proto(i);
}
break;
case MSC_S1AP_ENB:
rv = snprintf(&g_msc_proto2str[i][0], MSC_MAX_PROTO_NAME_LENGTH, "S1AP_ENB");
if (rv >= MSC_MAX_PROTO_NAME_LENGTH) {g_msc_proto2str[i][MSC_MAX_PROTO_NAME_LENGTH-1] = 0;}
if (rv >= MSC_MAX_PROTO_NAME_LENGTH) {
g_msc_proto2str[i][MSC_MAX_PROTO_NAME_LENGTH-1] = 0;
}
if ((envP == MSC_E_UTRAN) || (envP == MSC_MME_GW) || (envP == MSC_MME)) {
msc_log_declare_proto(i);
}
break;
case MSC_GTPU_ENB:
rv = snprintf(&g_msc_proto2str[i][0], MSC_MAX_PROTO_NAME_LENGTH, "GTPU_ENB");
if (rv >= MSC_MAX_PROTO_NAME_LENGTH) {g_msc_proto2str[i][MSC_MAX_PROTO_NAME_LENGTH-1] = 0;}
if (rv >= MSC_MAX_PROTO_NAME_LENGTH) {
g_msc_proto2str[i][MSC_MAX_PROTO_NAME_LENGTH-1] = 0;
}
if ((envP == MSC_E_UTRAN) || (envP == MSC_E_UTRAN_LIPA)) {
msc_log_declare_proto(i);
}
break;
case MSC_GTPU_SGW:
rv = snprintf(&g_msc_proto2str[i][0], MSC_MAX_PROTO_NAME_LENGTH, "GTPU_SGW");
if (rv >= MSC_MAX_PROTO_NAME_LENGTH) {g_msc_proto2str[i][MSC_MAX_PROTO_NAME_LENGTH-1] = 0;}
if (rv >= MSC_MAX_PROTO_NAME_LENGTH) {
g_msc_proto2str[i][MSC_MAX_PROTO_NAME_LENGTH-1] = 0;
}
if ((envP == MSC_MME_GW) || (envP == MSC_E_UTRAN) || (envP == MSC_E_UTRAN_LIPA)) {
msc_log_declare_proto(i);
}
break;
case MSC_S1AP_MME:
rv = snprintf(&g_msc_proto2str[i][0], MSC_MAX_PROTO_NAME_LENGTH, "S1AP_MME");
if (rv >= MSC_MAX_PROTO_NAME_LENGTH) {g_msc_proto2str[i][MSC_MAX_PROTO_NAME_LENGTH-1] = 0;}
if (rv >= MSC_MAX_PROTO_NAME_LENGTH) {
g_msc_proto2str[i][MSC_MAX_PROTO_NAME_LENGTH-1] = 0;
}
if ((envP == MSC_MME_GW) || (envP == MSC_MME) || (envP == MSC_E_UTRAN) || (envP == MSC_E_UTRAN_LIPA)) {
msc_log_declare_proto(i);
}
break;
case MSC_MMEAPP_MME:
rv = snprintf(&g_msc_proto2str[i][0], MSC_MAX_PROTO_NAME_LENGTH, "MME_APP");
if (rv >= MSC_MAX_PROTO_NAME_LENGTH) {g_msc_proto2str[i][MSC_MAX_PROTO_NAME_LENGTH-1] = 0;}
if (rv >= MSC_MAX_PROTO_NAME_LENGTH) {
g_msc_proto2str[i][MSC_MAX_PROTO_NAME_LENGTH-1] = 0;
}
if ((envP == MSC_MME_GW) || (envP == MSC_MME)) {
msc_log_declare_proto(i);
}
break;
case MSC_NAS_MME:
rv = snprintf(&g_msc_proto2str[i][0], MSC_MAX_PROTO_NAME_LENGTH, "NAS_MME");
if (rv >= MSC_MAX_PROTO_NAME_LENGTH) {g_msc_proto2str[i][MSC_MAX_PROTO_NAME_LENGTH-1] = 0;}
if (rv >= MSC_MAX_PROTO_NAME_LENGTH) {
g_msc_proto2str[i][MSC_MAX_PROTO_NAME_LENGTH-1] = 0;
}
msc_log_declare_proto(i);
break;
case MSC_NAS_EMM_MME:
rv = snprintf(&g_msc_proto2str[i][0], MSC_MAX_PROTO_NAME_LENGTH, "NAS_EMM");
if (rv >= MSC_MAX_PROTO_NAME_LENGTH) {g_msc_proto2str[i][MSC_MAX_PROTO_NAME_LENGTH-1] = 0;}
if (rv >= MSC_MAX_PROTO_NAME_LENGTH) {
g_msc_proto2str[i][MSC_MAX_PROTO_NAME_LENGTH-1] = 0;
}
if ((envP == MSC_MME_GW) || (envP == MSC_MME)) {
msc_log_declare_proto(i);
}
break;
case MSC_NAS_ESM_MME:
rv = snprintf(&g_msc_proto2str[i][0], MSC_MAX_PROTO_NAME_LENGTH, "NAS_ESM");
if (rv >= MSC_MAX_PROTO_NAME_LENGTH) {g_msc_proto2str[i][MSC_MAX_PROTO_NAME_LENGTH-1] = 0;}
if (rv >= MSC_MAX_PROTO_NAME_LENGTH) {
g_msc_proto2str[i][MSC_MAX_PROTO_NAME_LENGTH-1] = 0;
}
if ((envP == MSC_MME_GW) || (envP == MSC_MME)) {
msc_log_declare_proto(i);
}
break;
case MSC_SP_GWAPP_MME:
rv = snprintf(&g_msc_proto2str[i][0], MSC_MAX_PROTO_NAME_LENGTH, "SP_GW_MME");
if (rv >= MSC_MAX_PROTO_NAME_LENGTH) {g_msc_proto2str[i][MSC_MAX_PROTO_NAME_LENGTH-1] = 0;}
if (rv >= MSC_MAX_PROTO_NAME_LENGTH) {
g_msc_proto2str[i][MSC_MAX_PROTO_NAME_LENGTH-1] = 0;
}
if (envP == MSC_MME_GW) {
msc_log_declare_proto(i);
}
break;
case MSC_S11_MME:
rv = snprintf(&g_msc_proto2str[i][0], MSC_MAX_PROTO_NAME_LENGTH, "S11_MME");
if (rv >= MSC_MAX_PROTO_NAME_LENGTH) {g_msc_proto2str[i][MSC_MAX_PROTO_NAME_LENGTH-1] = 0;}
if (rv >= MSC_MAX_PROTO_NAME_LENGTH) {
g_msc_proto2str[i][MSC_MAX_PROTO_NAME_LENGTH-1] = 0;
}
if (envP == MSC_MME) {
msc_log_declare_proto(i);
}
break;
case MSC_S6A_MME:
rv = snprintf(&g_msc_proto2str[i][0], MSC_MAX_PROTO_NAME_LENGTH, "S6A");
if (rv >= MSC_MAX_PROTO_NAME_LENGTH) {g_msc_proto2str[i][MSC_MAX_PROTO_NAME_LENGTH-1] = 0;}
if (rv >= MSC_MAX_PROTO_NAME_LENGTH) {
g_msc_proto2str[i][MSC_MAX_PROTO_NAME_LENGTH-1] = 0;
}
if ((envP == MSC_MME_GW) || (envP == MSC_MME)) {
msc_log_declare_proto(i);
}
break;
case MSC_HSS:
rv = snprintf(&g_msc_proto2str[i][0], MSC_MAX_PROTO_NAME_LENGTH, "HSS");
if (rv >= MSC_MAX_PROTO_NAME_LENGTH) {g_msc_proto2str[i][MSC_MAX_PROTO_NAME_LENGTH-1] = 0;}
if (rv >= MSC_MAX_PROTO_NAME_LENGTH) {
g_msc_proto2str[i][MSC_MAX_PROTO_NAME_LENGTH-1] = 0;
}
if ((envP == MSC_MME_GW) || (envP == MSC_MME)) {
msc_log_declare_proto(i);
}
break;
default:
rv = snprintf(&g_msc_proto2str[i][0], MSC_MAX_PROTO_NAME_LENGTH, "UNKNOWN");
if (rv >= MSC_MAX_PROTO_NAME_LENGTH) {g_msc_proto2str[i][MSC_MAX_PROTO_NAME_LENGTH-1] = 0;}
if (rv >= MSC_MAX_PROTO_NAME_LENGTH) {
g_msc_proto2str[i][MSC_MAX_PROTO_NAME_LENGTH-1] = 0;
}
}
}
rv = itti_create_task (TASK_MSC, msc_task, NULL);
AssertFatal (rv == 0, "Create task for MSC failed!\n");
fprintf(stderr, "Initializing MSC logs Done\n");
@@ -359,15 +508,17 @@ void msc_flush_messages(void)
int rv;
msc_queue_item_t *item_p = NULL;
while ((rv = lfds611_queue_dequeue( g_msc_message_queue_p, (void**)&item_p )) == 1) {
if (NULL != item_p->message_str) {
fputs(item_p->message_str, g_msc_fd);
// TODO BIN DATA
rv = lfds611_stack_guaranteed_push( g_msc_memory_stack_p, item_p->message_str );
}
// TODO FREE BIN DATA
free(item_p);
while ((rv = lfds611_queue_dequeue( g_msc_message_queue_p, (void **)&item_p )) == 1) {
if (NULL != item_p->message_str) {
fputs(item_p->message_str, g_msc_fd);
// TODO BIN DATA
rv = lfds611_stack_guaranteed_push( g_msc_memory_stack_p, item_p->message_str );
}
// TODO FREE BIN DATA
free(item_p);
}
fflush(g_msc_fd);
}
@@ -377,23 +528,27 @@ void msc_end(void)
//------------------------------------------------------------------------------
{
int rv;
if (NULL != g_msc_fd ) {
msc_flush_messages();
msc_flush_messages();
rv = fflush(g_msc_fd);
if (rv != 0) {
fprintf(stderr, "Error while flushing stream of MSC log file: %s", strerror(errno));
}
rv = fclose(g_msc_fd);
if (rv != 0) {
fprintf(stderr, "Error while closing MSC log file: %s", strerror(errno));
fprintf(stderr, "Error while flushing stream of MSC log file: %s", strerror(errno));
}
rv = fclose(g_msc_fd);
if (rv != 0) {
fprintf(stderr, "Error while closing MSC log file: %s", strerror(errno));
}
}
}
//------------------------------------------------------------------------------
void msc_log_declare_proto(
const msc_proto_t protoP
)
const msc_proto_t protoP
)
//------------------------------------------------------------------------------
{
int rv = 0;
@@ -401,47 +556,55 @@ void msc_log_declare_proto(
char *char_message_p = NULL;
if ((MIN_MSC_PROTOS <= protoP) && (MAX_MSC_PROTOS > protoP)) {
// may be build a memory pool for that also ?
new_item_p = malloc(sizeof(msc_queue_item_t));
if (NULL != new_item_p) {
// may be build a memory pool for that also ?
new_item_p = malloc(sizeof(msc_queue_item_t));
rv = lfds611_stack_pop(g_msc_memory_stack_p, (void**)&char_message_p);
if (0 == rv) {
msc_flush_messages();
rv = lfds611_stack_pop(g_msc_memory_stack_p, (void**)&char_message_p);
}
if (1 == rv) {
if (NULL != new_item_p) {
rv = lfds611_stack_pop(g_msc_memory_stack_p, (void **)&char_message_p);
if (0 == rv) {
msc_flush_messages();
rv = lfds611_stack_pop(g_msc_memory_stack_p, (void **)&char_message_p);
}
if (1 == rv) {
rv = snprintf(char_message_p, MSC_MAX_MESSAGE_LENGTH, "%"PRIu64" [PROTO] %d %s\n", __sync_fetch_and_add (&g_message_number, 1), protoP, &g_msc_proto2str[protoP][0]);
if (0 > rv) {
fprintf(stderr, "Error while declaring new protocol in MSC: %s", strerror(errno));
}
new_item_p->message_str = char_message_p;
new_item_p->message_str_size = rv;
new_item_p->message_bin = NULL;
new_item_p->message_bin_size = 0;
rv = lfds611_queue_enqueue( g_msc_message_queue_p, new_item_p );
if (0 == rv) {
rv = lfds611_queue_guaranteed_enqueue(g_msc_message_queue_p, new_item_p );
if (0 == rv) {
if (0 == rv) {
rv = lfds611_queue_guaranteed_enqueue(g_msc_message_queue_p, new_item_p );
if (0 == rv) {
fprintf(stderr, "Error while lfds611_queue_guaranteed_enqueue message %s in MSC", char_message_p);
rv = lfds611_stack_guaranteed_push( g_msc_memory_stack_p, char_message_p );
free(new_item_p);
}
}
return;
} else {
fprintf(stderr, "Error while lfds611_stack_pop()\n");
}
rv = lfds611_stack_guaranteed_push( g_msc_memory_stack_p, char_message_p );
free(new_item_p);
}
}
return;
} else {
fprintf(stderr, "Error while lfds611_stack_pop()\n");
}
free(new_item_p);
} else {
} else {
fprintf(stderr, "Error while malloc in MSC");
}
}
}
}
//------------------------------------------------------------------------------
void msc_log_event(
const msc_proto_t protoP,
char *format, ...)
const msc_proto_t protoP,
char *format, ...)
//------------------------------------------------------------------------------
{
va_list args;
@@ -450,52 +613,62 @@ void msc_log_event(
msc_queue_item_t *new_item_p = NULL;
char *char_message_p = NULL;
if ((MIN_MSC_PROTOS > protoP) || (MAX_MSC_PROTOS <= protoP)) {
return;
return;
}
new_item_p = malloc(sizeof(msc_queue_item_t));
if (NULL != new_item_p) {
rv = lfds611_stack_pop(g_msc_memory_stack_p, (void**)&char_message_p);
new_item_p = malloc(sizeof(msc_queue_item_t));
if (NULL != new_item_p) {
rv = lfds611_stack_pop(g_msc_memory_stack_p, (void **)&char_message_p);
if (0 == rv) {
msc_flush_messages();
rv = lfds611_stack_pop(g_msc_memory_stack_p, (void**)&char_message_p);
rv = lfds611_stack_pop(g_msc_memory_stack_p, (void **)&char_message_p);
}
if (1 == rv) {
rv = snprintf(char_message_p, MSC_MAX_MESSAGE_LENGTH, "%"PRIu64" [EVENT] %d ", __sync_fetch_and_add (&g_message_number, 1), protoP);
if ((0 > rv) || (MSC_MAX_MESSAGE_LENGTH < rv)) {
fprintf(stderr, "Error while logging MSC event : %s", &g_msc_proto2str[protoP][0]);
goto error_event;
}
va_start(args, format);
rv2 = vsnprintf(&char_message_p[rv],MSC_MAX_MESSAGE_LENGTH - rv, format, args);
va_end(args);
if ((0 > rv2) || ((MSC_MAX_MESSAGE_LENGTH - rv) < rv2)) {
fprintf(stderr, "Error while logging MSC event : %s", &g_msc_proto2str[protoP][0]);
goto error_event;
}
rv += rv2;
rv2 = snprintf(&char_message_p[rv],MSC_MAX_MESSAGE_LENGTH - rv, "\n");
if ((0 > rv2) || ((MSC_MAX_MESSAGE_LENGTH - rv) < rv2)) {
fprintf(stderr, "Error while logging MSC event : %s", &g_msc_proto2str[protoP][0]);
goto error_event;
}
rv += rv2;
new_item_p->message_str = char_message_p;
new_item_p->message_str_size = rv;
new_item_p->message_bin = NULL;
new_item_p->message_bin_size = 0;
rv = lfds611_queue_enqueue( g_msc_message_queue_p, new_item_p );
if (0 == rv) {
if (0 == rv) {
fprintf(stderr, "Error while lfds611_queue_guaranteed_enqueue message %s in MSC", char_message_p);
rv = lfds611_stack_guaranteed_push( g_msc_memory_stack_p, char_message_p );
free(new_item_p);
}
rv = lfds611_stack_guaranteed_push( g_msc_memory_stack_p, char_message_p );
free(new_item_p);
}
} else {
fprintf(stderr, "Error while lfds611_stack_pop()\n");
}
}
}
return;
error_event:
rv = lfds611_stack_guaranteed_push( g_msc_memory_stack_p, char_message_p );
@@ -503,12 +676,12 @@ error_event:
}
//------------------------------------------------------------------------------
void msc_log_message(
const char * const message_operationP,
const msc_proto_t proto1P,
const msc_proto_t proto2P,
const uint8_t * const bytesP,
const unsigned int num_bytes,
char *format, ...)
const char *const message_operationP,
const msc_proto_t proto1P,
const msc_proto_t proto2P,
const uint8_t *const bytesP,
const unsigned int num_bytes,
char *format, ...)
//------------------------------------------------------------------------------
{
va_list args;
@@ -518,56 +691,65 @@ void msc_log_message(
msc_queue_item_t *new_item_p = NULL;
char *char_message_p = NULL;
if ((MIN_MSC_PROTOS > proto1P) || (MAX_MSC_PROTOS <= proto1P) ||
(MIN_MSC_PROTOS > proto2P) || (MAX_MSC_PROTOS <= proto2P) ) {
(MIN_MSC_PROTOS > proto2P) || (MAX_MSC_PROTOS <= proto2P) ) {
return;
}
new_item_p = malloc(sizeof(msc_queue_item_t));
if (NULL != new_item_p) {
rv = lfds611_stack_pop(g_msc_memory_stack_p, (void**)&char_message_p);
if (NULL != new_item_p) {
rv = lfds611_stack_pop(g_msc_memory_stack_p, (void **)&char_message_p);
if (0 == rv) {
msc_flush_messages();
rv = lfds611_stack_pop(g_msc_memory_stack_p, (void**)&char_message_p);
}
rv = lfds611_stack_pop(g_msc_memory_stack_p, (void **)&char_message_p);
}
if (1 == rv) {
rv = snprintf(char_message_p, MSC_MAX_MESSAGE_LENGTH, "%"PRIu64" [MESSAGE] %d %s %d %"PRIu64" ",
__sync_fetch_and_add (&g_message_number, 1), proto1P, message_operationP, proto2P, mac);
__sync_fetch_and_add (&g_message_number, 1), proto1P, message_operationP, proto2P, mac);
if ((0 > rv) || (MSC_MAX_MESSAGE_LENGTH < rv)) {
fprintf(stderr, "Error while logging MSC message : %s/%s", &g_msc_proto2str[proto1P][0], &g_msc_proto2str[proto2P][0]);
goto error_event;
}
va_start(args, format);
rv2 = vsnprintf(&char_message_p[rv],MSC_MAX_MESSAGE_LENGTH - rv, format, args);
va_end(args);
if ((0 > rv2) || ((MSC_MAX_MESSAGE_LENGTH - rv) < rv2)) {
fprintf(stderr, "Error while logging MSC message : %s/%s", &g_msc_proto2str[proto1P][0], &g_msc_proto2str[proto2P][0]);
goto error_event;
}
rv += rv2;
rv2 = snprintf(&char_message_p[rv],MSC_MAX_MESSAGE_LENGTH - rv, "\n");
if ((0 > rv2) || ((MSC_MAX_MESSAGE_LENGTH - rv) < rv2)) {
fprintf(stderr, "Error while logging MSC message : %s/%s", &g_msc_proto2str[proto1P][0], &g_msc_proto2str[proto2P][0]);
goto error_event;
}
rv += rv2;
new_item_p->message_str = char_message_p;
new_item_p->message_str_size = rv;
new_item_p->message_bin = NULL; // TO DO
new_item_p->message_bin_size = 0; // TO DO
rv = lfds611_queue_enqueue( g_msc_message_queue_p, new_item_p );
if (0 == rv) {
if (0 == rv) {
fprintf(stderr, "Error while lfds611_queue_guaranteed_enqueue message %s in MSC", char_message_p);
rv = lfds611_stack_guaranteed_push( g_msc_memory_stack_p, char_message_p );
free(new_item_p);
}
rv = lfds611_stack_guaranteed_push( g_msc_memory_stack_p, char_message_p );
free(new_item_p);
}
} else {
fprintf(stderr, "Error while lfds611_stack_pop()\n");
msc_flush_messages();
}
}
}
return;
error_event:
rv = lfds611_stack_guaranteed_push( g_msc_memory_stack_p, char_message_p );
@@ -578,8 +760,7 @@ error_event:
// function called when oai loader loads the msc shared lib
int msc_autoinit(msc_interface_t *msc_interface)
//------------------------------------------------------------------------------
{
{
msc_interface->msc_init = msc_init;
msc_interface->msc_start_use = msc_start_use;
msc_interface->msc_end = msc_end;
@@ -587,4 +768,4 @@ int msc_autoinit(msc_interface_t *msc_interface)
msc_interface->msc_log_message = msc_log_message;
msc_interface->msc_loaded = 1;
return 0;
}
}
+55 -53
View File
@@ -25,46 +25,46 @@
#include <stdint.h>
typedef enum {
MIN_MSC_ENV = 0,
MSC_E_UTRAN = MIN_MSC_ENV,
MSC_E_UTRAN_LIPA,
MSC_MME_GW,
MSC_MME,
MSC_SP_GW,
MAX_MSC_ENV
MIN_MSC_ENV = 0,
MSC_E_UTRAN = MIN_MSC_ENV,
MSC_E_UTRAN_LIPA,
MSC_MME_GW,
MSC_MME,
MSC_SP_GW,
MAX_MSC_ENV
} msc_env_t;
typedef enum {
MIN_MSC_PROTOS = 0,
MSC_IP_UE = MIN_MSC_PROTOS,
MSC_NAS_UE,
MSC_RRC_UE,
MSC_PDCP_UE,
MSC_RLC_UE,
MSC_MAC_UE,
MSC_PHY_UE,
MSC_PHY_ENB,
MSC_MAC_ENB,
MSC_RLC_ENB,
MSC_PDCP_ENB,
MSC_RRC_ENB,
MSC_IP_ENB,
MSC_S1AP_ENB,
MSC_GTPU_ENB,
MSC_GTPU_SGW,
MSC_S1AP_MME,
MSC_MMEAPP_MME,
MSC_NAS_MME,
MSC_NAS_EMM_MME,
MSC_NAS_ESM_MME,
MSC_SP_GWAPP_MME,
MSC_S11_MME,
MSC_S6A_MME,
MSC_HSS,
MSC_X2AP_SRC_ENB,
MSC_X2AP_TARGET_ENB,
MAX_MSC_PROTOS,
MIN_MSC_PROTOS = 0,
MSC_IP_UE = MIN_MSC_PROTOS,
MSC_NAS_UE,
MSC_RRC_UE,
MSC_PDCP_UE,
MSC_RLC_UE,
MSC_MAC_UE,
MSC_PHY_UE,
MSC_PHY_ENB,
MSC_MAC_ENB,
MSC_RLC_ENB,
MSC_PDCP_ENB,
MSC_RRC_ENB,
MSC_IP_ENB,
MSC_S1AP_ENB,
MSC_GTPU_ENB,
MSC_GTPU_SGW,
MSC_S1AP_MME,
MSC_MMEAPP_MME,
MSC_NAS_MME,
MSC_NAS_EMM_MME,
MSC_NAS_ESM_MME,
MSC_SP_GWAPP_MME,
MSC_S11_MME,
MSC_S6A_MME,
MSC_HSS,
MSC_X2AP_SRC_ENB,
MSC_X2AP_TARGET_ENB,
MAX_MSC_PROTOS,
} msc_proto_t;
@@ -73,22 +73,22 @@ typedef enum {
#define MSC_AS_TIME_FMT "%05u:%02u"
#define MSC_AS_TIME_ARGS(CTXT_Pp) \
(CTXT_Pp)->frame, \
(CTXT_Pp)->subframe
(CTXT_Pp)->frame, \
(CTXT_Pp)->subframe
typedef int(*msc_init_t)(const msc_env_t, const int );
typedef void(*msc_start_use_t)(void );
typedef void(*msc_end_t)(void);
typedef void(*msc_log_event_t)(const msc_proto_t,char *, ...);
typedef void(*msc_log_message_t)(const char * const, const msc_proto_t, const msc_proto_t,
const uint8_t* const, const unsigned int, char * , ...);
typedef void(*msc_log_message_t)(const char *const, const msc_proto_t, const msc_proto_t,
const uint8_t *const, const unsigned int, char *, ...);
typedef struct msc_interface {
int msc_loaded;
msc_init_t msc_init;
msc_start_use_t msc_start_use;
msc_end_t msc_end;
msc_log_event_t msc_log_event;
msc_log_message_t msc_log_message;
int msc_loaded;
msc_init_t msc_init;
msc_start_use_t msc_start_use;
msc_end_t msc_end;
msc_log_event_t msc_log_event;
msc_log_message_t msc_log_message;
} msc_interface_t;
#ifdef MSC_LIBRARY
@@ -99,15 +99,17 @@ void msc_end(void);
void msc_log_declare_proto(const msc_proto_t protoP);
void msc_log_event(const msc_proto_t protoP,char *format, ...);
void msc_log_message(
const char * const message_operationP,
const msc_proto_t receiverP,
const msc_proto_t senderP,
const uint8_t* const bytesP,
const unsigned int num_bytes,
char *format, ...);
const char *const message_operationP,
const msc_proto_t receiverP,
const msc_proto_t senderP,
const uint8_t *const bytesP,
const unsigned int num_bytes,
char *format, ...);
#else
#define MESSAGE_CHART_GENERATOR msc_interface.msc_loaded
msc_interface_t msc_interface;
#define MSC_INIT(arg1,arg2) if(msc_interface.msc_loaded) msc_interface.msc_init(arg1,arg2)
#define MSC_START_USE if(msc_interface.msc_loaded) msc_interface.msc_start_use
@@ -119,4 +121,4 @@ msc_interface_t msc_interface;
#define MSC_LOG_TX_MESSAGE_FAILED(sENDER, rECEIVER, bYTES, nUMbYTES, fORMAT, aRGS...) if(msc_interface.msc_loaded) msc_interface.msc_log_message("-x",sENDER, rECEIVER, (const uint8_t *)bYTES, nUMbYTES, fORMAT, ##aRGS)
#endif
#endif
#endif
File diff suppressed because it is too large Load Diff
+21 -1
View File
@@ -8,7 +8,8 @@
5. [eNB RRC Layer](#enb-rrc-layer)
6. [eNB X2AP](#enb-x2ap)
7. [eNB Advanced Features](#enb-advanced-features)
2. [OpenAirInterface UE Feature Set](#openairinterface-ue-feature-set)
2. [OpenAirInterface Functional Split](#openairinterface-functional-split)
3. [OpenAirInterface UE Feature Set](#openairinterface-ue-feature-set)
1. [LTE UE PHY Layer](#lte-ue-phy-layer)
2. [LTE UE MAC Layer](#lte-ue-mac-layer)
3. [LTE UE RLC Layer](#lte-ue-rlc-layer)
@@ -131,6 +132,18 @@ The X2AP layer is based on **3GPP 36.423** v14.6.0 and implements the following
**To be completed**
# OpenAirInterface Functional Split #
- RCC: Radio-Cloud Center
- RAU: Radio-Access Unit
- RRU: Remote Radio-Unit
![Functional Split Architecture](./oai_lte_enb_func_split_arch.png)
- IF4.5 / IF5 : similar to IEEE P1914.1
- FAPI (IF2) : specified by Small Cell Forum (open-nFAPI implementation)
- IF1 : F1 in 3GPP Release 15 (not implemented yet)
# OpenAirInterface UE Feature Set #
## LTE UE PHY Layer ##
@@ -172,3 +185,10 @@ The RRC layer is based on **3GPP 36.331** v14.3.0 and implements the following f
- System Information decoding
- RRC connection establishment
## LTE UE NAS Layer ##
The NAS layer is based on **3GPP 24.301** and implements the following functions:
- EMM attach/detach, authentication, tracking area update, and more
- ESM default/dedicated bearer, PDN connectivity, and more
Binary file not shown.

After

Width:  |  Height:  |  Size: 60 KiB

+8 -6
View File
@@ -270,6 +270,7 @@ int pnf_param_resp_cb(nfapi_vnf_config_t* config, int p5_idx, nfapi_pnf_param_re
for(int i = 0; i < resp->pnf_phy.number_of_phys; ++i)
{
phy_info phy;
memset(&phy,0,sizeof(phy));
phy.index = resp->pnf_phy.phy[i].phy_config_index;
printf("[VNF] (PHY:%d) phy_config_idx:%d\n", i, resp->pnf_phy.phy[i].phy_config_index);
@@ -287,6 +288,7 @@ int pnf_param_resp_cb(nfapi_vnf_config_t* config, int p5_idx, nfapi_pnf_param_re
for(int i = 0; i < resp->pnf_rf.number_of_rfs; ++i) {
rf_info rf;
memset(&rf,0,sizeof(rf));
rf.index = resp->pnf_rf.rf[i].rf_config_index;
printf("[VNF] (RF:%d) rf_config_idx:%d\n", i, resp->pnf_rf.rf[i].rf_config_index);
@@ -897,7 +899,7 @@ int param_resp_cb(nfapi_vnf_config_t* config, int p5_idx, nfapi_param_response_t
// for now just 1
printf("[VNF] %d.%d pnf p7 %s:%d timing %d %d %d %d\n", p5_idx, phy->id, phy->remote_addr, phy->remote_port, p7_vnf->timing_window, p7_vnf->periodic_timing_period, p7_vnf->aperiodic_timing_enabled, p7_vnf->periodic_timing_period);
printf("[VNF] %d.%d pnf p7 %s:%d timing %u %u %u %u\n", p5_idx, phy->id, phy->remote_addr, phy->remote_port, p7_vnf->timing_window, p7_vnf->periodic_timing_period, p7_vnf->aperiodic_timing_enabled, p7_vnf->periodic_timing_period);
req->header.message_id = NFAPI_CONFIG_REQUEST;
req->header.phy_id = phy->id;
@@ -919,7 +921,7 @@ int param_resp_cb(nfapi_vnf_config_t* config, int p5_idx, nfapi_param_response_t
req->nfapi_config.timing_window.tl.tag = NFAPI_NFAPI_TIMING_WINDOW_TAG;
req->nfapi_config.timing_window.value = p7_vnf->timing_window;
printf("[VNF] Timing window:%d\n", p7_vnf->timing_window);
printf("[VNF] Timing window:%u\n", p7_vnf->timing_window);
req->num_tlv++;
if(p7_vnf->periodic_timing_enabled || p7_vnf->aperiodic_timing_enabled) {
@@ -1110,7 +1112,7 @@ int oai_nfapi_dl_config_req(nfapi_dl_config_request_t *dl_config_req)
nfapi_vnf_p7_config_t *p7_config = vnf.p7_vnfs[0].config;
dl_config_req->header.phy_id = 1; // DJP HACK TODO FIXME - need to pass this around!!!!
dl_config_req->header.message_id = NFAPI_DL_CONFIG_REQUEST;
int retval = nfapi_vnf_p7_dl_config_req(p7_config, dl_config_req);
dl_config_req->dl_config_request_body.number_pdcch_ofdm_symbols = 1;
@@ -1129,7 +1131,7 @@ int oai_nfapi_tx_req(nfapi_tx_request_t *tx_req)
nfapi_vnf_p7_config_t *p7_config = vnf.p7_vnfs[0].config;
tx_req->header.phy_id = 1; // DJP HACK TODO FIXME - need to pass this around!!!!
tx_req->header.message_id = NFAPI_TX_REQUEST;
//LOG_D(PHY, "[VNF] %s() TX_REQ sfn_sf:%d number_of_pdus:%d\n", __FUNCTION__, NFAPI_SFNSF2DEC(tx_req->sfn_sf), tx_req->tx_request_body.number_of_pdus);
int retval = nfapi_vnf_p7_tx_req(p7_config, tx_req);
@@ -1147,7 +1149,7 @@ int oai_nfapi_hi_dci0_req(nfapi_hi_dci0_request_t *hi_dci0_req) {
nfapi_vnf_p7_config_t *p7_config = vnf.p7_vnfs[0].config;
hi_dci0_req->header.phy_id = 1; // DJP HACK TODO FIXME - need to pass this around!!!!
hi_dci0_req->header.message_id = NFAPI_HI_DCI0_REQUEST;
//LOG_D(PHY, "[VNF] %s() HI_DCI0_REQ sfn_sf:%d dci:%d hi:%d\n", __FUNCTION__, NFAPI_SFNSF2DEC(hi_dci0_req->sfn_sf), hi_dci0_req->hi_dci0_request_body.number_of_dci, hi_dci0_req->hi_dci0_request_body.number_of_hi);
int retval = nfapi_vnf_p7_hi_dci0_req(p7_config, hi_dci0_req);
@@ -1166,7 +1168,7 @@ int oai_nfapi_ul_config_req(nfapi_ul_config_request_t *ul_config_req) {
nfapi_vnf_p7_config_t *p7_config = vnf.p7_vnfs[0].config;
ul_config_req->header.phy_id = 1; // DJP HACK TODO FIXME - need to pass this around!!!!
ul_config_req->header.message_id = NFAPI_UL_CONFIG_REQUEST;
//LOG_D(PHY, "[VNF] %s() header message_id:%02x\n", __FUNCTION__, ul_config_req->header.message_id);
//LOG_D(PHY, "[VNF] %s() UL_CONFIG sfn_sf:%d PDUs:%d rach_prach_frequency_resources:%d srs_present:%d\n", __FUNCTION__, NFAPI_SFNSF2DEC(ul_config_req->sfn_sf), ul_config_req->ul_config_request_body.number_of_pdus, ul_config_req->ul_config_request_body.rach_prach_frequency_resources, ul_config_req->ul_config_request_body.srs_present);
+2 -1
View File
@@ -1237,11 +1237,11 @@ int pnf_connect(pnf_t* pnf)
}
struct addrinfo *p = servinfo;
int i = 0;
int connected = 0;
while(p != NULL && connected == 0)
{
#ifdef NFAPI_TRACE_ENABLED
char* family = "Unknown";
char* address = "Unknown";
char _addr[128];
@@ -1261,6 +1261,7 @@ int pnf_connect(pnf_t* pnf)
}
NFAPI_TRACE(NFAPI_TRACE_NOTE, "Host address info %d Family:%s Address:%s\n", i++, family, address);
#endif
if (pnf->sctp)
{
+1 -1
View File
@@ -379,7 +379,7 @@ static uint32_t get_sf_time(uint32_t now_hr, uint32_t sf_start_hr)
{
if(now_hr < sf_start_hr)
{
NFAPI_TRACE(NFAPI_TRACE_INFO, "now is earlier than start of subframe now_hr:%u sf_start_hr:%u\n", now_hr, sf_start_hr);
//NFAPI_TRACE(NFAPI_TRACE_INFO, "now is earlier than start of subframe now_hr:%u sf_start_hr:%u\n", now_hr, sf_start_hr);
return 0;
}
else
+2 -2
View File
@@ -1203,12 +1203,12 @@ void vnf_handle_ul_node_sync(void *pRecvMsg, int recvMsgLen, vnf_p7_t* vnf_p7)
if(phy->in_sync == 0)
{
NFAPI_TRACE(NFAPI_TRACE_NOTE, "***** Adjusting VNF phy_id:%d SFN/SF (%s) from %d to %d (%d) mode:%s zeroCount:%u sync:%s\n",
/*NFAPI_TRACE(NFAPI_TRACE_NOTE, "***** Adjusting VNF phy_id:%d SFN/SF (%s) from %d to %d (%d) mode:%s zeroCount:%u sync:%s\n",
ind.header.phy_id, (phy->in_sync ? "via sfn" : "now"),
NFAPI_SFNSF2DEC(curr_sfn_sf), NFAPI_SFNSF2DEC(new_sfn_sf), phy->adjustment,
phy->filtered_adjust ? "FILTERED" : "ABSOLUTE",
phy->zero_count,
phy->in_sync ? "IN_SYNC" : "OUT_OF_SYNC");
phy->in_sync ? "IN_SYNC" : "OUT_OF_SYNC");*/
phy->sfn_sf = new_sfn_sf;
}
+118 -180
View File
@@ -26,9 +26,9 @@
date: 09.2012
*/
#ifndef TC_MAIN
#include "coding_defs.h"
#include "coding_defs.h"
#else
#include <stdint.h>
#include <stdint.h>
#endif
#include <stdio.h>
#include <string.h>
@@ -66,11 +66,11 @@ struct treillis {
union {
uint8x8_t systematic_andp1_64[3];
char systematic_andp1_8[24];
}__attribute__((aligned(64)));
} __attribute__((aligned(64)));
union {
uint8x8_t parity2_64[3];
char parity2_8[24];
}__attribute__((aligned(64)));
} __attribute__((aligned(64)));
int exit_state;
};
#endif
@@ -79,23 +79,20 @@ struct treillis all_treillis[8][256];
int all_treillis_initialized=0;
static inline unsigned char threegpplte_rsc(unsigned char input,unsigned char *state)
{
static inline unsigned char threegpplte_rsc(unsigned char input,unsigned char *state) {
unsigned char output;
output = (input ^ (*state>>2) ^ (*state>>1))&1;
*state = (((input<<2)^(*state>>1))^((*state>>1)<<2)^((*state)<<2))&7;
return(output);
}
static inline void threegpplte_rsc_termination(unsigned char *x,unsigned char *z,unsigned char *state)
{
static inline void threegpplte_rsc_termination(unsigned char *x,unsigned char *z,unsigned char *state) {
*z = ((*state>>2) ^ (*state)) &1;
*x = ((*state) ^ (*state>>1)) &1;
*state = (*state)>>1;
}
static void treillis_table_init(void)
{
static void treillis_table_init(void) {
//struct treillis t[][]=all_treillis;
//t=memalign(16,sizeof(struct treillis)*8*256);
int i, j,b;
@@ -114,8 +111,8 @@ static void treillis_table_init(void)
all_treillis[i][j].systematic_andp1_8[b*3]= (j&(1<<(7-b)))>>(7-b);
v=threegpplte_rsc( all_treillis[i][j].systematic_andp1_8[b*3] ,
&current_state);
all_treillis[i][j].systematic_andp1_8[b*3+1]=v; // for the yparity1
// all_treillis[i][j].parity1_8[b*3+1]=v; // for the yparity1
all_treillis[i][j].systematic_andp1_8[b*3+1]=v; // for the yparity1
// all_treillis[i][j].parity1_8[b*3+1]=v; // for the yparity1
all_treillis[i][j].parity2_8[b*3+2]=v; // for the yparity2
}
@@ -128,14 +125,12 @@ static void treillis_table_init(void)
}
char interleave_compact_byte(short * base_interleaver,unsigned char * input, unsigned char * output, int n)
{
char interleave_compact_byte(short *base_interleaver,unsigned char *input, unsigned char *output, int n) {
char expandInput[768*8] __attribute__((aligned(32)));
int i,loop=n>>4;
#if defined(__x86_64__) || defined(__i386__)
#ifndef __AVX2__
__m128i *i_128=(__m128i *)input, *o_128=(__m128i*)expandInput;
__m128i *i_128=(__m128i *)input, *o_128=(__m128i *)expandInput;
__m128i tmp1, tmp2, tmp3, tmp4;
__m128i BIT_MASK = _mm_set_epi8( 0b00000001,
0b00000010,
@@ -153,42 +148,41 @@ char interleave_compact_byte(short * base_interleaver,unsigned char * input, uns
0b00100000,
0b01000000,
0b10000000);
#else
__m256i *i_256=(__m256i *)input, *o_256=(__m256i*)expandInput;
__m256i *i_256=(__m256i *)input, *o_256=(__m256i *)expandInput;
__m256i tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7;
__m256i BIT_MASK = _mm256_set_epi8( 0b00000001,
0b00000010,
0b00000100,
0b00001000,
0b00010000,
0b00100000,
0b01000000,
0b10000000,
0b00000001,
0b00000010,
0b00000100,
0b00001000,
0b00010000,
0b00100000,
0b01000000,
0b10000000,
0b00000001,
0b00000010,
0b00000100,
0b00001000,
0b00010000,
0b00100000,
0b01000000,
0b10000000,
0b00000001,
0b00000010,
0b00000100,
0b00001000,
0b00010000,
0b00100000,
0b01000000,
0b10000000);
0b00000010,
0b00000100,
0b00001000,
0b00010000,
0b00100000,
0b01000000,
0b10000000,
0b00000001,
0b00000010,
0b00000100,
0b00001000,
0b00010000,
0b00100000,
0b01000000,
0b10000000,
0b00000001,
0b00000010,
0b00000100,
0b00001000,
0b00010000,
0b00100000,
0b01000000,
0b10000000,
0b00000001,
0b00000010,
0b00000100,
0b00001000,
0b00010000,
0b00100000,
0b01000000,
0b10000000);
#endif
#elif defined(__arm__)
uint8x16_t *i_128=(uint8x16_t *)input, *o_128=(uint8x16_t *)expandInput;
@@ -196,40 +190,41 @@ char interleave_compact_byte(short * base_interleaver,unsigned char * input, uns
uint16x8_t tmp3;
uint32x4_t tmp4;
uint8x16_t and_tmp;
uint8x16_t BIT_MASK = { 0b10000000,
0b01000000,
0b00100000,
0b00010000,
0b00001000,
0b00000100,
0b00000010,
0b00000001,
0b10000000,
0b01000000,
0b00100000,
0b00010000,
0b00001000,
0b00000100,
0b00000010,
0b00000001};
uint8x16_t BIT_MASK = { 0b10000000,
0b01000000,
0b00100000,
0b00010000,
0b00001000,
0b00000100,
0b00000010,
0b00000001,
0b10000000,
0b01000000,
0b00100000,
0b00010000,
0b00001000,
0b00000100,
0b00000010,
0b00000001
};
#endif
#ifndef __AVX2__
if ((n&15) > 0)
loop++;
#else
loop=n>>5;
if ((n&31) > 0)
loop++;
#endif
for (i=0; i<loop ; i++ ) {
// int cur_byte=i<<3;
// for (b=0;b<8;b++)
// expandInput[cur_byte+b] = (input[i]&(1<<(7-b)))>>(7-b);
// int cur_byte=i<<3;
// for (b=0;b<8;b++)
// expandInput[cur_byte+b] = (input[i]&(1<<(7-b)))>>(7-b);
#if defined(__x86_64__) || defined(__i386__)
#ifndef __AVX2__
tmp1=_mm_load_si128(i_128++); // tmp1 = B0,B1,...,B15
@@ -237,29 +232,22 @@ char interleave_compact_byte(short * base_interleaver,unsigned char * input, uns
tmp3=_mm_unpacklo_epi16(tmp2,tmp2); // tmp3 = B0,B0,B0,B0,B1,B1,B1,B1,B2,B2,B2,B2,B3,B3,B3,B3
tmp4=_mm_unpacklo_epi32(tmp3,tmp3); // tmp4 - B0,B0,B0,B0,B0,B0,B0,B0,B1,B1,B1,B1,B1,B1,B1,B1
*o_128++=_mm_cmpeq_epi8(_mm_and_si128(tmp4,BIT_MASK),BIT_MASK);
tmp4=_mm_unpackhi_epi32(tmp3,tmp3); // tmp4 - B2,B2,B2,B2,B2,B2,B2,B2,B3,B3,B3,B3,B3,B3,B3,B3
*o_128++=_mm_cmpeq_epi8(_mm_and_si128(tmp4,BIT_MASK),BIT_MASK);;
tmp3=_mm_unpackhi_epi16(tmp2,tmp2); // tmp3 = B4,B4,B4,B4,B5,B5,B5,B5,B6,B6,B6,B6,B7,B7,B7,B7
tmp4=_mm_unpacklo_epi32(tmp3,tmp3); // tmp4 - B4,B4,B4,B4,B4,B4,B4,B4,B5,B5,B5,B5,B5,B5,B5,B5
*o_128++=_mm_cmpeq_epi8(_mm_and_si128(tmp4,BIT_MASK),BIT_MASK);;
tmp4=_mm_unpackhi_epi32(tmp3,tmp3); // tmp4 - B6,B6,B6,B6,B6,B6,B6,B6,B7,B7,B7,B7,B7,B7,B7,B7
*o_128++=_mm_cmpeq_epi8(_mm_and_si128(tmp4,BIT_MASK),BIT_MASK);;
tmp2=_mm_unpackhi_epi8(tmp1,tmp1); // tmp2 = B8,B8,B9,B9,...,B15,B15
tmp3=_mm_unpacklo_epi16(tmp2,tmp2); // tmp3 = B8,B8,B8,B8,B9,B9,B9,B9,B10,B10,B10,B10,B11,B11,B11,B11
tmp4=_mm_unpacklo_epi32(tmp3,tmp3); // tmp4 = B8,B8,B8,B8,B8,B8,B8,B8,B9,B9,B9,B9,B9,B9,B9,B9
*o_128++=_mm_cmpeq_epi8(_mm_and_si128(tmp4,BIT_MASK),BIT_MASK);;
tmp4=_mm_unpackhi_epi32(tmp3,tmp3); // tmp4 = B10,B10,B10,B10,B10,B10,B10,B10,B11,B11,B11,B11,B11,B11,B11,B11
*o_128++=_mm_cmpeq_epi8(_mm_and_si128(tmp4,BIT_MASK),BIT_MASK);;
tmp3=_mm_unpackhi_epi16(tmp2,tmp2); // tmp3 = B12,B12,B12,B12,B13,B13,B13,B13,B14,B14,B14,B14,B15,B15,B15,B15
tmp4=_mm_unpacklo_epi32(tmp3,tmp3); // tmp4 = B12,B12,B12,B12,B12,B12,B12,B12,B13,B13,B13,B13,B13,B13,B13,B13
*o_128++=_mm_cmpeq_epi8(_mm_and_si128(tmp4,BIT_MASK),BIT_MASK);;
tmp4=_mm_unpackhi_epi32(tmp3,tmp3); // tmp4 = B14,B14,B14,B14,B14,B14,B14,B14,B15,B15,B15,B15,B15,B15,B15,B15
*o_128++=_mm_cmpeq_epi8(_mm_and_si128(tmp4,BIT_MASK),BIT_MASK);;
#else
@@ -281,7 +269,6 @@ char interleave_compact_byte(short * base_interleaver,unsigned char * input, uns
//print_bytes2("out",(uint8_t*)o_256);
o_256[4]=_mm256_cmpeq_epi8(_mm256_and_si256(tmp7,BIT_MASK),BIT_MASK);;
//print_bytes2("out",(uint8_t*)(o_256+4));
tmp3=_mm256_unpackhi_epi16(tmp2,tmp2); // tmp3 = B4,B4,B4,B4,B5,B5,B5,B5,B6,B6,B6,B6,B7,B7,B7,B7,B20,B20,B20,B20,...,B23,B23,B23,B23
tmp4=_mm256_unpacklo_epi32(tmp3,tmp3); // tmp4 - B4,B4,B4,B4,B4,B4,B4,B4,B5,B5,B5,B5,B5,B5,B5,B5,B20,B20...,B21..,B21
tmp5=_mm256_unpackhi_epi32(tmp3,tmp3); // tmp5 - B6,B6,B6,B6,B6,B6,B6,B6,B7,B7,B7,B7,B7,B7,B7,B7,B22...,B22,B23,...,B23
@@ -297,7 +284,6 @@ char interleave_compact_byte(short * base_interleaver,unsigned char * input, uns
//print_bytes2("out",(uint8_t*)(o_256+1));
o_256[5]=_mm256_cmpeq_epi8(_mm256_and_si256(tmp7,BIT_MASK),BIT_MASK);;
//print_bytes2("out",(uint8_t*)(o_256+4));
tmp2=_mm256_unpackhi_epi8(tmp1,tmp1); // tmp2 = B8 B9 B10 B11 B12 B13 B14 B15 B25 B26 B27 B28 B29 B30 B31
tmp3=_mm256_unpacklo_epi16(tmp2,tmp2); // tmp3 = B8,B9,B10,B11,B26,B27,B28,B29
tmp4=_mm256_unpacklo_epi32(tmp3,tmp3); // tmp4 - B8,B9,B26,B27
@@ -314,11 +300,10 @@ char interleave_compact_byte(short * base_interleaver,unsigned char * input, uns
//print_bytes2("out",(uint8_t*)(o_256+2));
o_256[6]=_mm256_cmpeq_epi8(_mm256_and_si256(tmp7,BIT_MASK),BIT_MASK);;
//print_bytes2("out",(uint8_t*)(o_256+4));
tmp3=_mm256_unpackhi_epi16(tmp2,tmp2); // tmp3 = B12 B13 B14 B15 B28 B29 B30 B31
tmp4=_mm256_unpacklo_epi32(tmp3,tmp3); // tmp4 = B12 B13 B28 B29
tmp5=_mm256_unpackhi_epi32(tmp3,tmp3); // tmp5 = B14 B15 B30 B31
tmp6=_mm256_insertf128_si256(tmp4,_mm256_extracti128_si256(tmp5,0),1); // tmp6 = B12 B13 B14 B15
tmp5=_mm256_unpackhi_epi32(tmp3,tmp3); // tmp5 = B14 B15 B30 B31
tmp6=_mm256_insertf128_si256(tmp4,_mm256_extracti128_si256(tmp5,0),1); // tmp6 = B12 B13 B14 B15
tmp7=_mm256_insertf128_si256(tmp5,_mm256_extracti128_si256(tmp4,1),0); // tmp7 = B28 B29 B30 B31
//print_bytes2("tmp2",(uint8_t*)&tmp2);
//print_bytes2("tmp3",(uint8_t*)&tmp3);
@@ -330,48 +315,35 @@ char interleave_compact_byte(short * base_interleaver,unsigned char * input, uns
//print_bytes2("out",(uint8_t*)(o_256+3));
o_256[7]=_mm256_cmpeq_epi8(_mm256_and_si256(tmp7,BIT_MASK),BIT_MASK);;
//print_bytes2("out",(uint8_t*)(o_256+7));
o_256+=8;
#endif
#elif defined(__arm__)
tmp1=vld1q_u8((uint8_t*)i_128);
tmp1=vld1q_u8((uint8_t *)i_128);
//print_bytes("tmp1:",(uint8_t*)&tmp1);
uint8x16x2_t temp1 = vzipq_u8(tmp1,tmp1);
tmp2 = temp1.val[0];
uint16x8x2_t temp2 = vzipq_u16((uint16x8_t)tmp2,(uint16x8_t)tmp2);
tmp3 = temp2.val[0];
uint32x4x2_t temp3 = vzipq_u32((uint32x4_t)tmp3,(uint32x4_t)tmp3);
tmp4 = temp3.val[0];
//print_bytes("tmp4:",(uint8_t*)&tmp4);
*o_128++=vceqq_u8(vandq_u8((uint8x16_t)tmp4,BIT_MASK),BIT_MASK); //1
//print_bytes("o:",(uint8_t*)(o_128-1));
tmp4 = temp3.val[1];
//print_bytes("tmp4:",(uint8_t*)&tmp4);
*o_128++=vceqq_u8(vandq_u8((uint8x16_t)tmp4,BIT_MASK),BIT_MASK); //2
//print_bytes("o:",(uint8_t*)(o_128-1));
tmp3 = temp2.val[1];
temp3 = vzipq_u32((uint32x4_t)tmp3,(uint32x4_t)tmp3);
tmp4 = temp3.val[0];
//print_bytes("tmp4:",(uint8_t*)&tmp4);
*o_128++=vceqq_u8(vandq_u8((uint8x16_t)tmp4,BIT_MASK),BIT_MASK); //3
//print_bytes("o:",(uint8_t*)(o_128-1));
tmp4 = temp3.val[1];
//print_bytes("tmp4:",(uint8_t*)&tmp4);
*o_128++=vceqq_u8(vandq_u8((uint8x16_t)tmp4,BIT_MASK),BIT_MASK); //4
//and_tmp = vandq_u8((uint8x16_t)tmp4,BIT_MASK); print_bytes("and:",and_tmp);
//and_tmp = vandq_u8((uint8x16_t)tmp4,BIT_MASK); print_bytes("and:",and_tmp);
//print_bytes("o:",(uint8_t*)(o_128-1));
temp1 = vzipq_u8(tmp1,tmp1);
tmp2 = temp1.val[1];
temp2 = vzipq_u16((uint16x8_t)tmp2,(uint16x8_t)tmp2);
@@ -379,52 +351,41 @@ char interleave_compact_byte(short * base_interleaver,unsigned char * input, uns
temp3 = vzipq_u32((uint32x4_t)tmp3,(uint32x4_t)tmp3);
tmp4 = temp3.val[0];
//print_bytes("tmp4:",(uint8_t*)&tmp4);
*o_128++=vceqq_u8(vandq_u8((uint8x16_t)tmp4,BIT_MASK),BIT_MASK); //5
//print_bytes("o:",(uint8_t*)(o_128-1));
tmp4 = temp3.val[1];
//print_bytes("tmp4:",(uint8_t*)&tmp4);
*o_128++=vceqq_u8(vandq_u8((uint8x16_t)tmp4,BIT_MASK),BIT_MASK); //6
//print_bytes("o:",(uint8_t*)(o_128-1));
temp2 = vzipq_u16((uint16x8_t)tmp2,(uint16x8_t)tmp2);
tmp3 = temp2.val[1];
temp3 = vzipq_u32((uint32x4_t)tmp3,(uint32x4_t)tmp3);
tmp4 = temp3.val[0];
//print_bytes("tmp4:",(uint8_t*)&tmp4);
*o_128++=vceqq_u8(vandq_u8((uint8x16_t)tmp4,BIT_MASK),BIT_MASK); //7
//print_bytes("o:",(uint8_t*)(o_128-1));
tmp4 = temp3.val[1];
//print_bytes("tmp4:",(uint8_t*)&tmp4);
*o_128++=vceqq_u8(vandq_u8((uint8x16_t)tmp4,BIT_MASK),BIT_MASK); //7
//print_bytes("o:",(uint8_t*)(o_128-1));
i_128++;
#endif
}
short * ptr_intl=base_interleaver;
short *ptr_intl=base_interleaver;
#if defined(__x86_64) || defined(__i386__)
#ifndef __AVX2__
__m128i tmp;
uint16_t *systematic2_ptr=(uint16_t *) output;
uint16_t *systematic2_ptr=(uint16_t *) output;
#else
__m256i tmp;
uint32_t *systematic2_ptr=(uint32_t *) output;
uint32_t *systematic2_ptr=(uint32_t *) output;
#endif
#elif defined(__arm__)
uint8x16_t tmp;
const uint8_t __attribute__ ((aligned (16))) _Powers[16]=
{ 1, 2, 4, 8, 16, 32, 64, 128, 1, 2, 4, 8, 16, 32, 64, 128 };
// Set the powers of 2 (do it once for all, if applicable)
const uint8_t __attribute__ ((aligned (16))) _Powers[16]=
{ 1, 2, 4, 8, 16, 32, 64, 128, 1, 2, 4, 8, 16, 32, 64, 128 };
// Set the powers of 2 (do it once for all, if applicable)
uint8x16_t Powers= vld1q_u8(_Powers);
uint8_t *systematic2_ptr=(uint8_t *) output;
#endif
@@ -435,8 +396,6 @@ char interleave_compact_byte(short * base_interleaver,unsigned char * input, uns
#endif
for ( i=0; i< input_length_words ; i ++ ) {
#if defined(__x86_64__) || defined(__i386__)
#ifndef __AVX2__
tmp=_mm_insert_epi8(tmp,expandInput[*ptr_intl++],7);
@@ -465,7 +424,6 @@ char interleave_compact_byte(short * base_interleaver,unsigned char * input, uns
tmp=_mm256_insert_epi8(tmp,expandInput[*ptr_intl++],2);
tmp=_mm256_insert_epi8(tmp,expandInput[*ptr_intl++],1);
tmp=_mm256_insert_epi8(tmp,expandInput[*ptr_intl++],0);
tmp=_mm256_insert_epi8(tmp,expandInput[*ptr_intl++],8+7);
tmp=_mm256_insert_epi8(tmp,expandInput[*ptr_intl++],8+6);
tmp=_mm256_insert_epi8(tmp,expandInput[*ptr_intl++],8+5);
@@ -474,7 +432,6 @@ char interleave_compact_byte(short * base_interleaver,unsigned char * input, uns
tmp=_mm256_insert_epi8(tmp,expandInput[*ptr_intl++],8+2);
tmp=_mm256_insert_epi8(tmp,expandInput[*ptr_intl++],8+1);
tmp=_mm256_insert_epi8(tmp,expandInput[*ptr_intl++],8+0);
tmp=_mm256_insert_epi8(tmp,expandInput[*ptr_intl++],16+7);
tmp=_mm256_insert_epi8(tmp,expandInput[*ptr_intl++],16+6);
tmp=_mm256_insert_epi8(tmp,expandInput[*ptr_intl++],16+5);
@@ -483,7 +440,6 @@ char interleave_compact_byte(short * base_interleaver,unsigned char * input, uns
tmp=_mm256_insert_epi8(tmp,expandInput[*ptr_intl++],16+2);
tmp=_mm256_insert_epi8(tmp,expandInput[*ptr_intl++],16+1);
tmp=_mm256_insert_epi8(tmp,expandInput[*ptr_intl++],16+0);
tmp=_mm256_insert_epi8(tmp,expandInput[*ptr_intl++],24+7);
tmp=_mm256_insert_epi8(tmp,expandInput[*ptr_intl++],24+6);
tmp=_mm256_insert_epi8(tmp,expandInput[*ptr_intl++],24+5);
@@ -492,7 +448,6 @@ char interleave_compact_byte(short * base_interleaver,unsigned char * input, uns
tmp=_mm256_insert_epi8(tmp,expandInput[*ptr_intl++],24+2);
tmp=_mm256_insert_epi8(tmp,expandInput[*ptr_intl++],24+1);
tmp=_mm256_insert_epi8(tmp,expandInput[*ptr_intl++],24+0);
*systematic2_ptr++=(unsigned int)_mm256_movemask_epi8(tmp);
#endif
#elif defined(__arm__)
@@ -512,11 +467,10 @@ char interleave_compact_byte(short * base_interleaver,unsigned char * input, uns
tmp=vsetq_lane_u8(expandInput[*ptr_intl++],tmp,8+2);
tmp=vsetq_lane_u8(expandInput[*ptr_intl++],tmp,8+1);
tmp=vsetq_lane_u8(expandInput[*ptr_intl++],tmp,8+0);
// Compute the mask from the input
// Compute the mask from the input
uint64x2_t Mask= vpaddlq_u32(vpaddlq_u16(vpaddlq_u8(vandq_u8(tmp, Powers))));
vst1q_lane_u8(systematic2_ptr++, (uint8x16_t)Mask, 0);
vst1q_lane_u8(systematic2_ptr++, (uint8x16_t)Mask, 8);
#endif
}
@@ -537,14 +491,12 @@ char interleave_compact_byte(short * base_interleaver,unsigned char * input, uns
void threegpplte_turbo_encoder_sse(unsigned char *input,
unsigned short input_length_bytes,
unsigned char *output,
unsigned char F)
{
unsigned char F) {
int i;
unsigned char *x;
unsigned char state0=0,state1=0;
unsigned short input_length_bits = input_length_bytes<<3;
short * base_interleaver;
short *base_interleaver;
if ( all_treillis_initialized == 0 ) {
treillis_table_init();
@@ -560,15 +512,12 @@ void threegpplte_turbo_encoder_sse(unsigned char *input,
base_interleaver=il_tb+f1f2mat[i].beg_index;
}
unsigned char systematic2[768] __attribute__((aligned(32)));
interleave_compact_byte(base_interleaver,input,systematic2,input_length_bytes);
#if defined(__x86_64__) || defined(__i386__)
__m64 *ptr_output=(__m64*) output;
__m64 *ptr_output=(__m64 *) output;
#elif defined(__arm__)
uint8x8_t *ptr_output=(uint8x8_t*)output;
uint8x8_t *ptr_output=(uint8x8_t *)output;
#endif
unsigned char cur_s1, cur_s2;
int code_rate;
@@ -582,54 +531,45 @@ void threegpplte_turbo_encoder_sse(unsigned char *input,
/*
*ptr_output++ = _mm_add_pi8(all_treillis[state0][cur_s1].systematic_64[code_rate],
_mm_add_pi8(all_treillis[state0][cur_s1].parity1_64[code_rate],
all_treillis[state1][cur_s2].parity2_64[code_rate]));
*/
all_treillis[state1][cur_s2].parity2_64[code_rate]));
*/
*ptr_output++ = _mm_add_pi8(all_treillis[state0][cur_s1].systematic_andp1_64[code_rate],
all_treillis[state1][cur_s2].parity2_64[code_rate]);
all_treillis[state1][cur_s2].parity2_64[code_rate]);
#elif defined(__arm__)
*ptr_output++ = vadd_u8(all_treillis[state0][cur_s1].systematic_andp1_64[code_rate],
all_treillis[state0][cur_s1].parity2_64[code_rate]);
*ptr_output++ = vadd_u8(all_treillis[state0][cur_s1].systematic_andp1_64[code_rate],
all_treillis[state0][cur_s1].parity2_64[code_rate]);
#endif
}
state0=all_treillis[state0][cur_s1].exit_state;
state1=all_treillis[state1][cur_s2].exit_state;
}
state0=all_treillis[state0][cur_s1].exit_state;
state1=all_treillis[state1][cur_s2].exit_state;
}
x=output+(input_length_bits*3);
// Trellis termination
threegpplte_rsc_termination(&x[0],&x[1],&state0);
#ifdef DEBUG_TURBO_ENCODER
printf("term: x0 %d, x1 %d, state0 %d\n",x[0],x[1],state0);
printf("term: x0 %u, x1 %u, state0 %d\n",x[0],x[1],state0);
#endif //DEBUG_TURBO_ENCODER
threegpplte_rsc_termination(&x[2],&x[3],&state0);
#ifdef DEBUG_TURBO_ENCODER
printf("term: x0 %d, x1 %d, state0 %d\n",x[2],x[3],state0);
printf("term: x0 %u, x1 %u, state0 %d\n",x[2],x[3],state0);
#endif //DEBUG_TURBO_ENCODER
threegpplte_rsc_termination(&x[4],&x[5],&state0);
#ifdef DEBUG_TURBO_ENCODER
printf("term: x0 %d, x1 %d, state0 %d\n",x[4],x[5],state0);
printf("term: x0 %u, x1 %u, state0 %d\n",x[4],x[5],state0);
#endif //DEBUG_TURBO_ENCODER
threegpplte_rsc_termination(&x[6],&x[7],&state1);
#ifdef DEBUG_TURBO_ENCODER
printf("term: x0 %d, x1 %d, state1 %d\n",x[6],x[7],state1);
printf("term: x0 %u, x1 %u, state1 %d\n",x[6],x[7],state1);
#endif //DEBUG_TURBO_ENCODER
threegpplte_rsc_termination(&x[8],&x[9],&state1);
#ifdef DEBUG_TURBO_ENCODER
printf("term: x0 %d, x1 %d, state1 %d\n",x[8],x[9],state1);
printf("term: x0 %u, x1 %u, state1 %d\n",x[8],x[9],state1);
#endif //DEBUG_TURBO_ENCODER
threegpplte_rsc_termination(&x[10],&x[11],&state1);
#ifdef DEBUG_TURBO_ENCODER
printf("term: x0 %d, x1 %d, state1 %d\n",x[10],x[11],state1);
printf("term: x0 %u, x1 %u, state1 %d\n",x[10],x[11],state1);
#endif //DEBUG_TURBO_ENCODER
#if defined(__x86_64__) || defined(__i386__)
_mm_empty();
@@ -638,32 +578,31 @@ void threegpplte_turbo_encoder_sse(unsigned char *input,
}
void init_encoder_sse (void) {
treillis_table_init();
treillis_table_init();
}
/* function which will be called by the shared lib loader, to check shared lib version
against main exec version. version mismatch no considered as fatal (interfaces not supposed to change)
*/
int coding_checkbuildver(char * mainexec_buildversion, char ** shlib_buildversion)
{
*/
int coding_checkbuildver(char *mainexec_buildversion, char **shlib_buildversion) {
#ifndef PACKAGE_VERSION
#define PACKAGE_VERSION "standalone built: " __DATE__ __TIME__
#endif
*shlib_buildversion = PACKAGE_VERSION;
if (strcmp(mainexec_buildversion, *shlib_buildversion) != 0) {
fprintf(stderr,"[CODING] shared lib version %s, doesn't match main version %s, compatibility should be checked\n",
mainexec_buildversion,*shlib_buildversion);
}
return 0;
*shlib_buildversion = PACKAGE_VERSION;
if (strcmp(mainexec_buildversion, *shlib_buildversion) != 0) {
fprintf(stderr,"[CODING] shared lib version %s, doesn't match main version %s, compatibility should be checked\n",
mainexec_buildversion,*shlib_buildversion);
}
return 0;
}
#ifdef TC_MAIN
#define INPUT_LENGTH 20
#define INPUT_LENGTH 20
#define F1 21
#define F2 120
int main(int argc,char **argv)
{
int main(int argc,char **argv) {
unsigned char input[INPUT_LENGTH+32],state,state2;
unsigned char output[12+(3*(INPUT_LENGTH<<3))],x,z;
int i;
@@ -680,28 +619,27 @@ int main(int argc,char **argv)
printf("\n");
for (state=0; state<8; state++) {
state2=state;
threegpplte_rsc_termination(&x,&z,&state2);
printf("Termination: (%d->%d) : (%d,%d)\n",state,state2,x,z);
}
memset((void*)input,0,INPUT_LENGTH+16);
memset((void *)input,0,INPUT_LENGTH+16);
for (i=0; i<INPUT_LENGTH; i++) {
input[i] = i*219;
printf("Input %d : %d\n",i,input[i]);
printf("Input %d : %u\n",i,input[i]);
}
threegpplte_turbo_encoder_sse(&input[0],
INPUT_LENGTH,
&output[0],
0);
INPUT_LENGTH,
&output[0],
0);
for (i=0; i<12+(INPUT_LENGTH*24); i++)
printf("%u",output[i]);
for (i=0;i<12+(INPUT_LENGTH*24);i++)
printf("%d",output[i]);
printf("\n");
return(0);
}
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+54 -81
View File
@@ -47,27 +47,20 @@ void
ccodedot11_encode (unsigned int numbytes,
unsigned char *inPtr,
unsigned char *outPtr,
unsigned char puncturing)
{
unsigned char puncturing) {
unsigned int state;
unsigned char c, out, shiftbit =0;
// printf("In ccodedot11_encode (%d,%p,%p,%d)\n",numbytes,inPtr,outPtr,puncturing);
#ifdef DEBUG_CCODE
unsigned int dummy;
#endif //DEBUG_CCODE
int bit_index;
/* The input bit is shifted in position 8 of the state.
Shiftbit will take values between 1 and 8 */
state = 0;
#ifdef DEBUG_CCODE
dummy = 0;
#endif //DEBUG_CCODE
/* Do not increment inPtr until we read the next octet */
bit_index=0;
@@ -78,85 +71,75 @@ ccodedot11_encode (unsigned int numbytes,
#endif //DEBUG_CCODE
switch (puncturing) {
case 0: //rate 1/2
for (shiftbit = 0; shiftbit<8; shiftbit++) {
case 0: //rate 1/2
for (shiftbit = 0; shiftbit<8; shiftbit++) {
state >>= 1;
state >>= 1;
if ((c&(1<<shiftbit)) != 0) {
state |= 64;
}
if ((c&(1<<shiftbit)) != 0) {
state |= 64;
out = ccodedot11_table[state];
*outPtr++ = out & 1;
*outPtr++ = (out>>1)&1;
#ifdef DEBUG_CCODE
printf("%u: %u -> %d (%u)\n",dummy,state,out,ccodedot11_table[state]);
dummy+=2;
#endif //DEBUG_CCODE
}
out = ccodedot11_table[state];
break;
*outPtr++ = out & 1;
*outPtr++ = (out>>1)&1;
case 1: // rate 3/4
for (shiftbit = 0; shiftbit<8; shiftbit++) {
state >>= 1;
if ((c&(1<<shiftbit)) != 0) {
state |= 64;
}
out = ccodedot11_table[state];
if (bit_index<2)
*outPtr++ = out & 1;
if (bit_index!=1)
*outPtr++ = (out>>1)&1;
#ifdef DEBUG_CCODE
printf("%d: %d -> %d (%d)\n",dummy,state,out,ccodedot11_table[state]);
dummy+=2;
printf("%u: %u -> %d (%u)\n",dummy,state,out,ccodedot11_table[state]);
dummy+=2;
#endif //DEBUG_CCODE
}
break;
case 1: // rate 3/4
for (shiftbit = 0; shiftbit<8; shiftbit++) {
state >>= 1;
if ((c&(1<<shiftbit)) != 0) {
state |= 64;
bit_index=(bit_index==2)?0:(bit_index+1);
}
out = ccodedot11_table[state];
break;
if (bit_index<2)
case 2: // rate 2/3
for (shiftbit = 0; shiftbit<8; shiftbit++) {
state >>= 1;
if ((c&(1<<shiftbit)) != 0) {
state |= 64;
}
out = ccodedot11_table[state];
*outPtr++ = out & 1;
if (bit_index!=1)
*outPtr++ = (out>>1)&1;
if (bit_index==0)
*outPtr++ = (out>>1)&1;
#ifdef DEBUG_CCODE
printf("%d: %d -> %d (%d)\n",dummy,state,out,ccodedot11_table[state]);
dummy+=2;
printf("%d: %u -> %d (%u)\n",dummy,state,out,ccodedot11_table[state]);
dummy+=2;
#endif //DEBUG_CCODE
bit_index=(bit_index==2)?0:(bit_index+1);
}
break;
case 2: // rate 2/3
for (shiftbit = 0; shiftbit<8; shiftbit++) {
state >>= 1;
if ((c&(1<<shiftbit)) != 0) {
state |= 64;
bit_index=(bit_index==0)?1:0;
}
out = ccodedot11_table[state];
break;
*outPtr++ = out & 1;
if (bit_index==0)
*outPtr++ = (out>>1)&1;
#ifdef DEBUG_CCODE
printf("%d: %d -> %d (%d)\n",dummy,state,out,ccodedot11_table[state]);
dummy+=2;
#endif //DEBUG_CCODE
bit_index=(bit_index==0)?1:0;
}
break;
default:
break;
default:
break;
}
}
@@ -181,8 +164,6 @@ ccodedot11_encode (unsigned int numbytes,
}
*/
}
@@ -197,8 +178,7 @@ ccodedot11_encode (unsigned int numbytes,
/* Basic code table initialization for constraint length 7 */
/* Input in MSB, followed by state in 6 LSBs */
void ccodedot11_init(void)
{
void ccodedot11_init(void) {
unsigned int i, j, k, sum;
for (i = 0; i < 128; i++) {
@@ -219,8 +199,7 @@ void ccodedot11_init(void)
}
/* Input in LSB, followed by state in 6 MSBs */
void ccodedot11_init_inv(void)
{
void ccodedot11_init_inv(void) {
unsigned int i, j, k, sum;
for (i = 0; i < 128; i++) {
@@ -251,21 +230,15 @@ void ccodedot11_init_inv(void)
#ifdef DEBUG_CCODE
#include <stdio.h>
main()
{
main() {
unsigned char test[] = "0Thebigredfox";
unsigned char output[512], *inPtr, *outPtr;
unsigned int i;
test[0] = 128;
test[1] = 0;
ccodedot11_init();
inPtr = test;
outPtr = output;
ccodedot11_encode(16, inPtr, outPtr,0);
for (i = 0; i < 32; i++) printf("%x ", output[i]);
+8 -39
View File
@@ -52,20 +52,16 @@ ccodelte_encode (int32_t numbits,
uint8_t add_crc,
uint8_t *inPtr,
uint8_t *outPtr,
uint16_t rnti)
{
uint16_t rnti) {
uint32_t state;
uint8_t c, out, first_bit;
int8_t shiftbit=0;
uint16_t c16;
uint16_t next_last_byte=0;
uint32_t crc=0;
#ifdef DEBUG_CCODE
uint32_t dummy=0;
#endif //DEBUG_CCODE
/* The input bit is shifted in position 8 of the state.
Shiftbit will take values between 1 and 8 */
state = 0;
@@ -137,17 +133,12 @@ ccodelte_encode (int32_t numbits,
#endif //DEBUG_CCODE
/* Do not increment inPtr until we read the next octet */
while (numbits > 0) {
c = *inPtr++;
#ifdef DEBUG_CCODE
printf("** %x **\n",c);
#endif //DEBUG_CCODE
// for (shiftbit = 0; (shiftbit<8) && (numbits>0);shiftbit++,numbits--) {
for (shiftbit = 7; (shiftbit>=0) && (numbits>0); shiftbit--,numbits--) {
state >>= 1;
@@ -157,23 +148,18 @@ ccodelte_encode (int32_t numbits,
}
out = ccodelte_table[state];
*outPtr++ = out & 1;
*outPtr++ = (out>>1)&1;
*outPtr++ = (out>>2)&1;
#ifdef DEBUG_CCODE
printf("numbits %d, input %d, outbit %d: %d -> %d (%d%d%d)\n",numbits,state>>6,dummy,state,out,out&1,(out>>1)&1,(out>>2)&1);
dummy+=3;
#endif //DEBUG_CCODE
}
}
// now code 8-bit CRC for UCI
if (add_crc == 1) {
c = (uint8_t)(crc>>24);
// for (shiftbit = 0; (shiftbit<8);shiftbit++) {
@@ -185,22 +171,18 @@ ccodelte_encode (int32_t numbits,
}
out = ccodelte_table[state];
*outPtr++ = out & 1;
*outPtr++ = (out>>1)&1;
*outPtr++ = (out>>2)&1;
#ifdef DEBUG_CCODE
printf("crc bit %d input %d, outbit %d: %d -> %d (%d)\n",shiftbit,state>>6,dummy,state,out,ccodelte_table[state]);
printf("crc bit %d input %d, outbit %d: %d -> %d (%u)\n",shiftbit,state>>6,dummy,state,out,ccodelte_table[state]);
dummy+=3;
#endif //DEBUG_CCODE
}
}
// now code 16-bit CRC for DCI
if (add_crc == 2) {
c16 = (uint16_t)(crc>>16);
// for (shiftbit = 0; (shiftbit<16);shiftbit++) {
@@ -212,16 +194,13 @@ ccodelte_encode (int32_t numbits,
}
out = ccodelte_table[state];
*outPtr++ = out & 1;
*outPtr++ = (out>>1)&1;
*outPtr++ = (out>>2)&1;
#ifdef DEBUG_CCODE
printf("crc bit %d input %d, outbit %d: %d -> %d (%d)\n",shiftbit,state>>6,dummy,state,out,ccodelte_table[state]);
printf("crc bit %d input %d, outbit %d: %d -> %d (%u)\n",shiftbit,state>>6,dummy,state,out,ccodelte_table[state]);
dummy+=3;
#endif //DEBUG_CCODE
}
}
}
@@ -238,8 +217,7 @@ ccodelte_encode (int32_t numbits,
/* Basic code table initialization for constraint length 7 */
/* Input in MSB, followed by state in 6 LSBs */
void ccodelte_init(void)
{
void ccodelte_init(void) {
unsigned int i, j, k, sum;
for (i = 0; i < 128; i++) {
@@ -260,8 +238,7 @@ void ccodelte_init(void)
}
/* Input in LSB, followed by state in 6 MSBs */
void ccodelte_init_inv(void)
{
void ccodelte_init_inv(void) {
unsigned int i, j, k, sum;
for (i = 0; i < 128; i++) {
@@ -281,8 +258,7 @@ void ccodelte_init_inv(void)
}
}
void ccodedab_init(void)
{
void ccodedab_init(void) {
unsigned int i, j, k, sum;
for (i = 0; i < 128; i++) {
@@ -303,8 +279,7 @@ void ccodedab_init(void)
}
/* Input in LSB, followed by state in 6 MSBs */
void ccodedab_init_inv(void)
{
void ccodedab_init_inv(void) {
unsigned int i, j, k, sum;
for (i = 0; i < 128; i++) {
@@ -334,21 +309,15 @@ void ccodedab_init_inv(void)
#ifdef CCODE_MAIN
#include <stdio.h>
main()
{
main() {
unsigned char test[] = "Thebigredfox";
unsigned char output[512], *inPtr, *outPtr;
unsigned int i;
test[0] = 128;
test[1] = 0;
ccodelte_init();
inPtr = test;
outPtr = output;
ccodelte_encode(21, inPtr, outPtr);
for (i = 0; i < 21*3; i++) printf("%x ", output[i]);
+22 -89
View File
@@ -25,8 +25,8 @@
date: 21.10.2009
*/
#ifdef MAIN
#include <stdio.h>
#include <stdlib.h>
#include <stdio.h>
#include <stdlib.h>
#endif
#include "PHY/defs_eNB.h"
#include "PHY/LTE_TRANSPORT/transport_common.h"
@@ -42,9 +42,7 @@ static uint32_t bitrev_cc[32] = {1,17,9,25,5,21,13,29,3,19,11,27,7,23,15,31,0,16
//#define RM_DEBUG2 1
//#define RM_DEBUG_CC 1
uint32_t sub_block_interleaving_turbo(uint32_t D, uint8_t *d,uint8_t *w)
{
uint32_t sub_block_interleaving_turbo(uint32_t D, uint8_t *d,uint8_t *w) {
uint32_t RTC = (D>>5), ND, ND3;
uint32_t row,col,Kpi;
uint32_t index3,k,k2;
@@ -64,7 +62,6 @@ uint32_t sub_block_interleaving_turbo(uint32_t D, uint8_t *d,uint8_t *w)
printf("RTC = %d, Kpi=%d, ND=%d\n",RTC,Kpi,ND);
#endif
ND3 = ND*3;
// copy d02 to dD2 (for mod Kpi operation from clause (4), p.16 of 36.212
d[(3*D)+2] = d[2];
k=0;
@@ -80,12 +77,9 @@ uint32_t sub_block_interleaving_turbo(uint32_t D, uint8_t *d,uint8_t *w)
index3 = bitrev_x3[col];//3*index;
for (row=0; row<RTC; row++) {
w[k] = d1[index3];//d[index3-ND3];
w[Kpi+k2] = d2[index3];//d[index3-ND3+1];
w[Kpi+1+k2] = d3[index3];//d[index3-ND3+5];
#ifdef RM_DEBUG
printf("row %d, index %d, index-Nd %d index-Nd+1 %d (k,Kpi+2k,Kpi+2k+1) (%d,%d,%d) w(%d,%d,%d)\n",row,index,index-ND,((index+1)%Kpi)-ND,k,Kpi+(k<<1),Kpi+(k<<1)+1,w[k],w[Kpi+(k<<1)],w[Kpi+1+(k<<1)]);
@@ -100,7 +94,8 @@ uint32_t sub_block_interleaving_turbo(uint32_t D, uint8_t *d,uint8_t *w)
#endif
index3+=96;
k++;k2+=2;
k++;
k2+=2;
}
}
@@ -120,9 +115,7 @@ uint32_t sub_block_interleaving_turbo(uint32_t D, uint8_t *d,uint8_t *w)
}
uint32_t sub_block_interleaving_cc(uint32_t D, uint8_t *d,uint8_t *w)
{
uint32_t sub_block_interleaving_cc(uint32_t D, uint8_t *d,uint8_t *w) {
uint32_t RCC = (D>>5), ND, ND3;
uint32_t row,col,Kpi,index;
uint32_t index3,k;
@@ -141,7 +134,6 @@ uint32_t sub_block_interleaving_cc(uint32_t D, uint8_t *d,uint8_t *w)
printf("RCC = %d, Kpi=%d, ND=%d\n",RCC,Kpi,ND);
#endif
ND3 = ND*3;
k=0;
for (col=0; col<32; col++) {
@@ -180,9 +172,7 @@ uint32_t sub_block_interleaving_cc(uint32_t D, uint8_t *d,uint8_t *w)
return(RCC);
}
void sub_block_deinterleaving_turbo(uint32_t D,int16_t *d,int16_t *w)
{
void sub_block_deinterleaving_turbo(uint32_t D,int16_t *d,int16_t *w) {
uint32_t RTC = (D>>5), ND, ND3;
uint32_t row,col,Kpi,index;
uint32_t index3,k,k2;
@@ -199,7 +189,6 @@ void sub_block_deinterleaving_turbo(uint32_t D,int16_t *d,int16_t *w)
printf("RTC = %d, Kpi=%d, ND=%d\n",RTC,Kpi,ND);
#endif
ND3 = ND*3;
// copy d02 to dD2 (for mod Kpi operation from clause (4), p.16 of 36.212
k=0;
k2=0;
@@ -215,7 +204,6 @@ void sub_block_deinterleaving_turbo(uint32_t D,int16_t *d,int16_t *w)
index3 = bitrev_x3[col];//3*index;
for (row=0; row<RTC; row++) {
d1[index3] = w[k];
d2[index3] = w[Kpi+k2];
d3[index3] = w[Kpi+1+k2];
@@ -229,12 +217,9 @@ void sub_block_deinterleaving_turbo(uint32_t D,int16_t *d,int16_t *w)
// if (ND>0)
// d[2] = LTE_NULL;//d[(3*D)+2];
}
void sub_block_deinterleaving_cc(uint32_t D,int8_t *d,int8_t *w)
{
void sub_block_deinterleaving_cc(uint32_t D,int8_t *d,int8_t *w) {
//WANG_Hao uint32_t RCC = (D>>5), ND, ND3;
uint32_t RCC = (D>>5);
ptrdiff_t ND, ND3;
@@ -251,10 +236,9 @@ void sub_block_deinterleaving_cc(uint32_t D,int8_t *d,int8_t *w)
ND = Kpi - D;
#ifdef RM_DEBUG2
printf("sub_block_interleaving_cc : D = %d (%d), d %p, w %p\n",D,D*3,d,w);
printf("RCC = %d, Kpi=%d, ND=%d\n",RCC,Kpi,ND);
printf("RCC = %d, Kpi=%d, ND=%ld\n",RCC,Kpi,ND);
#endif
ND3 = ND*3;
k=0;
for (col=0; col<32; col++) {
@@ -265,24 +249,20 @@ void sub_block_deinterleaving_cc(uint32_t D,int8_t *d,int8_t *w)
index3 = 3*index;
for (row=0; row<RCC; row++) {
d[index3-ND3] = w[k];
d[index3-ND3+1] = w[Kpi+k];
d[index3-ND3+2] = w[(Kpi<<1)+k];
#ifdef RM_DEBUG2
printf("row %d, index %d k %d index3-ND3 %d w(%d,%d,%d)\n",row,index,k,index3-ND3,w[k],w[Kpi+k],w[(Kpi<<1)+k]);
printf("row %d, index %d k %d index3-ND3 %ld w(%d,%d,%d)\n",row,index,k,index3-ND3,w[k],w[Kpi+k],w[(Kpi<<1)+k]);
#endif
index3+=96;
index+=32;
k++;
}
}
}
uint32_t generate_dummy_w(uint32_t D, uint8_t *w,uint8_t F)
{
uint32_t generate_dummy_w(uint32_t D, uint8_t *w,uint8_t F) {
uint32_t RTC = (D>>5), ND;
uint32_t col,Kpi,index;
int32_t k,k2;
@@ -301,8 +281,6 @@ uint32_t generate_dummy_w(uint32_t D, uint8_t *w,uint8_t F)
printf("dummy sub_block_interleaving_turbo : D = %d (%d)\n",D,D*3);
printf("RTC = %d, Kpi=%d, ND=%d, F=%d (Nulled %d)\n",RTC,Kpi,ND,F,(2*F + 3*ND));
#endif
k=0;
k2=0;
wKpi = &w[Kpi];
@@ -371,9 +349,7 @@ uint32_t generate_dummy_w(uint32_t D, uint8_t *w,uint8_t F)
return(RTC);
}
uint32_t generate_dummy_w_cc(uint32_t D, uint8_t *w)
{
uint32_t generate_dummy_w_cc(uint32_t D, uint8_t *w) {
uint32_t RCC = (D>>5), ND;
uint32_t col,Kpi,index;
int32_t k;
@@ -392,7 +368,6 @@ uint32_t generate_dummy_w_cc(uint32_t D, uint8_t *w)
printf("RCC = %d, Kpi=%d, ND=%d, (Nulled %d)\n",RCC,Kpi,ND,3*ND);
#endif
// ND3 = ND*3;
// copy d02 to dD2 (for mod Kpi operation from clause (4), p.16 of 36.212
k=0;
@@ -466,8 +441,6 @@ uint32_t lte_rate_matching_turbo(uint32_t RTC,
uint8_t nb_rb)
// uint8_t m)
{
uint32_t Nir,Ncb,Gp,GpmodC,E,Ncbmod,ind,k;
// int cnt=0;
uint8_t *e2;
@@ -487,11 +460,11 @@ uint32_t lte_rate_matching_turbo(uint32_t RTC,
if (Mdlharq>0) { // Downlink
Nir = Nsoft/Kmimo/cmin(8,Mdlharq);
Ncb = cmin(Nir/C,3*(RTC<<5));
}
else { // Uplink
} else { // Uplink
Nir=0;
Ncb = 3*(RTC<<5); // Kw
}
#ifdef RM_DEBUG_TX
if (rvidx==0 && r==0) {
@@ -518,7 +491,6 @@ uint32_t lte_rate_matching_turbo(uint32_t RTC,
AssertFatal(Qm>0,"Qm is 0\n");
Gp = G/Nl/Qm;
GpmodC = Gp%C;
#ifdef RM_DEBUG
printf("lte_rate_matching_turbo: Ncb %d, Kw %d, Nir/C %d, rvidx %d, G %d, Qm %d, Nl%d, r %d\n",Ncb,3*(RTC<<5),Nir/C,rvidx, G, Qm,Nl,r);
#endif
@@ -529,16 +501,12 @@ uint32_t lte_rate_matching_turbo(uint32_t RTC,
E = Nl*Qm * ((GpmodC==0?0:1) + (Gp/C));
Ncbmod = Ncb%(RTC<<3);
ind = RTC * (2+(rvidx*(((Ncbmod==0)?0:1) + (Ncb/(RTC<<3)))*2));
#ifdef RM_DEBUG_TX
printf("lte_rate_matching_turbo: E %d, k0 %d, Ncbmod %d, Ncb/(RTC<<3) %d\n",E,ind,Ncbmod,Ncb/(RTC<<3));
#endif
//e2=e+(r*E);
e2 = e;
k=0;
for (; (ind<Ncb)&&(k<E); ind++) {
@@ -633,25 +601,16 @@ uint32_t lte_rate_matching_turbo(uint32_t RTC,
uint32_t lte_rate_matching_cc(uint32_t RCC,
uint16_t E,
uint8_t *w,
uint8_t *e)
{
uint8_t *e) {
uint32_t ind=0,k;
uint16_t Kw = 3*(RCC<<5);
#ifdef RM_DEBUG_CC
uint32_t nulled=0;
printf("lte_rate_matching_cc: Kw %d, E %d\n",Kw, E);
#endif
for (k=0; k<E; k++) {
while(w[ind] == LTE_NULL) {
#ifdef RM_DEBUG_CC
nulled++;
printf("RM_TX_CC : ind %d, NULL\n",ind);
@@ -662,7 +621,6 @@ uint32_t lte_rate_matching_cc(uint32_t RCC,
ind=0;
}
e[k] = w[ind];
#ifdef RM_DEBUG_CC
// printf("k %d ind %d, w %c(%d)\n",k,ind,w[ind],w[ind]);
@@ -695,10 +653,7 @@ int lte_rate_matching_turbo_rx(uint32_t RTC,
uint8_t Qm,
uint8_t Nl,
uint8_t r,
uint32_t *E_out)
{
uint32_t *E_out) {
uint32_t Nir,Ncb,Gp,GpmodC,E,Ncbmod,ind,k;
int16_t *soft_input2;
// int32_t w_tmp;
@@ -708,15 +663,14 @@ int lte_rate_matching_turbo_rx(uint32_t RTC,
if (Kmimo==0 || C==0 || Qm==0 || Nl==0) {
printf("lte_rate_matching.c: invalid parameters (Kmimo %d, Mdlharq %d, C %d, Qm %d, Nl %d\n",
Kmimo,Mdlharq,C,Qm,Nl);
Kmimo,Mdlharq,C,Qm,Nl);
return(-1);
}
if (Mdlharq>0) { // Downlink
Nir = Nsoft/Kmimo/cmin(8,Mdlharq);
Ncb = cmin(Nir/C,3*(RTC<<5));
}
else { // Uplink
} else { // Uplink
Nir=0;
Ncb = 3*(RTC<<5);
}
@@ -726,17 +680,13 @@ int lte_rate_matching_turbo_rx(uint32_t RTC,
Gp = G/Nl/Qm;
GpmodC = Gp%C;
if (r < (C-(GpmodC)))
E = Nl*Qm * (Gp/C);
else
E = Nl*Qm * ((GpmodC==0?0:1) + (Gp/C));
Ncbmod = Ncb%(RTC<<3);
ind = RTC * (2+(rvidx*(((Ncbmod==0)?0:1) + (Ncb/(RTC<<3)))*2));
#ifdef RM_DEBUG
printf("lte_rate_matching_turbo_rx: Clear %d, E %d, Ncb %d, Kw %d, rvidx %d, G %d, Qm %d, Nl%d, r %d\n",clear,E,Ncb,3*(RTC<<5),rvidx, G, Qm,Nl,r);
#endif
@@ -751,8 +701,8 @@ int lte_rate_matching_turbo_rx(uint32_t RTC,
if (dummy_w[ind] != LTE_NULL) {
/*
if ((w[ind]>0 && soft_input2[k]<0) ||
(w[ind]<0 && soft_input2[k]>0))
printf("ind %d: w %d => soft_in %d\n",ind,w[ind],soft_input2[k]);*/
(w[ind]<0 && soft_input2[k]>0))
printf("ind %d: w %d => soft_in %d\n",ind,w[ind],soft_input2[k]);*/
w[ind] += soft_input2[k++];
#ifdef RM_DEBUG
printf("RM_RX k%d Ind: %d (%d)\n",k-1,ind,w[ind]);
@@ -831,10 +781,8 @@ int lte_rate_matching_turbo_rx(uint32_t RTC,
ind=0;
}
*/
*E_out = E;
return(0);
}
@@ -842,28 +790,19 @@ void lte_rate_matching_cc_rx(uint32_t RCC,
uint16_t E,
int8_t *w,
uint8_t *dummy_w,
int8_t *soft_input)
{
int8_t *soft_input) {
uint32_t ind=0,k;
uint16_t Kw = 3*(RCC<<5);
uint32_t acc=1;
int16_t w16[Kw];
#ifdef RM_DEBUG_CC
uint32_t nulled=0;
printf("lte_rate_matching_cc_rx: Kw %d, E %d, w %p, soft_input %p\n",3*(RCC<<5),E,w,soft_input);
#endif
memset(w,0,Kw);
memset(w16,0,Kw*sizeof(int16_t));
for (k=0; k<E; k++) {
while(dummy_w[ind] == LTE_NULL) {
#ifdef RM_DEBUG_CC
nulled++;
@@ -883,10 +822,7 @@ void lte_rate_matching_cc_rx(uint32_t RCC,
#ifdef RM_DEBUG_CC
printf("RM_RX_CC k %d (%d) ind: %d (%d)\n",k,soft_input[k],ind,w16[ind]);
#endif
w16[ind] += soft_input[k];
ind++;
if (ind==Kw) {
@@ -907,7 +843,6 @@ void lte_rate_matching_cc_rx(uint32_t RCC,
}
#ifdef RM_DEBUG_CC
printf("Nulled %d\n",nulled);
#endif
}
@@ -915,8 +850,7 @@ void lte_rate_matching_cc_rx(uint32_t RCC,
#ifdef MAIN
void main()
{
void main() {
uint8_t d[96+3+(3*6144)];
uint8_t w[3*6144],e[12*6144];
uint32_t RTC,G,rvidx;
@@ -924,7 +858,6 @@ void main()
uint32_t mod_order = 4;
uint32_t first_dlsch_symbol = 2;
uint32_t i;
G = ( nb_rb * (12 * mod_order) * (12-first_dlsch_symbol-3)) ;//( nb_rb * (12 * mod_order) * (14-first_dlsch_symbol-3)) :
// initialize 96 first positions to "LTE_NULL"
+15 -25
View File
@@ -38,9 +38,7 @@ int lte_segmentation(unsigned char *input_buffer,
unsigned int *Cminus,
unsigned int *Kplus,
unsigned int *Kminus,
unsigned int *F)
{
unsigned int *F) {
unsigned int L,Bprime,Bprime_by_C,r,Kr,k,s,crc;
if (B<=6144) {
@@ -56,19 +54,19 @@ int lte_segmentation(unsigned char *input_buffer,
Bprime = B+((*C)*L);
#ifdef DEBUG_SEGMENTATION
printf("Bprime %d\n",Bprime);
printf("Bprime %u\n",Bprime);
#endif
}
if ((*C)>MAX_NUM_DLSCH_SEGMENTS) {
LOG_E(PHY,"lte_segmentation.c: too many segments %d, B %d, L %d, Bprime %d\n",*C,B,L,Bprime);
LOG_E(PHY,"lte_segmentation.c: too many segments %d, B %d, L %d, Bprime %d\n",*C,B,L,Bprime);
return(-1);
}
// Find K+
Bprime_by_C = Bprime/(*C);
#ifdef DEBUG_SEGMENTATION
printf("Bprime_by_C %d\n",Bprime_by_C);
printf("Bprime_by_C %u\n",Bprime_by_C);
#endif
// Bprime = Bprime_by_C>>3;
@@ -93,17 +91,16 @@ int lte_segmentation(unsigned char *input_buffer,
*Kminus = (*Kplus - 32);
} else if (Bprime_by_C <=6144 ) { // increase by 8 bytes til here
*Kplus = (Bprime_by_C>>6)<<6;
#ifdef DEBUG_SEGMENTATION
printf("Bprime_by_C_by_C %d , Kplus %d\n",Bprime_by_C,*Kplus);
printf("Bprime_by_C_by_C %u , Kplus %u\n",Bprime_by_C,*Kplus);
#endif
if (*Kplus < Bprime_by_C)
*Kplus = *Kplus + 64;
#ifdef DEBUG_SEGMENTATION
printf("Bprime_by_C_by_C %d , Kplus2 %d\n",Bprime_by_C,*Kplus);
printf("Bprime_by_C_by_C %u , Kplus2 %u\n",Bprime_by_C,*Kplus);
#endif
*Kminus = (*Kplus - 64);
} else {
@@ -116,25 +113,21 @@ int lte_segmentation(unsigned char *input_buffer,
*Kminus = 0;
*Cminus = 0;
} else {
// printf("More than one segment (%d), exiting \n",*C);
// exit(-1);
*Cminus = ((*C)*(*Kplus) - (Bprime))/((*Kplus) - (*Kminus));
*Cplus = (*C) - (*Cminus);
}
AssertFatal(Bprime <= (*Cplus)*(*Kplus) + (*Cminus)*(*Kminus),
"Bprime %d < (*Cplus %d)*(*Kplus %d) + (*Cminus %d)*(*Kminus %d)\n",
Bprime,*Cplus,*Kplus,*Cminus,*Kminus);
"Bprime %d < (*Cplus %d)*(*Kplus %d) + (*Cminus %d)*(*Kminus %d)\n",
Bprime,*Cplus,*Kplus,*Cminus,*Kminus);
*F = ((*Cplus)*(*Kplus) + (*Cminus)*(*Kminus) - (Bprime));
#ifdef DEBUG_SEGMENTATION
printf("C %d, Cplus %d, Cminus %d, Kplus %d, Kminus %d, Bprime_bytes %d, Bprime %d, F %d\n",*C,*Cplus,*Cminus,*Kplus,*Kminus,Bprime>>3,Bprime,*F);
printf("C %u, Cplus %u, Cminus %u, Kplus %u, Kminus %u, Bprime_bytes %u, Bprime %u, F %u\n",*C,*Cplus,*Cminus,*Kplus,*Kminus,Bprime>>3,Bprime,*F);
#endif
if ((input_buffer) && (output_buffers)) {
for (k=0; k<*F>>3; k++) {
output_buffers[0][k] = 0;
}
@@ -142,7 +135,6 @@ int lte_segmentation(unsigned char *input_buffer,
s=0;
for (r=0; r<*C; r++) {
if (r<*Cminus)
Kr = *Kminus;
else
@@ -150,18 +142,18 @@ int lte_segmentation(unsigned char *input_buffer,
while (k<((Kr - L)>>3)) {
output_buffers[r][k] = input_buffer[s];
// printf("encoding segment %d : byte %d (%d) => %d\n",r,k,Kr>>3,input_buffer[s]);
// printf("encoding segment %d : byte %d (%d) => %d\n",r,k,Kr>>3,input_buffer[s]);
k++;
s++;
}
if (*C > 1) { // add CRC
crc = crc24b(output_buffers[r],Kr-24)>>8;
output_buffers[r][(Kr-24)>>3] = ((uint8_t*)&crc)[2];
output_buffers[r][1+((Kr-24)>>3)] = ((uint8_t*)&crc)[1];
output_buffers[r][2+((Kr-24)>>3)] = ((uint8_t*)&crc)[0];
output_buffers[r][(Kr-24)>>3] = ((uint8_t *)&crc)[2];
output_buffers[r][1+((Kr-24)>>3)] = ((uint8_t *)&crc)[1];
output_buffers[r][2+((Kr-24)>>3)] = ((uint8_t *)&crc)[0];
#ifdef DEBUG_SEGMENTATION
printf("Segment %d : CRC %x\n",r,crc);
printf("Segment %u : CRC %x\n",r,crc);
#endif
}
@@ -175,9 +167,7 @@ int lte_segmentation(unsigned char *input_buffer,
#ifdef MAIN
main()
{
main() {
unsigned int Kplus,Kminus,C,Cplus,Cminus,F,Bbytes;
for (Bbytes=5; Bbytes<2*768; Bbytes++) {
@@ -34,8 +34,7 @@ int lte_dl_channel_estimation(PHY_VARS_UE *ue,
unsigned char Ns,
unsigned char p,
unsigned char l,
unsigned char symbol)
{
unsigned char symbol) {
int pilot[2][200] __attribute__((aligned(16)));
unsigned char nu,aarx;
unsigned short k;
@@ -45,16 +44,14 @@ int lte_dl_channel_estimation(PHY_VARS_UE *ue,
// unsigned int n;
// int i;
static int interpolateS11S12 = 1;
uint16_t Nid_cell = (eNB_offset == 0) ? ue->frame_parms.Nid_cell : ue->measurements.adj_cell_id[eNB_offset-1];
uint8_t nushift,pilot0,pilot1,pilot2,pilot3;
uint8_t previous_thread_id = ue->current_thread_id[Ns>>1]==0 ? (RX_NB_TH-1):(ue->current_thread_id[Ns>>1]-1);
int **dl_ch_estimates =ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[Ns>>1]].dl_ch_estimates[eNB_offset];
int **dl_ch_estimates_previous=ue->common_vars.common_vars_rx_data_per_thread[previous_thread_id].dl_ch_estimates[eNB_offset];
int **rxdataF=ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[Ns>>1]].rxdataF;
pilot0 = 0;
if (ue->frame_parms.Ncp == 0) { // normal prefix
pilot1 = 4;
pilot2 = 7;
@@ -81,7 +78,6 @@ int lte_dl_channel_estimation(PHY_VARS_UE *ue,
return(-1);
}
//ch_offset = (l*(ue->frame_parms.ofdm_symbol_size));
if (ue->high_speed_flag == 0) // use second channel estimate position for temporary storage
ch_offset = ue->frame_parms.ofdm_symbol_size ;
@@ -89,93 +85,88 @@ int lte_dl_channel_estimation(PHY_VARS_UE *ue,
ch_offset = ue->frame_parms.ofdm_symbol_size*symbol;
symbol_offset = ue->frame_parms.ofdm_symbol_size*symbol;
k = (nu + nushift)%6;
#ifdef DEBUG_CH
printf("Channel Estimation : ThreadId %d, eNB_offset %d cell_id %d ch_offset %d, OFDM size %d, Ncp=%d, l=%d, Ns=%d, k=%d\n",ue->current_thread_id[Ns>>1], eNB_offset,Nid_cell,ch_offset,ue->frame_parms.ofdm_symbol_size,
printf("Channel Estimation : ThreadId %d, eNB_offset %d cell_id %d ch_offset %d, OFDM size %d, Ncp=%d, l=%d, Ns=%d, k=%d\n",ue->current_thread_id[Ns>>1], eNB_offset,Nid_cell,ch_offset,
ue->frame_parms.ofdm_symbol_size,
ue->frame_parms.Ncp,l,Ns,k);
#endif
switch (k) {
case 0 :
f=filt24_0; //for first pilot of RB, first half
f2=filt24_2; //for second pilot of RB, first half
fl=filt24_0; //for first pilot of leftmost RB
f2l2=filt24_2;
// fr=filt24_2r; //for first pilot of rightmost RB
fr=filt24_0r2; //for first pilot of rightmost RB
// f2r2=filt24_0r2;
f2r2=filt24_2r;
case 0 :
f=filt24_0; //for first pilot of RB, first half
f2=filt24_2; //for second pilot of RB, first half
fl=filt24_0; //for first pilot of leftmost RB
f2l2=filt24_2;
// fr=filt24_2r; //for first pilot of rightmost RB
fr=filt24_0r2; //for first pilot of rightmost RB
// f2r2=filt24_0r2;
f2r2=filt24_2r;
f_dc=filt24_0_dcr;
f2_dc=filt24_2_dcl;
break;
f_dc=filt24_0_dcr;
f2_dc=filt24_2_dcl;
case 1 :
f=filt24_1;
f2=filt24_3;
fl=filt24_1l;
f2l2=filt24_3l2;
fr=filt24_1r2;
f2r2=filt24_3r;
f_dc=filt24_1_dcr; //for first pilot of RB, first half
f2_dc=filt24_3_dcl; //for first pilot of RB, first half
break;
break;
case 2 :
f=filt24_2;
f2=filt24_4;
fl=filt24_2l;
f2l2=filt24_4l2;
fr=filt24_2r2;
f2r2=filt24_4r;
f_dc=filt24_2_dcr; //for first pilot of RB, first half
f2_dc=filt24_4_dcl; //for first pilot of RB, first half
break;
case 1 :
f=filt24_1;
f2=filt24_3;
fl=filt24_1l;
f2l2=filt24_3l2;
fr=filt24_1r2;
f2r2=filt24_3r;
f_dc=filt24_1_dcr; //for first pilot of RB, first half
f2_dc=filt24_3_dcl; //for first pilot of RB, first half
break;
case 3 :
f=filt24_3;
f2=filt24_5;
fl=filt24_3l;
f2l2=filt24_5l2;
fr=filt24_3r2;
f2r2=filt24_5r;
f_dc=filt24_3_dcr; //for first pilot of RB, first half
f2_dc=filt24_5_dcl; //for first pilot of RB, first half
break;
case 2 :
f=filt24_2;
f2=filt24_4;
fl=filt24_2l;
f2l2=filt24_4l2;
fr=filt24_2r2;
f2r2=filt24_4r;
f_dc=filt24_2_dcr; //for first pilot of RB, first half
f2_dc=filt24_4_dcl; //for first pilot of RB, first half
break;
case 4 :
f=filt24_4;
f2=filt24_6;
fl=filt24_4l;
f2l2=filt24_6l2;
fr=filt24_4r2;
f2r2=filt24_6r;
f_dc=filt24_4_dcr; //for first pilot of RB, first half
f2_dc=filt24_6_dcl; //for first pilot of RB, first half
break;
case 3 :
f=filt24_3;
f2=filt24_5;
fl=filt24_3l;
f2l2=filt24_5l2;
fr=filt24_3r2;
f2r2=filt24_5r;
f_dc=filt24_3_dcr; //for first pilot of RB, first half
f2_dc=filt24_5_dcl; //for first pilot of RB, first half
break;
case 5 :
f=filt24_5;
f2=filt24_7;
fl=filt24_5l;
f2l2=filt24_7l2;
fr=filt24_5r2;
f2r2=filt24_7r;
f_dc=filt24_5_dcr; //for first pilot of RB, first half
f2_dc=filt24_7_dcl; //for first pilot of RB, first half
break;
case 4 :
f=filt24_4;
f2=filt24_6;
fl=filt24_4l;
f2l2=filt24_6l2;
fr=filt24_4r2;
f2r2=filt24_6r;
f_dc=filt24_4_dcr; //for first pilot of RB, first half
f2_dc=filt24_6_dcl; //for first pilot of RB, first half
break;
case 5 :
f=filt24_5;
f2=filt24_7;
fl=filt24_5l;
f2l2=filt24_7l2;
fr=filt24_5r2;
f2r2=filt24_7r;
f_dc=filt24_5_dcr; //for first pilot of RB, first half
f2_dc=filt24_7_dcl; //for first pilot of RB, first half
break;
default:
LOG_E(PHY,"lte_dl_channel_estimation: k=%d -> ERROR\n",k);
return(-1);
break;
default:
LOG_E(PHY,"lte_dl_channel_estimation: k=%d -> ERROR\n",k);
return(-1);
break;
}
// generate pilot
lte_dl_cell_spec_rx(ue,
eNB_offset,
@@ -184,27 +175,25 @@ int lte_dl_channel_estimation(PHY_VARS_UE *ue,
(l==0)?0:1,
p);
for (aarx=0; aarx<ue->frame_parms.nb_antennas_rx; aarx++) {
pil = (int16_t *)&pilot[p][0];
rxF = (int16_t *)&rxdataF[aarx][((symbol_offset+k+ue->frame_parms.first_carrier_offset))];
dl_ch = (int16_t *)&dl_ch_estimates[(p<<1)+aarx][ch_offset];
// if (eNb_id==0)
memset(dl_ch,0,4*(ue->frame_parms.ofdm_symbol_size));
if (ue->high_speed_flag==0) // multiply previous channel estimate by ch_est_alpha
multadd_complex_vector_real_scalar(dl_ch-(ue->frame_parms.ofdm_symbol_size<<1),
ue->ch_est_alpha,dl_ch-(ue->frame_parms.ofdm_symbol_size<<1),
1,ue->frame_parms.ofdm_symbol_size);
#ifdef DEBUG_CH
printf("k %d, first_carrier %d\n",k,ue->frame_parms.first_carrier_offset);
#endif
if ((ue->frame_parms.N_RB_DL==6) ||
(ue->frame_parms.N_RB_DL==50) ||
(ue->frame_parms.N_RB_DL==100)) {
//First half of pilots
// Treat first 2 pilots specially (left edge)
ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
@@ -219,7 +208,6 @@ int lte_dl_channel_estimation(PHY_VARS_UE *ue,
pil+=2; // Re Im
rxF+=12;
dl_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);
#ifdef DEBUG_CH
@@ -234,28 +222,22 @@ int lte_dl_channel_estimation(PHY_VARS_UE *ue,
dl_ch+=16;
for (pilot_cnt=2; pilot_cnt<((ue->frame_parms.N_RB_DL)-1); pilot_cnt+=2) {
ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15); //Re
ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15); //Im
#ifdef DEBUG_CH
printf("pilot %d : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",pilot_cnt,rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]);
printf("pilot %u : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",pilot_cnt,rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]);
#endif
multadd_real_vector_complex_scalar(f,
ch,
dl_ch,
24);
pil+=2; // Re Im
rxF+=12;
dl_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);
#ifdef DEBUG_CH
printf("pilot %d : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",pilot_cnt+1,rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]);
printf("pilot %u : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",pilot_cnt+1,rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]);
#endif
multadd_real_vector_complex_scalar(f2,
ch,
@@ -264,29 +246,25 @@ int lte_dl_channel_estimation(PHY_VARS_UE *ue,
pil+=2;
rxF+=12;
dl_ch+=16;
}
// printf("Second half\n");
// Second half of RBs
k = (nu + nushift)%6;
if (k > 6)
k -=6;
rxF = (int16_t *)&rxdataF[aarx][((symbol_offset+1+k))];
#ifdef DEBUG_CH
printf("second half k %d\n",k);
#endif
for (pilot_cnt=0; pilot_cnt<((ue->frame_parms.N_RB_DL)-3); pilot_cnt+=2) {
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);
#ifdef DEBUG_CH
printf("pilot %d : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",pilot_cnt,rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]);
printf("pilot %u : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",pilot_cnt,rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]);
#endif
multadd_real_vector_complex_scalar(f,
ch,
@@ -295,11 +273,10 @@ int lte_dl_channel_estimation(PHY_VARS_UE *ue,
pil+=2;
rxF+=12;
dl_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);
#ifdef DEBUG_CH
printf("pilot %d : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",pilot_cnt+1,rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]);
printf("pilot %u : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",pilot_cnt+1,rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]);
#endif
multadd_real_vector_complex_scalar(f2,
ch,
@@ -308,13 +285,12 @@ int lte_dl_channel_estimation(PHY_VARS_UE *ue,
pil+=2;
rxF+=12;
dl_ch+=16;
}
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);
#ifdef DEBUG_CH
printf("pilot %d: rxF -> (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",pilot_cnt,rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]);
printf("pilot %u: rxF -> (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",pilot_cnt,rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]);
#endif
multadd_real_vector_complex_scalar(fr,
ch,
@@ -323,34 +299,25 @@ int lte_dl_channel_estimation(PHY_VARS_UE *ue,
pil+=2; // Re Im
rxF+=12;
dl_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);
#ifdef DEBUG_CH
printf("pilot %d: rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",pilot_cnt+1,rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]);
printf("pilot %u: rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",pilot_cnt+1,rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]);
#endif
multadd_real_vector_complex_scalar(f2r2,
ch,
dl_ch,
24);
}
else if (ue->frame_parms.N_RB_DL==25) {
} else if (ue->frame_parms.N_RB_DL==25) {
//printf("Channel estimation\n");
// Treat first 2 pilots specially (left edge)
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);
#ifdef DEBUG_CH
printf("pilot 0 : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]);
// ch[0] = 1024;
// ch[1] = -128;
#endif
multadd_real_vector_complex_scalar(fl,
ch,
dl_ch,
@@ -358,17 +325,13 @@ int lte_dl_channel_estimation(PHY_VARS_UE *ue,
pil+=2; // Re Im
rxF+=12;
dl_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);
#ifdef DEBUG_CH
printf("pilot 1 : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]);
// ch[0] = 1024;
// ch[1] = -128;
#endif
multadd_real_vector_complex_scalar(f2l2,
ch,
dl_ch,
@@ -378,21 +341,15 @@ int lte_dl_channel_estimation(PHY_VARS_UE *ue,
dl_ch+=16;
for (pilot_cnt=2; pilot_cnt<24; pilot_cnt+=2) {
// printf("pilot[%d][%d] (%d,%d)\n",p,rb,pil[0],pil[1]);
// printf("rx[%d][%d] -> (%d,%d)\n",p,ue->frame_parms.first_carrier_offset + ue->frame_parms.nushift + 6*rb+(3*p),rxF[0],rxF[1]);
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);
#ifdef DEBUG_CH
printf("pilot %d : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",pilot_cnt,rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]);
printf("pilot %u : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",pilot_cnt,rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]);
// ch[0] = 1024;
// ch[1] = -128;
#endif
multadd_real_vector_complex_scalar(f,
ch,
dl_ch,
@@ -400,13 +357,10 @@ int lte_dl_channel_estimation(PHY_VARS_UE *ue,
pil+=2; // Re Im
rxF+=12;
dl_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);
#ifdef DEBUG_CH
printf("pilot %d : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",pilot_cnt+1,rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]);
printf("pilot %u : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",pilot_cnt+1,rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]);
// ch[0] = 1024;
// ch[1] = -128;
#endif
@@ -417,39 +371,31 @@ int lte_dl_channel_estimation(PHY_VARS_UE *ue,
pil+=2;
rxF+=12;
dl_ch+=16;
}
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);
#ifdef DEBUG_CH
printf("pilot 24: rxF -> (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]);
// ch[0] = 1024;
// ch[1] = -128;
#endif
multadd_real_vector_complex_scalar(f_dc,
ch,
dl_ch,
24);
pil+=2; // Re Im
dl_ch+=8;
// printf("Second half\n");
// Second half of RBs
rxF = (int16_t *)&rxdataF[aarx][((symbol_offset+1+k))];
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);
#ifdef DEBUG_CH
printf("pilot 25: rxF -> (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]);
// ch[0] = 1024;
// ch[1] = -128;
#endif
multadd_real_vector_complex_scalar(f2_dc,
ch,
dl_ch,
@@ -459,19 +405,15 @@ int lte_dl_channel_estimation(PHY_VARS_UE *ue,
dl_ch+=16;
for (pilot_cnt=0; pilot_cnt<22; pilot_cnt+=2) {
// printf("* pilot[%d][%d] (%d,%d)\n",p,rb,pil[0],pil[1]);
// printf("rx[%d][%d] -> (%d,%d)\n",p,ue->frame_parms.first_carrier_offset + ue->frame_parms.nushift + 6*rb+(3*p),rxF[0],rxF[1]);
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);
#ifdef DEBUG_CH
printf("pilot %d rxF -> (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",26+pilot_cnt,rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]);
printf("pilot %u rxF -> (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",26+pilot_cnt,rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]);
// ch[0] = 1024;
// ch[1] = -128;
#endif
multadd_real_vector_complex_scalar(f,
ch,
dl_ch,
@@ -479,16 +421,13 @@ int lte_dl_channel_estimation(PHY_VARS_UE *ue,
pil+=2;
rxF+=12;
dl_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);
#ifdef DEBUG_CH
printf("pilot %d : rxF -> (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",27+pilot_cnt,rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]);
printf("pilot %u : rxF -> (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",27+pilot_cnt,rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]);
// ch[0] = 1024;
// ch[1] = -128;
#endif
multadd_real_vector_complex_scalar(f2,
ch,
dl_ch,
@@ -496,20 +435,15 @@ int lte_dl_channel_estimation(PHY_VARS_UE *ue,
pil+=2;
rxF+=12;
dl_ch+=16;
}
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);
#ifdef DEBUG_CH
printf("pilot 49: rxF -> (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]);
// ch[0] = 1024;
// ch[1] = -128;
#endif
multadd_real_vector_complex_scalar(fr,
ch,
dl_ch,
@@ -517,28 +451,20 @@ int lte_dl_channel_estimation(PHY_VARS_UE *ue,
pil+=2; // Re Im
rxF+=12;
dl_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);
#ifdef DEBUG_CH
printf("pilot 50: rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]);
// ch[0] = 1024;
// ch[1] = -128;
#endif
multadd_real_vector_complex_scalar(f2r2,
ch,
dl_ch,
24);
} else if (ue->frame_parms.N_RB_DL==15) {
//printf("First Half\n");
for (rb=0; rb<28; rb+=4) {
//printf("aarx=%d\n",aarx);
//printf("pilot[%d][%d] (%d,%d)\n",p,rb,pil[0],pil[1]);
//printf("rx[%d][%d] -> (%d,%d)\n",p,
@@ -555,7 +481,6 @@ int lte_dl_channel_estimation(PHY_VARS_UE *ue,
pil+=2; // Re Im
rxF+=12;
dl_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);
//printf("ch -> (%d,%d)\n",ch[0],ch[1]);
@@ -566,7 +491,6 @@ int lte_dl_channel_estimation(PHY_VARS_UE *ue,
pil+=2;
rxF+=12;
dl_ch+=16;
}
ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
@@ -578,13 +502,11 @@ int lte_dl_channel_estimation(PHY_VARS_UE *ue,
24);
pil+=2; // Re Im
dl_ch+=8;
//printf("Second half\n");
//Second half of RBs
rxF = (int16_t *)&rxdataF[aarx][((symbol_offset+1+nushift + (3*p)))];
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);
multadd_real_vector_complex_scalar(f2,
ch,
dl_ch,
@@ -602,7 +524,6 @@ int lte_dl_channel_estimation(PHY_VARS_UE *ue,
// rxF[1]);
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);
multadd_real_vector_complex_scalar(f,
ch,
dl_ch,
@@ -610,10 +531,8 @@ int lte_dl_channel_estimation(PHY_VARS_UE *ue,
pil+=2;
rxF+=12;
dl_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);
multadd_real_vector_complex_scalar(f2,
ch,
dl_ch,
@@ -621,17 +540,14 @@ int lte_dl_channel_estimation(PHY_VARS_UE *ue,
pil+=2;
rxF+=12;
dl_ch+=16;
}
} else {
LOG_E(PHY,"channel estimation not implemented for ue->frame_parms.N_RB_DL = %d\n",ue->frame_parms.N_RB_DL);
}
if (ue->perfect_ce == 0) {
// Temporal Interpolation
// printf("ch_offset %d\n",ch_offset);
dl_ch = (int16_t *)&dl_ch_estimates[(p<<1)+aarx][ch_offset];
if (ue->high_speed_flag == 0) {
@@ -639,182 +555,155 @@ int lte_dl_channel_estimation(PHY_VARS_UE *ue,
32767-ue->ch_est_alpha,
dl_ch-(ue->frame_parms.ofdm_symbol_size<<1),0,ue->frame_parms.ofdm_symbol_size);
} else { // high_speed_flag == 1
if ((symbol == 0)) {
// printf("Interpolating %d->0\n",4-ue->frame_parms.Ncp);
// dl_ch_prev = (int16_t *)&dl_ch_estimates[(p<<1)+aarx][(4-ue->frame_parms.Ncp)*(ue->frame_parms.ofdm_symbol_size)];
if(((Ns>>1)!=0) || ( ((Ns>>1)==0) && interpolateS11S12))
{
//LOG_I(PHY,"Interpolate s11-->s0 to get s12 and s13 Ns %d \n", Ns);
dl_ch_prev = (int16_t *)&dl_ch_estimates_previous[(p<<1)+aarx][pilot3*(ue->frame_parms.ofdm_symbol_size)];
if ((symbol == 0)) {
// printf("Interpolating %d->0\n",4-ue->frame_parms.Ncp);
// dl_ch_prev = (int16_t *)&dl_ch_estimates[(p<<1)+aarx][(4-ue->frame_parms.Ncp)*(ue->frame_parms.ofdm_symbol_size)];
if(((Ns>>1)!=0) || ( ((Ns>>1)==0) && interpolateS11S12)) {
//LOG_I(PHY,"Interpolate s11-->s0 to get s12 and s13 Ns %d \n", Ns);
dl_ch_prev = (int16_t *)&dl_ch_estimates_previous[(p<<1)+aarx][pilot3*(ue->frame_parms.ofdm_symbol_size)];
multadd_complex_vector_real_scalar(dl_ch_prev,21845,dl_ch_prev+(2*(ue->frame_parms.ofdm_symbol_size)),1,ue->frame_parms.ofdm_symbol_size);
multadd_complex_vector_real_scalar(dl_ch,10923,dl_ch_prev+(2*(ue->frame_parms.ofdm_symbol_size)),0,ue->frame_parms.ofdm_symbol_size);
multadd_complex_vector_real_scalar(dl_ch_prev,10923,dl_ch_prev+(2*((ue->frame_parms.ofdm_symbol_size)<<1)),1,ue->frame_parms.ofdm_symbol_size);
multadd_complex_vector_real_scalar(dl_ch,21845,dl_ch_prev+(2*((ue->frame_parms.ofdm_symbol_size)<<1)),0,ue->frame_parms.ofdm_symbol_size);
}
multadd_complex_vector_real_scalar(dl_ch_prev,21845,dl_ch_prev+(2*(ue->frame_parms.ofdm_symbol_size)),1,ue->frame_parms.ofdm_symbol_size);
multadd_complex_vector_real_scalar(dl_ch,10923,dl_ch_prev+(2*(ue->frame_parms.ofdm_symbol_size)),0,ue->frame_parms.ofdm_symbol_size);
interpolateS11S12 = 1;
} // this is 1/3,2/3 combination for pilots spaced by 3 symbols
else if (symbol == pilot1) {
dl_ch_prev = (int16_t *)&dl_ch_estimates[(p<<1)+aarx][0];
multadd_complex_vector_real_scalar(dl_ch_prev,10923,dl_ch_prev+(2*((ue->frame_parms.ofdm_symbol_size)<<1)),1,ue->frame_parms.ofdm_symbol_size);
multadd_complex_vector_real_scalar(dl_ch,21845,dl_ch_prev+(2*((ue->frame_parms.ofdm_symbol_size)<<1)),0,ue->frame_parms.ofdm_symbol_size);
}
//LOG_I(PHY,"Interpolate s0-->s4 to get s1 s2 and s3 Ns %d \n", Ns);
if (ue->frame_parms.Ncp==0) {// pilot spacing 4 symbols (1/4,1/2,3/4 combination)
uint8_t previous_subframe;
interpolateS11S12 = 1;
} // this is 1/3,2/3 combination for pilots spaced by 3 symbols
else if (symbol == pilot1) {
dl_ch_prev = (int16_t *)&dl_ch_estimates[(p<<1)+aarx][0];
//LOG_I(PHY,"Interpolate s0-->s4 to get s1 s2 and s3 Ns %d \n", Ns);
if (ue->frame_parms.Ncp==0) {// pilot spacing 4 symbols (1/4,1/2,3/4 combination)
uint8_t previous_subframe;
if(Ns>>1 == 0)
previous_subframe = 9;
else
previous_subframe = ((Ns>>1) - 1 )%9;
if((subframe_select(&ue->frame_parms,previous_subframe) == SF_UL))
{
multadd_complex_vector_real_scalar(dl_ch_prev,328,dl_ch_prev+(2*(ue->frame_parms.ofdm_symbol_size)),1,ue->frame_parms.ofdm_symbol_size);
multadd_complex_vector_real_scalar(dl_ch,32440,dl_ch_prev+(2*(ue->frame_parms.ofdm_symbol_size)),0,ue->frame_parms.ofdm_symbol_size);
multadd_complex_vector_real_scalar(dl_ch_prev,328,dl_ch_prev+(2*((ue->frame_parms.ofdm_symbol_size)<<1)),1,ue->frame_parms.ofdm_symbol_size);
multadd_complex_vector_real_scalar(dl_ch,32440,dl_ch_prev+(2*((ue->frame_parms.ofdm_symbol_size)<<1)),0,ue->frame_parms.ofdm_symbol_size);
multadd_complex_vector_real_scalar(dl_ch_prev,8192,dl_ch_prev+(3*2*(ue->frame_parms.ofdm_symbol_size)),1,ue->frame_parms.ofdm_symbol_size);
multadd_complex_vector_real_scalar(dl_ch,32440,dl_ch_prev+(3*2*(ue->frame_parms.ofdm_symbol_size)),0,ue->frame_parms.ofdm_symbol_size);
}
else
{
multadd_complex_vector_real_scalar(dl_ch_prev,24576,dl_ch_prev+(2*(ue->frame_parms.ofdm_symbol_size)),1,ue->frame_parms.ofdm_symbol_size);
multadd_complex_vector_real_scalar(dl_ch,8192,dl_ch_prev+(2*(ue->frame_parms.ofdm_symbol_size)),0,ue->frame_parms.ofdm_symbol_size);
multadd_complex_vector_real_scalar(dl_ch_prev,16384,dl_ch_prev+(2*((ue->frame_parms.ofdm_symbol_size)<<1)),1,ue->frame_parms.ofdm_symbol_size);
multadd_complex_vector_real_scalar(dl_ch,16384,dl_ch_prev+(2*((ue->frame_parms.ofdm_symbol_size)<<1)),0,ue->frame_parms.ofdm_symbol_size);
multadd_complex_vector_real_scalar(dl_ch_prev,8192,dl_ch_prev+(3*2*(ue->frame_parms.ofdm_symbol_size)),1,ue->frame_parms.ofdm_symbol_size);
multadd_complex_vector_real_scalar(dl_ch,24576,dl_ch_prev+(3*2*(ue->frame_parms.ofdm_symbol_size)),0,ue->frame_parms.ofdm_symbol_size);
}
} else {
multadd_complex_vector_real_scalar(dl_ch_prev,328,dl_ch_prev+(2*(ue->frame_parms.ofdm_symbol_size)),1,ue->frame_parms.ofdm_symbol_size);
multadd_complex_vector_real_scalar(dl_ch,21845,dl_ch_prev+(2*(ue->frame_parms.ofdm_symbol_size)),0,ue->frame_parms.ofdm_symbol_size);
multadd_complex_vector_real_scalar(dl_ch_prev,21845,dl_ch_prev+(2*(ue->frame_parms.ofdm_symbol_size)<<1),1,ue->frame_parms.ofdm_symbol_size);
multadd_complex_vector_real_scalar(dl_ch,10923,dl_ch_prev+(2*((ue->frame_parms.ofdm_symbol_size)<<1)),0,ue->frame_parms.ofdm_symbol_size);
} // pilot spacing 3 symbols (1/3,2/3 combination)
} else if (symbol == pilot2) {
dl_ch_prev = (int16_t *)&dl_ch_estimates[(p<<1)+aarx][pilot1*(ue->frame_parms.ofdm_symbol_size)];
multadd_complex_vector_real_scalar(dl_ch_prev,21845,dl_ch_prev+(2*(ue->frame_parms.ofdm_symbol_size)),1,ue->frame_parms.ofdm_symbol_size);
multadd_complex_vector_real_scalar(dl_ch,10923,dl_ch_prev+(2*(ue->frame_parms.ofdm_symbol_size)),0,ue->frame_parms.ofdm_symbol_size);
multadd_complex_vector_real_scalar(dl_ch_prev,10923,dl_ch_prev+(2*((ue->frame_parms.ofdm_symbol_size)<<1)),1,ue->frame_parms.ofdm_symbol_size);
multadd_complex_vector_real_scalar(dl_ch,21845,dl_ch_prev+(2*((ue->frame_parms.ofdm_symbol_size)<<1)),0,ue->frame_parms.ofdm_symbol_size);
} else { // symbol == pilot3
// printf("Interpolating 0->%d\n",4-ue->frame_parms.Ncp);
dl_ch_prev = (int16_t *)&dl_ch_estimates[(p<<1)+aarx][pilot2*(ue->frame_parms.ofdm_symbol_size)];
if (ue->frame_parms.Ncp==0) {// pilot spacing 4 symbols (1/4,1/2,3/4 combination)
multadd_complex_vector_real_scalar(dl_ch_prev,24576,dl_ch_prev+(2*(ue->frame_parms.ofdm_symbol_size)),1,ue->frame_parms.ofdm_symbol_size);
multadd_complex_vector_real_scalar(dl_ch,8192,dl_ch_prev+(2*(ue->frame_parms.ofdm_symbol_size)),0,ue->frame_parms.ofdm_symbol_size);
multadd_complex_vector_real_scalar(dl_ch_prev,16384,dl_ch_prev+(2*((ue->frame_parms.ofdm_symbol_size)<<1)),1,ue->frame_parms.ofdm_symbol_size);
multadd_complex_vector_real_scalar(dl_ch,16384,dl_ch_prev+(2*((ue->frame_parms.ofdm_symbol_size)<<1)),0,ue->frame_parms.ofdm_symbol_size);
multadd_complex_vector_real_scalar(dl_ch_prev,8192,dl_ch_prev+(3*2*(ue->frame_parms.ofdm_symbol_size)),1,ue->frame_parms.ofdm_symbol_size);
multadd_complex_vector_real_scalar(dl_ch,24576,dl_ch_prev+(3*2*(ue->frame_parms.ofdm_symbol_size)),0,ue->frame_parms.ofdm_symbol_size);
} else {
multadd_complex_vector_real_scalar(dl_ch_prev,10923,dl_ch_prev+(2*(ue->frame_parms.ofdm_symbol_size)),1,ue->frame_parms.ofdm_symbol_size);
multadd_complex_vector_real_scalar(dl_ch,21845,dl_ch_prev+(2*(ue->frame_parms.ofdm_symbol_size)),0,ue->frame_parms.ofdm_symbol_size);
multadd_complex_vector_real_scalar(dl_ch_prev,21845,dl_ch_prev+(2*(ue->frame_parms.ofdm_symbol_size)<<1),1,ue->frame_parms.ofdm_symbol_size);
multadd_complex_vector_real_scalar(dl_ch,10923,dl_ch_prev+(2*((ue->frame_parms.ofdm_symbol_size)<<1)),0,ue->frame_parms.ofdm_symbol_size);
} // pilot spacing 3 symbols (1/3,2/3 combination)
if((ue->rx_offset_diff !=0) && ((Ns>>1) == 9))
{
//LOG_I(PHY,"Extrapolate s7-->s11 to get s12 and s13 Ns %d\n", Ns);
interpolateS11S12 = 0;
//LOG_E(PHY,"Interpolate s7--s11 s12 s13 pilot 3 Ns %d l %d symbol %d \n", Ns, l, symbol);
int16_t *dlChEst_ofdm11 = (int16_t *)&dl_ch_estimates[(p<<1)+aarx][pilot3*(ue->frame_parms.ofdm_symbol_size)];
int16_t *dlChEst_ofdm7 = (int16_t *)&dl_ch_estimates[(p<<1)+aarx][pilot2*(ue->frame_parms.ofdm_symbol_size)];
// interpolate ofdm s12: 5/4*ofdms11 + -1/4*ofdms7 5/4 q1.15 40960 -1/4 q1.15 8192
int16_t *dlChEst_ofdm12 = (int16_t *)&dl_ch_estimates[(p<<1)+aarx][12*ue->frame_parms.ofdm_symbol_size];
for(int i=0; i<(2*ue->frame_parms.ofdm_symbol_size); i++)
{
int64_t tmp_mult = 0;
tmp_mult = ((int64_t)dlChEst_ofdm11[i] * 40960 - (int64_t)dlChEst_ofdm7[i] * 8192);
tmp_mult = tmp_mult >> 15;
dlChEst_ofdm12[i] = tmp_mult;
}
// interpolate ofdm s13: 3/2*ofdms11 + -1/2*ofdms7 3/2 q1.15 49152 1/2 q1.15 16384
int16_t *dlChEst_ofdm13 = (int16_t *)&dl_ch_estimates[(p<<1)+aarx][13*ue->frame_parms.ofdm_symbol_size];
for(int i=0; i<(2*ue->frame_parms.ofdm_symbol_size); i++)
{
int64_t tmp_mult = 0;
tmp_mult = ((int64_t)dlChEst_ofdm11[i] * 49152 - (int64_t)dlChEst_ofdm7[i] * 16384);
tmp_mult = tmp_mult >> 15;
dlChEst_ofdm13[i] = tmp_mult;
}
}
if(Ns>>1 == 0)
previous_subframe = 9;
else
previous_subframe = ((Ns>>1) - 1 )%9;
if((subframe_select(&ue->frame_parms,previous_subframe) == SF_UL)) {
multadd_complex_vector_real_scalar(dl_ch_prev,328,dl_ch_prev+(2*(ue->frame_parms.ofdm_symbol_size)),1,ue->frame_parms.ofdm_symbol_size);
multadd_complex_vector_real_scalar(dl_ch,32440,dl_ch_prev+(2*(ue->frame_parms.ofdm_symbol_size)),0,ue->frame_parms.ofdm_symbol_size);
multadd_complex_vector_real_scalar(dl_ch_prev,328,dl_ch_prev+(2*((ue->frame_parms.ofdm_symbol_size)<<1)),1,ue->frame_parms.ofdm_symbol_size);
multadd_complex_vector_real_scalar(dl_ch,32440,dl_ch_prev+(2*((ue->frame_parms.ofdm_symbol_size)<<1)),0,ue->frame_parms.ofdm_symbol_size);
multadd_complex_vector_real_scalar(dl_ch_prev,8192,dl_ch_prev+(3*2*(ue->frame_parms.ofdm_symbol_size)),1,ue->frame_parms.ofdm_symbol_size);
multadd_complex_vector_real_scalar(dl_ch,32440,dl_ch_prev+(3*2*(ue->frame_parms.ofdm_symbol_size)),0,ue->frame_parms.ofdm_symbol_size);
} else {
multadd_complex_vector_real_scalar(dl_ch_prev,24576,dl_ch_prev+(2*(ue->frame_parms.ofdm_symbol_size)),1,ue->frame_parms.ofdm_symbol_size);
multadd_complex_vector_real_scalar(dl_ch,8192,dl_ch_prev+(2*(ue->frame_parms.ofdm_symbol_size)),0,ue->frame_parms.ofdm_symbol_size);
multadd_complex_vector_real_scalar(dl_ch_prev,16384,dl_ch_prev+(2*((ue->frame_parms.ofdm_symbol_size)<<1)),1,ue->frame_parms.ofdm_symbol_size);
multadd_complex_vector_real_scalar(dl_ch,16384,dl_ch_prev+(2*((ue->frame_parms.ofdm_symbol_size)<<1)),0,ue->frame_parms.ofdm_symbol_size);
multadd_complex_vector_real_scalar(dl_ch_prev,8192,dl_ch_prev+(3*2*(ue->frame_parms.ofdm_symbol_size)),1,ue->frame_parms.ofdm_symbol_size);
multadd_complex_vector_real_scalar(dl_ch,24576,dl_ch_prev+(3*2*(ue->frame_parms.ofdm_symbol_size)),0,ue->frame_parms.ofdm_symbol_size);
}
}
} else {
multadd_complex_vector_real_scalar(dl_ch_prev,328,dl_ch_prev+(2*(ue->frame_parms.ofdm_symbol_size)),1,ue->frame_parms.ofdm_symbol_size);
multadd_complex_vector_real_scalar(dl_ch,21845,dl_ch_prev+(2*(ue->frame_parms.ofdm_symbol_size)),0,ue->frame_parms.ofdm_symbol_size);
multadd_complex_vector_real_scalar(dl_ch_prev,21845,dl_ch_prev+(2*(ue->frame_parms.ofdm_symbol_size)<<1),1,ue->frame_parms.ofdm_symbol_size);
multadd_complex_vector_real_scalar(dl_ch,10923,dl_ch_prev+(2*((ue->frame_parms.ofdm_symbol_size)<<1)),0,ue->frame_parms.ofdm_symbol_size);
} // pilot spacing 3 symbols (1/3,2/3 combination)
} else if (symbol == pilot2) {
dl_ch_prev = (int16_t *)&dl_ch_estimates[(p<<1)+aarx][pilot1*(ue->frame_parms.ofdm_symbol_size)];
multadd_complex_vector_real_scalar(dl_ch_prev,21845,dl_ch_prev+(2*(ue->frame_parms.ofdm_symbol_size)),1,ue->frame_parms.ofdm_symbol_size);
multadd_complex_vector_real_scalar(dl_ch,10923,dl_ch_prev+(2*(ue->frame_parms.ofdm_symbol_size)),0,ue->frame_parms.ofdm_symbol_size);
multadd_complex_vector_real_scalar(dl_ch_prev,10923,dl_ch_prev+(2*((ue->frame_parms.ofdm_symbol_size)<<1)),1,ue->frame_parms.ofdm_symbol_size);
multadd_complex_vector_real_scalar(dl_ch,21845,dl_ch_prev+(2*((ue->frame_parms.ofdm_symbol_size)<<1)),0,ue->frame_parms.ofdm_symbol_size);
} else { // symbol == pilot3
// printf("Interpolating 0->%d\n",4-ue->frame_parms.Ncp);
dl_ch_prev = (int16_t *)&dl_ch_estimates[(p<<1)+aarx][pilot2*(ue->frame_parms.ofdm_symbol_size)];
if (ue->frame_parms.Ncp==0) {// pilot spacing 4 symbols (1/4,1/2,3/4 combination)
multadd_complex_vector_real_scalar(dl_ch_prev,24576,dl_ch_prev+(2*(ue->frame_parms.ofdm_symbol_size)),1,ue->frame_parms.ofdm_symbol_size);
multadd_complex_vector_real_scalar(dl_ch,8192,dl_ch_prev+(2*(ue->frame_parms.ofdm_symbol_size)),0,ue->frame_parms.ofdm_symbol_size);
multadd_complex_vector_real_scalar(dl_ch_prev,16384,dl_ch_prev+(2*((ue->frame_parms.ofdm_symbol_size)<<1)),1,ue->frame_parms.ofdm_symbol_size);
multadd_complex_vector_real_scalar(dl_ch,16384,dl_ch_prev+(2*((ue->frame_parms.ofdm_symbol_size)<<1)),0,ue->frame_parms.ofdm_symbol_size);
multadd_complex_vector_real_scalar(dl_ch_prev,8192,dl_ch_prev+(3*2*(ue->frame_parms.ofdm_symbol_size)),1,ue->frame_parms.ofdm_symbol_size);
multadd_complex_vector_real_scalar(dl_ch,24576,dl_ch_prev+(3*2*(ue->frame_parms.ofdm_symbol_size)),0,ue->frame_parms.ofdm_symbol_size);
} else {
multadd_complex_vector_real_scalar(dl_ch_prev,10923,dl_ch_prev+(2*(ue->frame_parms.ofdm_symbol_size)),1,ue->frame_parms.ofdm_symbol_size);
multadd_complex_vector_real_scalar(dl_ch,21845,dl_ch_prev+(2*(ue->frame_parms.ofdm_symbol_size)),0,ue->frame_parms.ofdm_symbol_size);
multadd_complex_vector_real_scalar(dl_ch_prev,21845,dl_ch_prev+(2*(ue->frame_parms.ofdm_symbol_size)<<1),1,ue->frame_parms.ofdm_symbol_size);
multadd_complex_vector_real_scalar(dl_ch,10923,dl_ch_prev+(2*((ue->frame_parms.ofdm_symbol_size)<<1)),0,ue->frame_parms.ofdm_symbol_size);
} // pilot spacing 3 symbols (1/3,2/3 combination)
if((ue->rx_offset_diff !=0) && ((Ns>>1) == 9)) {
//LOG_I(PHY,"Extrapolate s7-->s11 to get s12 and s13 Ns %d\n", Ns);
interpolateS11S12 = 0;
//LOG_E(PHY,"Interpolate s7--s11 s12 s13 pilot 3 Ns %d l %d symbol %d \n", Ns, l, symbol);
int16_t *dlChEst_ofdm11 = (int16_t *)&dl_ch_estimates[(p<<1)+aarx][pilot3*(ue->frame_parms.ofdm_symbol_size)];
int16_t *dlChEst_ofdm7 = (int16_t *)&dl_ch_estimates[(p<<1)+aarx][pilot2*(ue->frame_parms.ofdm_symbol_size)];
// interpolate ofdm s12: 5/4*ofdms11 + -1/4*ofdms7 5/4 q1.15 40960 -1/4 q1.15 8192
int16_t *dlChEst_ofdm12 = (int16_t *)&dl_ch_estimates[(p<<1)+aarx][12*ue->frame_parms.ofdm_symbol_size];
for(int i=0; i<(2*ue->frame_parms.ofdm_symbol_size); i++) {
int64_t tmp_mult = 0;
tmp_mult = ((int64_t)dlChEst_ofdm11[i] * 40960 - (int64_t)dlChEst_ofdm7[i] * 8192);
tmp_mult = tmp_mult >> 15;
dlChEst_ofdm12[i] = tmp_mult;
}
// interpolate ofdm s13: 3/2*ofdms11 + -1/2*ofdms7 3/2 q1.15 49152 1/2 q1.15 16384
int16_t *dlChEst_ofdm13 = (int16_t *)&dl_ch_estimates[(p<<1)+aarx][13*ue->frame_parms.ofdm_symbol_size];
for(int i=0; i<(2*ue->frame_parms.ofdm_symbol_size); i++) {
int64_t tmp_mult = 0;
tmp_mult = ((int64_t)dlChEst_ofdm11[i] * 49152 - (int64_t)dlChEst_ofdm7[i] * 16384);
tmp_mult = tmp_mult >> 15;
dlChEst_ofdm13[i] = tmp_mult;
}
}
}
}
}
}
void (*idft)(int16_t *,int16_t *, int);
switch (ue->frame_parms.ofdm_symbol_size) {
case 128:
idft = idft128;
break;
case 128:
idft = idft128;
break;
case 256:
idft = idft256;
break;
case 256:
idft = idft256;
break;
case 512:
idft = idft512;
break;
case 512:
idft = idft512;
break;
case 1024:
idft = idft1024;
break;
case 1024:
idft = idft1024;
break;
case 1536:
idft = idft1536;
break;
case 1536:
idft = idft1536;
break;
case 2048:
idft = idft2048;
break;
case 2048:
idft = idft2048;
break;
default:
idft = idft512;
break;
default:
idft = idft512;
break;
}
if( ((Ns%2) == 0) && (l == pilot0))
{
// do ifft of channel estimate
for (aarx=0; aarx<ue->frame_parms.nb_antennas_rx; aarx++)
for (p=0; p<ue->frame_parms.nb_antenna_ports_eNB; p++) {
if (ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[Ns>>1]].dl_ch_estimates[eNB_offset][(p<<1)+aarx])
{
//LOG_I(PHY,"Channel Impulse Computation Slot %d ThreadId %d Symbol %d \n", Ns, ue->current_thread_id[Ns>>1], l);
idft((int16_t*) &ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[Ns>>1]].dl_ch_estimates[eNB_offset][(p<<1)+aarx][8],
(int16_t*) ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[Ns>>1]].dl_ch_estimates_time[eNB_offset][(p<<1)+aarx],1);
}
}
if( ((Ns%2) == 0) && (l == pilot0)) {
// do ifft of channel estimate
for (aarx=0; aarx<ue->frame_parms.nb_antennas_rx; aarx++)
for (p=0; p<ue->frame_parms.nb_antenna_ports_eNB; p++) {
if (ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[Ns>>1]].dl_ch_estimates[eNB_offset][(p<<1)+aarx]) {
//LOG_I(PHY,"Channel Impulse Computation Slot %d ThreadId %d Symbol %d \n", Ns, ue->current_thread_id[Ns>>1], l);
idft((int16_t *) &ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[Ns>>1]].dl_ch_estimates[eNB_offset][(p<<1)+aarx][8],
(int16_t *) ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[Ns>>1]].dl_ch_estimates_time[eNB_offset][(p<<1)+aarx],1);
}
}
}
T(T_UE_PHY_DL_CHANNEL_ESTIMATE, T_INT(eNB_id),
T_INT(ue->proc.proc_rxtx[ue->current_thread_id[Ns>>1]].frame_rx%1024), T_INT(ue->proc.proc_rxtx[ue->current_thread_id[Ns>>1]].subframe_rx),
T_INT(0), T_BUFFER(&ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[Ns>>1]].dl_ch_estimates_time[eNB_offset][0][0], 512 * 4));
return(0);
}
File diff suppressed because it is too large Load Diff
+7
View File
@@ -204,6 +204,12 @@ typedef struct {
/// condition variable for timer_thread;
pthread_cond_t cond_ticking;
//time_stats_t timer_stats;
// below 3 members is used for waiting each UE threads(multiple UEs test) in L2 FAPI simulator.
// This used in UE_phy_stub_single_thread_rxn_txnp4
pthread_mutex_t mutex_single_thread;
pthread_cond_t cond_single_thread;
int num_single_thread[NUMBER_OF_UE_MAX];
} SF_ticking;
typedef struct {
@@ -890,6 +896,7 @@ typedef struct {
struct rx_tx_thread_data {
PHY_VARS_UE *UE;
UE_rxtx_proc_t *proc;
uint16_t ue_thread_id;
};
+19 -9
View File
@@ -1,15 +1,20 @@
This folder contains the software for the device driver of CBMIMO1 and the physical layer signal processing.
This folder contains the software for layer 1 of the OpenAirInterface eNB and UE as well as the unitary simulators
|-- PHY // contains all signal processing related to physical layer (used in real-time AND simulation)
General remarks: every directory contains at least defs.h (for declaration of structure and functions), vars.h (for definitions of variables), and extern.h (variables are defined only once in cbmimo1_device.c (for real-time HW operation) or a top-level simulation (in SIMULATION/xxx), if variables are needed in another file, use extern.h)
General remarks: every directory contains at least defs.h (for declaration of structure and functions), vars.h (for definitions of variables), and extern.h (variables are defined only once in xxx-softmodem.c (for real-time HW operation) or a top-level simulation (in SIMULATION/xxx), if variables are needed in another file, use extern.h)
| |-- CODING // turbo and convolutional (de-)coders, rate-matching, crc generation (implementation of 36-212)
| | `-- TESTBENCH // This contains unitary testbenches for the different channel coders/decoders
| |-- INIT // variables defined in vars.h are initialzed here (memory allocation)
| |-- LTE_ESTIMATION // estimation for LTE
| |-- LTE_REFSIG // reference signals for LTE (sync and pilot sequences) reference signals from 36-211
| |-- NR_REFSIG // reference signals for NR (sync and pilot sequences) reference signals from 38-211
| |-- LTE_TRANSPORT // these are the top level routines for different transport and physical channels (for example DL-SCH, PSS) implements a subset of 36-211,36-212
| |-- LTE_UE_TRANSPORT // these are the top level routines for different transport and physical channels (for example DL-SCH, PSS) implements a subset of 36-211,36-212
| |-- NR_TRANSPORT // these are the top level routines for different transport and physical channels (for example DL-SCH, PSS) implements a subset of 38-211,38-212
| |-- NR_UE_TRANSPORT // these are the top level routines for different transport and physical channels (for example DL-SCH, PSS) implements a subset of 38-211,38-212
| |-- NBIoT_TRANSPORT // these are the top level routines for different transport and physical channels for NB-IoT
| |-- MODULATION // modulation and demodulation includes FFT/SC-FDMA front-end processing from 36-211
| |-- TOOLS // tools like (I)FFT, vector operations, matrix multiplication, etc.
| | `-- FFTTEST // unitary testbench for FFT routines
@@ -22,20 +27,25 @@ General remarks: every directory contains at least defs.h (for declaration of st
| |-- spec_defs_top.h
| |-- types.h
| `-- vars.h
|-- SCHED // schedules the different PHY functions according to the nodes role
|-- SCHED // schedules the different LTE eNB functions
| |-- defs.h
| |-- extern.h
| |-- phy_procedures_emos.c // non-LTE PHY procedures for EMOS
| |-- phy_procedures_emos.h
| |-- phy_procedures_lte_eNb.c // LTE PHY procedures for eNB (from 36-213)
| |-- phy_procedures_lte_ue.c // LTE PHY procedures for UE (from 36-213)
| |-- phy_procedures_lte_common.c // LTE PHY procedures common for UE and eNB (from 36-213)
| |-- prach_procedures.c //LTE PRACH procedures (from 36-213)
| |-- ru_procedures.c //RU procedures
| |-- fapi_l1.c //L1 side of the FAPI interface
| |-- phy_mac_stub.c //MAC stub that generates channels when used in phy-test-mode
| |-- rt_compat.h
| `-- vars.h
|-- SCHED_UE // schedules the different LTE UE functions
| |-- phy_procedures_lte_ue.c // LTE PHY procedures for UE (from 36-213)
| |-- pucch_pc.c // power control for PUCCH
| |-- pusch_pc.c // power control for PUSCH
| |-- srs_pc.c // power control for SRS
| |-- rt_compat.h
| `-- vars.h
|-- SCHED_NB_IOT // same as above for NB-IOT
|-- SCHED_NR // same as above for NR gNB
|-- SCHED_NR_UE // same as above for NR UE
|-- SIMULATION // contains simulation routines to test PHY
| |-- LTE_PHY // LTE simulation testbenches for unitary simulation of transport/physical channels
| | |-- pbchsim.c // PBCH simulation testbench
@@ -43,7 +53,7 @@ General remarks: every directory contains at least defs.h (for declaration of st
| | |-- dlsim.c // PDSCH simulation testbench
| | |-- ulsim.c // PUSCH simulation testbench
| | |-- pucchsim.c // PUCCH simulation testbench
| |-- RF
| |-- RF // RF simulation tools
| |-- ETH_TRANSPORT
| `-- TOOLS
+11
View File
@@ -64,6 +64,16 @@
# define MAX_MODULES NB_MODULES_MAX
#ifndef UE_EXPANSION
// TODO:L2 FAPI simulator.
// UESIM_EXPANSION is used to be same value of MAX_MOBILES_PER_ENB
// in eNB and UE.
// now , if we use --mu option in UE, compiling error will occur.
// This problem will be fixed in the future.
# ifdef UESIM_EXPANSION
# define MAX_MOBILES_PER_ENB 256
# define MAX_MOBILES_PER_ENB_NB_IoT 256
# define MAX_eNB 2
# else
# ifdef LARGE_SCALE
# define MAX_MOBILES_PER_ENB 128
# define MAX_MOBILES_PER_ENB_NB_IoT 128
@@ -73,6 +83,7 @@
# define MAX_MOBILES_PER_ENB_NB_IoT 16
# define MAX_eNB 2
# endif
#endif
#else
# define MAX_MOBILES_PER_ENB 256
# define MAX_MOBILES_PER_ENB_NB_IoT 256
-12
View File
@@ -25,18 +25,11 @@ TASK_DEF(TASK_TIMER, TASK_PRIORITY_MAX, 10)
// Other possible tasks in the process
// Common tasks:
/// Layer 2 and Layer 1 task supporting all the synchronous processing
TASK_DEF(TASK_L2L1, TASK_PRIORITY_MAX_LEAST, 200)
/// Bearers Manager task
TASK_DEF(TASK_BM, TASK_PRIORITY_MED, 200)
// eNodeB tasks and sub-tasks:
//// Layer 2 and Layer 1 sub-tasks
SUB_TASK_DEF(TASK_L2L1, TASK_PHY_ENB, 200)
SUB_TASK_DEF(TASK_L2L1, TASK_MAC_ENB, 200)
SUB_TASK_DEF(TASK_L2L1, TASK_RLC_ENB, 200)
SUB_TASK_DEF(TASK_L2L1, TASK_PDCP_ENB, 200)
/// Radio Resource Control task
TASK_DEF(TASK_RRC_ENB, TASK_PRIORITY_MED, 200)
@@ -63,11 +56,6 @@ TASK_DEF(TASK_ENB_APP, TASK_PRIORITY_MED, 200)
TASK_DEF(TASK_FLEXRAN_AGENT, TASK_PRIORITY_MED, 200)
// UE tasks and sub-tasks:
//// Layer 2 and Layer 1 sub-tasks
SUB_TASK_DEF(TASK_L2L1, TASK_PHY_UE, 200)
SUB_TASK_DEF(TASK_L2L1, TASK_MAC_UE, 200)
SUB_TASK_DEF(TASK_L2L1, TASK_RLC_UE, 200)
SUB_TASK_DEF(TASK_L2L1, TASK_PDCP_UE, 200)
/// Radio Resource Control task
TASK_DEF(TASK_RRC_UE, TASK_PRIORITY_MED, 200)
+5 -1
View File
@@ -375,14 +375,16 @@ void flexran_update_TA(mid_t mod_id, mid_t ue_id, uint8_t cc_id)
ue_sched_ctl->ta_timer--;
ue_sched_ctl->ta_update = 0; // don't trigger a timing advance command
}
*/
#warning "Implement flexran_update_TA() in RAN API"
*/
}
/* TODO needs to be revised, looks suspicious: why do we need UE stats? */
int flexran_get_MAC_CE_bitmap_TA(mid_t mod_id, mid_t ue_id, uint8_t cc_id)
{
/*
#warning "Implement flexran_get_MAC_CE_bitmap_TA() in RAN API"
*/
if (!phy_is_present(mod_id, cc_id)) return 0;
/* UE_stats can not be null, they are an array in RC
@@ -476,7 +478,9 @@ int flexran_get_harq(mid_t mod_id,
/* *status = 0; */
/* } */
/*return *round;*/
/*
#warning "Implement flexran_get_harq() in RAN API"
*/
return 0;
}
+1 -1
View File
@@ -1426,7 +1426,7 @@ schedule_RA(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP)
if (ra->state == MSG2)
generate_Msg2(module_idP, CC_id, frameP, subframeP, ra);
else if (ra->state == MSG4 && ra->Msg4_frame == frameP && ra->Msg4_subframe == subframeP )
else if (ra->state == MSG4 && ra->Msg4_frame == frameP && ra->Msg4_subframe == subframeP )
generate_Msg4(module_idP, CC_id, frameP, subframeP, ra);
else if (ra->state == WAITMSG4ACK)
check_Msg4_retransmission(module_idP, CC_id, frameP,
@@ -594,6 +594,7 @@ void dlsch_scheduler_pre_processor_fairRR (module_id_t Mod_id,
LTE_eNB_UE_stats *eNB_UE_stats2 = NULL;
UE_sched_ctrl *ue_sched_ctl1, *ue_sched_ctl2;
#endif
memset(rballoc_sub[0],0,(MAX_NUM_CCs)*(N_RBG_MAX)*sizeof(unsigned char));
memset(min_rb_unit,0,sizeof(min_rb_unit));
for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
+15 -3
View File
@@ -61,6 +61,7 @@ extern uint16_t frame_cnt;
#include "SCHED/sched_common.h"
extern RAN_CONTEXT_t RC;
extern uint8_t nfapi_mode;
int choose(int n, int k)
{
@@ -1286,6 +1287,7 @@ fill_nfapi_ulsch_harq_information(module_id_t module_
*/
#endif
harq_information->harq_information_rel10.delta_offset_harq = puschConfigDedicated->betaOffset_ACK_Index;
harq_information->harq_information_rel10.tl.tag = NFAPI_UL_CONFIG_REQUEST_ULSCH_HARQ_INFORMATION_REL10_TAG;
AssertFatal(UE_list->UE_template[CC_idP][UE_id].physicalConfigDedicated->pucch_ConfigDedicated != NULL,
"pucch_ConfigDedicated is null!\n");
if ((UE_list->UE_template[CC_idP][UE_id].physicalConfigDedicated->pucch_ConfigDedicated->tdd_AckNackFeedbackMode != NULL)
@@ -3629,9 +3631,19 @@ extract_harq(module_id_t mod_idP, int CC_idP, int UE_id,
AssertFatal(num_ack_nak == 1,
"num_ack_nak %d > 1 for 1 CC and single-layer transmission frame:%d subframe:%d\n",
num_ack_nak,frameP,subframeP);
AssertFatal(sched_ctl->round[CC_idP][harq_pid] < 8,
"Got ACK/NAK for inactive harq_pid %d for UE %d/%x\n",
harq_pid, UE_id, rnti);
// In case of nFAPI, sometimes timing of eNB and UE become different.
// So if nfapi_mode == 2(VNF) , this function don't check assertion to avoid process exit.
if (nfapi_mode != 2){
AssertFatal(sched_ctl->round[CC_idP][harq_pid] < 8,
"Got ACK/NAK for inactive harq_pid %d for UE %d/%x\n",
harq_pid, UE_id, rnti);
} else {
if(sched_ctl->round[CC_idP][harq_pid] == 8){
LOG_E(MAC,"Got ACK/NAK for inactive harq_pid %d for UE %d/%x\n",harq_pid, UE_id, rnti);
return;
}
}
AssertFatal(pdu[0] == 1 || pdu[0] == 2
|| pdu[0] == 4,
"Received ACK/NAK %d which is not 1 or 2 for harq_pid %d from UE %d/%x\n",
+2 -1
View File
@@ -64,7 +64,8 @@ extern eNB_DLSCH_INFO eNB_dlsch_info[NUMBER_OF_eNB_MAX][MAX_NUM_CCs][MAX_MOBILES
extern unsigned char NB_INST;
#endif
extern unsigned char NB_eNB_INST;
extern unsigned char NB_UE_INST;
extern uint16_t NB_UE_INST;
extern uint16_t NB_THREAD_INST;
extern unsigned char NB_RN_INST;
extern unsigned short NODE_ID[1];
+3 -2
View File
@@ -95,7 +95,7 @@ const uint8_t cqi2fmt2x_agg[MAX_SUPPORTED_BW][CQI_VALUE_RANGE] = {
uint32_t RRC_CONNECTION_FLAG;
UE_MAC_INST *UE_mac_inst; //[NB_MODULE_MAX];
UE_MAC_INST *UE_mac_inst = NULL; //[NB_MODULE_MAX];
MAC_RLC_XFACE *Mac_rlc_xface;
/// Primary component carrier index of eNB
@@ -109,7 +109,8 @@ eNB_DLSCH_INFO eNB_dlsch_info[NUMBER_OF_eNB_MAX][MAX_NUM_CCs][MAX_MOBILES_PER_EN
#ifdef OPENAIR2
unsigned char NB_eNB_INST = 0;
unsigned char NB_UE_INST = 0;
uint16_t NB_UE_INST = 0;
uint16_t NB_THREAD_INST = 0;
unsigned char NB_RN_INST = 0;
unsigned char NB_INST = 0;
#endif
+11 -1
View File
@@ -43,7 +43,8 @@
#include "common/ran_context.h"
extern FILL_UL_INFO_MUTEX_t fill_ul_mutex;
extern uint8_t nfapi_mode;
extern void openair_rrc_top_init_ue( int eMBMS_active, char* uecap_xer, uint8_t cba_group_active, uint8_t HO_active);
void dl_phy_sync_success(module_id_t module_idP, frame_t frameP, unsigned char eNB_index, uint8_t first_sync) //init as MR
@@ -103,6 +104,15 @@ mac_top_init_ue(int eMBMS_active, char *uecap_xer,
UE_mac_inst = NULL;
}
// mutex below are used for multiple UE's L2 FAPI simulation.
if (nfapi_mode == 3){
pthread_mutex_init(&fill_ul_mutex.rx_mutex,NULL);
pthread_mutex_init(&fill_ul_mutex.crc_mutex,NULL);
pthread_mutex_init(&fill_ul_mutex.sr_mutex,NULL);
pthread_mutex_init(&fill_ul_mutex.harq_mutex,NULL);
pthread_mutex_init(&fill_ul_mutex.cqi_mutex,NULL);
pthread_mutex_init(&fill_ul_mutex.rach_mutex,NULL);
}
LOG_I(MAC, "[MAIN] calling RRC\n");
openair_rrc_top_init_ue(eMBMS_active, uecap_xer, cba_group_active,
+33 -25
View File
@@ -69,6 +69,8 @@
extern UL_IND_t *UL_INFO;
extern uint8_t nfapi_mode;
extern int next_ra_frame;
extern module_id_t next_Mod_id;
/*
*
@@ -2523,44 +2525,50 @@ ue_scheduler(const module_id_t module_idP,
UE_mac_inst[module_idP].crnti, txFrameP,
txSubframeP, eNB_indexP);
#if defined(ENABLE_ITTI)
if(module_idP == 0){
do {
// Checks if a message has been sent to MAC sub-task
itti_poll_msg(TASK_MAC_UE, &msg_p);
do {
// Checks if a message has been sent to MAC sub-task
itti_poll_msg(TASK_MAC_UE, &msg_p);
if (msg_p != NULL) {
if (msg_p != NULL) {
switch (ITTI_MSG_ID(msg_p)) {
case RRC_MAC_CCCH_DATA_REQ:
LOG_I(MAC,
"Received %s from %s: instance %d, frameP %d, eNB_index %d\n",
ITTI_MSG_NAME(msg_p), ITTI_MSG_ORIGIN_NAME(msg_p), ITTI_MSG_INSTANCE(msg_p),
RRC_MAC_CCCH_DATA_REQ(msg_p).frame,
RRC_MAC_CCCH_DATA_REQ(msg_p).enb_index);
switch (ITTI_MSG_ID(msg_p)) {
case RRC_MAC_CCCH_DATA_REQ:
LOG_I(MAC,
"Received %s from %s: instance %d, frameP %d, eNB_index %d\n",
ITTI_MSG_NAME(msg_p), ITTI_MSG_ORIGIN_NAME(msg_p), ITTI_MSG_INSTANCE(msg_p),
RRC_MAC_CCCH_DATA_REQ(msg_p).frame,
RRC_MAC_CCCH_DATA_REQ(msg_p).enb_index);
// TODO process CCCH data req.
break;
// TODO process CCCH data req.
break;
default:
LOG_E(MAC, "Received unexpected message %s\n", ITTI_MSG_NAME(msg_p));
break;
default:
LOG_E(MAC, "Received unexpected message %s\n", ITTI_MSG_NAME(msg_p));
break;
}
result = itti_free(ITTI_MSG_ORIGIN_ID(msg_p), msg_p);
AssertFatal(result == EXIT_SUCCESS,
"Failed to free memory (%d)!\n", result);
}
result = itti_free(ITTI_MSG_ORIGIN_ID(msg_p), msg_p);
AssertFatal(result == EXIT_SUCCESS,
"Failed to free memory (%d)!\n", result);
}
}
}
while (msg_p != NULL);
}
#endif
//Mac_rlc_xface->frameP=frameP;
//Rrc_xface->Frame_index=Mac_rlc_xface->frameP;
//if (subframe%5 == 0)
//LG#ifdef EXMIMO
pdcp_run(&ctxt);
// data to/from NETLINK is treated in pdcp_run.
// one socket is used in multiple UE's L2 FAPI simulator and
// only first UE need to do this.
if(module_idP == 0){
pdcp_run(&ctxt);
}
//#endif
UE_mac_inst[module_idP].txFrame = txFrameP;
UE_mac_inst[module_idP].txSubframe = txSubframeP;
+17 -5
View File
@@ -49,7 +49,7 @@
#include "platform_constants.h"
#include "common/utils/LOG/vcd_signal_dumper.h"
#include "msc.h"
#include "targets/COMMON/openairinterface5g_limits.h"
#if defined(ENABLE_SECURITY)
# include "UTIL/OSA/osa_defs.h"
#endif
@@ -64,9 +64,12 @@
#endif
extern int otg_enabled;
#if defined(ENABLE_USE_MME)
extern uint8_t nfapi_mode;
#endif
#include "common/ran_context.h"
extern RAN_CONTEXT_t RC;
hash_table_t *pdcp_coll_p = NULL;
#ifdef MBMS_MULTICAST_OUT
# include <sys/types.h>
@@ -798,12 +801,21 @@ pdcp_data_ind(
* for the UE compiled in noS1 mode, we need 0
* TODO: be sure of this
*/
((pdcp_data_ind_header_t*) new_sdu_p->data)->inst = 1;
if (nfapi_mode == 3) {
#ifdef UESIM_EXPANSION
((pdcp_data_ind_header_t*) new_sdu_p->data)->inst = 0;
#else
((pdcp_data_ind_header_t*) new_sdu_p->data)->inst = ctxt_pP->module_id;
#endif
} else {
((pdcp_data_ind_header_t*) new_sdu_p->data)->inst = 1;
}
#endif
} else {
((pdcp_data_ind_header_t*) new_sdu_p->data)->rb_id = rb_id + (ctxt_pP->module_id * LTE_maxDRB);
((pdcp_data_ind_header_t*) new_sdu_p->data)->inst = ctxt_pP->module_id;
}
// new_sdu_p->data->inst is set again in UE case so move to above.
//Panos: Commented this out because it cancels the assignment in #if defined(ENABLE_USE_MME) case
//((pdcp_data_ind_header_t*) new_sdu_p->data)->inst = ctxt_pP->module_id;
@@ -2021,7 +2033,7 @@ void pdcp_layer_init(void)
* Initialize SDU list
*/
list_init(&pdcp_sdu_list, NULL);
pdcp_coll_p = hashtable_create ((LTE_maxDRB + 2) * 16, NULL, pdcp_free);
pdcp_coll_p = hashtable_create ((LTE_maxDRB + 2) * NUMBER_OF_UE_MAX, NULL, pdcp_free);
AssertFatal(pdcp_coll_p != NULL, "UNRECOVERABLE error, PDCP hashtable_create failed");
for (instance = 0; instance < MAX_MOBILES_PER_ENB; instance++) {
+1 -1
View File
@@ -542,7 +542,7 @@ sdu_size_t pdcp_input_sdu_remaining_size_to_read;
(((hash_key_t)(sESSION_ID)) << 37) | \
(((hash_key_t)(0x0000000000000001)) << 63))
hash_table_t *pdcp_coll_p;
extern hash_table_t *pdcp_coll_p;
#endif
/*@}*/
+53 -5
View File
@@ -82,10 +82,13 @@ extern struct msghdr nas_msg_tx;
extern struct msghdr nas_msg_rx;
unsigned char pdcp_read_state_g = 0;
extern uint8_t nfapi_mode;
#ifdef UESIM_EXPANSION
extern uint16_t inst_pdcp_list[NUMBER_OF_UE_MAX];
#endif
#endif
extern Packet_OTG_List_t *otg_pdcp_buffer;
#if defined(LINK_ENB_PDCP_TO_GTPV1U)
# include "gtpv1u_eNB_task.h"
# include "gtpv1u_eNB_defs.h"
@@ -168,7 +171,12 @@ int pdcp_fifo_flush_sdus(const protocol_ctxt_t* const ctxt_pP)
((pdcp_data_ind_header_t*) sdu_p->data)->inst,
((pdcp_data_ind_header_t *) sdu_p->data)->data_size);
#else
//((pdcp_data_ind_header_t *)(sdu_p->data))->inst = 0;
// Raphael: was suppressed by Raymond --> should be suppressed?
// value of sdu_p->data->inst is set in pdcp_data_ind
// it's necessary to set 1 in case of UE with S1.
//if (ctxt_pP->enb_flag){
// ((pdcp_data_ind_header_t *)(sdu_p->data))->inst = 0;
//}
#endif
#if defined(LINK_ENB_PDCP_TO_GTPV1U)
@@ -927,7 +935,15 @@ int pdcp_fifo_read_input_sdus (const protocol_ctxt_t* const ctxt_pP)
rab_id = pdcp_read_header_g.rb_id % LTE_maxDRB;
ctxt.rnti = pdcp_eNB_UE_instance_to_rnti[pdcp_read_header_g.rb_id / LTE_maxDRB];
} else {
ctxt.module_id = 0;
if (nfapi_mode == 3) {
#ifdef UESIM_EXPANSION
ctxt.module_id = inst_pdcp_list[pdcp_read_header_g.inst];
#else
ctxt.module_id = pdcp_read_header_g.inst;
#endif
} else {
ctxt.module_id = 0;
}
rab_id = pdcp_read_header_g.rb_id % LTE_maxDRB;
ctxt.rnti = pdcp_UE_UE_module_id_to_rnti[ctxt.module_id];
}
@@ -1072,7 +1088,22 @@ int pdcp_fifo_read_input_sdus (const protocol_ctxt_t* const ctxt_pP)
pdcp_read_header_g.rb_id,
rab_id,
pdcp_read_header_g.data_size);
if(nfapi_mode == 3){
pdcp_data_req(
&ctxt,
SRB_FLAG_NO,
rab_id,
RLC_MUI_UNDEFINED,
RLC_SDU_CONFIRM_NO,
pdcp_read_header_g.data_size,
(unsigned char *)NLMSG_DATA(nas_nlh_rx),
PDCP_TRANSMISSION_MODE_DATA
#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
,NULL
,NULL
#endif
);
}else{
pdcp_data_req(
&ctxt,
SRB_FLAG_NO,
@@ -1087,6 +1118,7 @@ int pdcp_fifo_read_input_sdus (const protocol_ctxt_t* const ctxt_pP)
,&pdcp_read_header_g.destinationL2Id
#endif
);
}
} else {
MSC_LOG_RX_DISCARDED_MESSAGE(
(ctxt_pP->enb_flag == ENB_FLAG_YES) ? MSC_PDCP_ENB:MSC_PDCP_UE,
@@ -1130,7 +1162,22 @@ int pdcp_fifo_read_input_sdus (const protocol_ctxt_t* const ctxt_pP)
pdcp_read_header_g.rb_id,
DEFAULT_RAB_ID,
pdcp_read_header_g.data_size);
if(nfapi_mode == 3){
pdcp_data_req (
&ctxt,
SRB_FLAG_NO,
DEFAULT_RAB_ID,
RLC_MUI_UNDEFINED,
RLC_SDU_CONFIRM_NO,
pdcp_read_header_g.data_size,
(unsigned char *)NLMSG_DATA(nas_nlh_rx),
PDCP_TRANSMISSION_MODE_DATA
#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
,NULL
,NULL
#endif
);
}else{
pdcp_data_req (
&ctxt,
SRB_FLAG_NO,
@@ -1145,6 +1192,7 @@ int pdcp_fifo_read_input_sdus (const protocol_ctxt_t* const ctxt_pP)
,&pdcp_read_header_g.destinationL2Id
#endif
);
}
}
}
File diff suppressed because it is too large Load Diff
+199 -226
View File
@@ -23,9 +23,7 @@
#define RLC_AM_REASSEMBLY_C 1
#include "platform_types.h"
//-----------------------------------------------------------------------------
#if ENABLE_ITTI
# include "intertask_interface.h"
#endif
#include "assertions.h"
#include "rlc.h"
#include "rlc_am.h"
@@ -37,19 +35,17 @@
//-----------------------------------------------------------------------------
inline void
rlc_am_clear_rx_sdu (
const protocol_ctxt_t* const ctxt_pP,
rlc_am_entity_t * const rlc_pP)
{
const protocol_ctxt_t *const ctxt_pP,
rlc_am_entity_t *const rlc_pP) {
rlc_pP->output_sdu_size_to_write = 0;
}
//-----------------------------------------------------------------------------
void
rlc_am_reassembly (
const protocol_ctxt_t* const ctxt_pP,
rlc_am_entity_t * const rlc_pP,
uint8_t * src_pP,
const int32_t lengthP)
{
const protocol_ctxt_t *const ctxt_pP,
rlc_am_entity_t *const rlc_pP,
uint8_t *src_pP,
const int32_t lengthP) {
LOG_D(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[REASSEMBLY PAYLOAD] reassembly() %d bytes\n",
PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP),
lengthP);
@@ -57,6 +53,7 @@ rlc_am_reassembly (
if (rlc_pP->output_sdu_in_construction == NULL) {
rlc_pP->output_sdu_in_construction = get_free_mem_block (RLC_SDU_MAX_SIZE, __func__);
rlc_pP->output_sdu_size_to_write = 0;
//assert(rlc_pP->output_sdu_in_construction != NULL);
if(rlc_pP->output_sdu_in_construction == NULL) {
LOG_E(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[REASSEMBLY PAYLOAD] output_sdu_in_construction is NULL\n",
@@ -66,7 +63,6 @@ rlc_am_reassembly (
}
if (rlc_pP->output_sdu_in_construction != NULL) {
// check if no overflow in size
if ((rlc_pP->output_sdu_size_to_write + lengthP) <= RLC_SDU_MAX_SIZE) {
memcpy (&rlc_pP->output_sdu_in_construction->data[rlc_pP->output_sdu_size_to_write], src_pP, lengthP);
@@ -93,18 +89,8 @@ rlc_am_reassembly (
//-----------------------------------------------------------------------------
void
rlc_am_send_sdu (
const protocol_ctxt_t* const ctxt_pP,
rlc_am_entity_t * const rlc_pP)
{
# if TRACE_RLC_AM_PDU
char message_string[7000];
size_t message_string_size = 0;
#if ENABLE_ITTI
MessageDef *msg_p;
#endif
int octet_index, index;
#endif
const protocol_ctxt_t *const ctxt_pP,
rlc_am_entity_t *const rlc_pP) {
if ((rlc_pP->output_sdu_in_construction)) {
LOG_D(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[SEND_SDU] %d bytes sdu %p\n",
PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP),
@@ -120,73 +106,62 @@ rlc_am_send_sdu (
rlc_pP->output_sdu_size_to_write,
rlc_pP->output_sdu_in_construction);
#else
# if TRACE_RLC_AM_PDU
message_string_size += sprintf(&message_string[message_string_size], "Bearer : %u\n", rlc_pP->rb_id);
message_string_size += sprintf(&message_string[message_string_size], "SDU size : %u\n", rlc_pP->output_sdu_size_to_write);
message_string_size += sprintf(&message_string[message_string_size], "\nPayload : \n");
message_string_size += sprintf(&message_string[message_string_size], "------+-------------------------------------------------|\n");
message_string_size += sprintf(&message_string[message_string_size], " | 0 1 2 3 4 5 6 7 8 9 a b c d e f |\n");
message_string_size += sprintf(&message_string[message_string_size], "------+-------------------------------------------------|\n");
if ( LOG_DEBUGFLAG(DEBUG_RLC)) {
char message_string[7000];
size_t message_string_size = 0;
int octet_index, index;
message_string_size += sprintf(&message_string[message_string_size], "Bearer : %u\n", rlc_pP->rb_id);
message_string_size += sprintf(&message_string[message_string_size], "SDU size : %u\n", rlc_pP->output_sdu_size_to_write);
message_string_size += sprintf(&message_string[message_string_size], "\nPayload : \n");
message_string_size += sprintf(&message_string[message_string_size], "------+-------------------------------------------------|\n");
message_string_size += sprintf(&message_string[message_string_size], " | 0 1 2 3 4 5 6 7 8 9 a b c d e f |\n");
message_string_size += sprintf(&message_string[message_string_size], "------+-------------------------------------------------|\n");
for (octet_index = 0; octet_index < rlc_pP->output_sdu_size_to_write; octet_index++) {
if ((octet_index % 16) == 0) {
if (octet_index != 0) {
message_string_size += sprintf(&message_string[message_string_size], " |\n");
for (octet_index = 0; octet_index < rlc_pP->output_sdu_size_to_write; octet_index++) {
if ((octet_index % 16) == 0) {
if (octet_index != 0) {
message_string_size += sprintf(&message_string[message_string_size], " |\n");
}
message_string_size += sprintf(&message_string[message_string_size], " %04d |", octet_index);
}
message_string_size += sprintf(&message_string[message_string_size], " %04d |", octet_index);
/*
* Print every single octet in hexadecimal form
*/
message_string_size += sprintf(&message_string[message_string_size],
" %02x",
rlc_pP->output_sdu_in_construction->data[octet_index]);
/*
* Align newline and pipes according to the octets in groups of 2
*/
}
/*
* Print every single octet in hexadecimal form
*/
message_string_size += sprintf(&message_string[message_string_size],
" %02x",
rlc_pP->output_sdu_in_construction->data[octet_index]);
/*
* Align newline and pipes according to the octets in groups of 2
* Append enough spaces and put final pipe
*/
for (index = octet_index; index < 16; ++index) {
message_string_size += sprintf(&message_string[message_string_size], " ");
}
message_string_size += sprintf(&message_string[message_string_size], " |\n");
LOG_T(RLC, "%s", message_string);
}
/*
* Append enough spaces and put final pipe
*/
for (index = octet_index; index < 16; ++index) {
message_string_size += sprintf(&message_string[message_string_size], " ");
}
message_string_size += sprintf(&message_string[message_string_size], " |\n");
# if ENABLE_ITTI
msg_p = itti_alloc_new_message_sized (ctxt_pP->enb_flag > 0 ? TASK_RLC_ENB:TASK_RLC_UE ,
RLC_AM_SDU_IND,
message_string_size + sizeof (IttiMsgText));
msg_p->ittiMsg.rlc_am_sdu_ind.size = message_string_size;
memcpy(&msg_p->ittiMsg.rlc_am_sdu_ind.text, message_string, message_string_size);
itti_send_msg_to_task(TASK_UNKNOWN, ctxt_pP->instance, msg_p);
# else
LOG_T(RLC, "%s", message_string);
# endif
# endif
#if !ENABLE_ITTI
RLC_AM_MUTEX_UNLOCK(&rlc_pP->lock_input_sdus);
#endif
MSC_LOG_TX_MESSAGE(
(ctxt_pP->enb_flag == ENB_FLAG_YES) ? MSC_RLC_ENB:MSC_RLC_UE,
(ctxt_pP->enb_flag == ENB_FLAG_YES) ? MSC_PDCP_ENB:MSC_PDCP_UE,
(const char*)(rlc_pP->output_sdu_in_construction->data),
(const char *)(rlc_pP->output_sdu_in_construction->data),
rlc_pP->output_sdu_size_to_write,
MSC_AS_TIME_FMT" "PROTOCOL_RLC_AM_MSC_FMT" DATA-IND size %u",
MSC_AS_TIME_ARGS(ctxt_pP),
PROTOCOL_RLC_AM_MSC_ARGS(ctxt_pP,rlc_pP),
rlc_pP->output_sdu_size_to_write
);
rlc_data_ind (ctxt_pP,
BOOL_NOT(rlc_pP->is_data_plane),
MBMS_FLAG_NO,
@@ -203,16 +178,16 @@ rlc_am_send_sdu (
PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP));
//msg("[RLC_AM][MOD %d] Freeing mem_block ...\n", rlc_pP->module_id);
//free_mem_block (rlc_pP->output_sdu_in_construction, __func__);
//Assertion(eNB)_PRAN_DesignDocument_annex No.764
LOG_E(RLC, PROTOCOL_RLC_AM_CTXT_FMT" SEND SDU REQUESTED %d bytes\n",
PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP),
rlc_pP->output_sdu_size_to_write);
/*
AssertFatal(3==4,
PROTOCOL_RLC_AM_CTXT_FMT" SEND SDU REQUESTED %d bytes",
PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP),
rlc_pP->output_sdu_size_to_write);
*/
//Assertion(eNB)_PRAN_DesignDocument_annex No.764
LOG_E(RLC, PROTOCOL_RLC_AM_CTXT_FMT" SEND SDU REQUESTED %d bytes\n",
PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP),
rlc_pP->output_sdu_size_to_write);
/*
AssertFatal(3==4,
PROTOCOL_RLC_AM_CTXT_FMT" SEND SDU REQUESTED %d bytes",
PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP),
rlc_pP->output_sdu_size_to_write);
*/
}
rlc_pP->output_sdu_size_to_write = 0;
@@ -221,191 +196,189 @@ rlc_am_send_sdu (
//-----------------------------------------------------------------------------
void
rlc_am_reassemble_pdu(
const protocol_ctxt_t* const ctxt_pP,
rlc_am_entity_t * const rlc_pP,
mem_block_t * const tb_pP,
boolean_t free_rlc_pdu)
{
const protocol_ctxt_t *const ctxt_pP,
rlc_am_entity_t *const rlc_pP,
mem_block_t *const tb_pP,
boolean_t free_rlc_pdu) {
int i,j;
rlc_am_pdu_info_t* pdu_info = &((rlc_am_rx_pdu_management_t*)(tb_pP->data))->pdu_info;
rlc_am_pdu_info_t *pdu_info = &((rlc_am_rx_pdu_management_t *)(tb_pP->data))->pdu_info;
LOG_D(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[REASSEMBLY PDU] TRY REASSEMBLY PDU SN=%03d\n",
PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP),
pdu_info->sn);
#if TRACE_RLC_AM_RX_DECODE
rlc_am_display_data_pdu_infos(ctxt_pP, rlc_pP, pdu_info);
#endif
if ( LOG_DEBUGFLAG(DEBUG_RLC)) {
rlc_am_display_data_pdu_infos(ctxt_pP, rlc_pP, pdu_info);
}
if (pdu_info->e == RLC_E_FIXED_PART_DATA_FIELD_FOLLOW) {
switch (pdu_info->fi) {
case RLC_FI_1ST_BYTE_DATA_IS_1ST_BYTE_SDU_LAST_BYTE_DATA_IS_LAST_BYTE_SDU:
LOG_D(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[REASSEMBLY PDU] TRY REASSEMBLY PDU NO E_LI FI=11 (00)\n",
PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP));
// one complete SDU
rlc_am_send_sdu(ctxt_pP, rlc_pP); // may be not necessary
rlc_am_reassembly (ctxt_pP, rlc_pP, pdu_info->payload, pdu_info->payload_size);
rlc_am_send_sdu(ctxt_pP, rlc_pP); // may be not necessary
//rlc_pP->reassembly_missing_sn_detected = 0;
break;
case RLC_FI_1ST_BYTE_DATA_IS_1ST_BYTE_SDU_LAST_BYTE_DATA_IS_LAST_BYTE_SDU:
LOG_D(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[REASSEMBLY PDU] TRY REASSEMBLY PDU NO E_LI FI=11 (00)\n",
PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP));
// one complete SDU
rlc_am_send_sdu(ctxt_pP, rlc_pP); // may be not necessary
rlc_am_reassembly (ctxt_pP, rlc_pP, pdu_info->payload, pdu_info->payload_size);
rlc_am_send_sdu(ctxt_pP, rlc_pP); // may be not necessary
//rlc_pP->reassembly_missing_sn_detected = 0;
break;
case RLC_FI_1ST_BYTE_DATA_IS_1ST_BYTE_SDU_LAST_BYTE_DATA_IS_NOT_LAST_BYTE_SDU:
LOG_D(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[REASSEMBLY PDU] TRY REASSEMBLY PDU NO E_LI FI=10 (01)\n",
PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP));
// one beginning segment of SDU in PDU
rlc_am_send_sdu(ctxt_pP, rlc_pP); // may be not necessary
rlc_am_reassembly (ctxt_pP, rlc_pP,pdu_info->payload, pdu_info->payload_size);
//rlc_pP->reassembly_missing_sn_detected = 0;
break;
case RLC_FI_1ST_BYTE_DATA_IS_1ST_BYTE_SDU_LAST_BYTE_DATA_IS_NOT_LAST_BYTE_SDU:
LOG_D(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[REASSEMBLY PDU] TRY REASSEMBLY PDU NO E_LI FI=10 (01)\n",
PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP));
// one beginning segment of SDU in PDU
rlc_am_send_sdu(ctxt_pP, rlc_pP); // may be not necessary
rlc_am_reassembly (ctxt_pP, rlc_pP,pdu_info->payload, pdu_info->payload_size);
//rlc_pP->reassembly_missing_sn_detected = 0;
break;
case RLC_FI_1ST_BYTE_DATA_IS_NOT_1ST_BYTE_SDU_LAST_BYTE_DATA_IS_LAST_BYTE_SDU:
LOG_D(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[REASSEMBLY PDU] TRY REASSEMBLY PDU NO E_LI FI=01 (10)\n",
PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP));
// one last segment of SDU
//if (rlc_pP->reassembly_missing_sn_detected == 0) {
rlc_am_reassembly (ctxt_pP, rlc_pP, pdu_info->payload, pdu_info->payload_size);
rlc_am_send_sdu(ctxt_pP, rlc_pP);
//} // else { clear sdu already done
//rlc_pP->reassembly_missing_sn_detected = 0;
break;
case RLC_FI_1ST_BYTE_DATA_IS_NOT_1ST_BYTE_SDU_LAST_BYTE_DATA_IS_LAST_BYTE_SDU:
LOG_D(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[REASSEMBLY PDU] TRY REASSEMBLY PDU NO E_LI FI=01 (10)\n",
PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP));
// one last segment of SDU
//if (rlc_pP->reassembly_missing_sn_detected == 0) {
rlc_am_reassembly (ctxt_pP, rlc_pP, pdu_info->payload, pdu_info->payload_size);
rlc_am_send_sdu(ctxt_pP, rlc_pP);
//} // else { clear sdu already done
//rlc_pP->reassembly_missing_sn_detected = 0;
break;
case RLC_FI_1ST_BYTE_DATA_IS_NOT_1ST_BYTE_SDU_LAST_BYTE_DATA_IS_NOT_LAST_BYTE_SDU:
LOG_D(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[REASSEMBLY PDU] TRY REASSEMBLY PDU NO E_LI FI=00 (11)\n",
PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP));
//if (rlc_pP->reassembly_missing_sn_detected == 0) {
// one whole segment of SDU in PDU
rlc_am_reassembly (ctxt_pP, rlc_pP, pdu_info->payload, pdu_info->payload_size);
//} else {
// rlc_pP->reassembly_missing_sn_detected = 1; // not necessary but for readability of the code
//}
case RLC_FI_1ST_BYTE_DATA_IS_NOT_1ST_BYTE_SDU_LAST_BYTE_DATA_IS_NOT_LAST_BYTE_SDU:
LOG_D(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[REASSEMBLY PDU] TRY REASSEMBLY PDU NO E_LI FI=00 (11)\n",
PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP));
//if (rlc_pP->reassembly_missing_sn_detected == 0) {
// one whole segment of SDU in PDU
rlc_am_reassembly (ctxt_pP, rlc_pP, pdu_info->payload, pdu_info->payload_size);
//} else {
// rlc_pP->reassembly_missing_sn_detected = 1; // not necessary but for readability of the code
//}
break;
break;
default:
//Assertion(eNB)_PRAN_DesignDocument_annex No.1428
LOG_E(RLC, "RLC_E_FIXED_PART_DATA_FIELD_FOLLOW error pdu_info->fi[%d]\n", pdu_info->fi);
// assert(0 != 0);
default:
//Assertion(eNB)_PRAN_DesignDocument_annex No.1428
LOG_E(RLC, "RLC_E_FIXED_PART_DATA_FIELD_FOLLOW error pdu_info->fi[%d]\n", pdu_info->fi);
// assert(0 != 0);
}
} else {
switch (pdu_info->fi) {
case RLC_FI_1ST_BYTE_DATA_IS_1ST_BYTE_SDU_LAST_BYTE_DATA_IS_LAST_BYTE_SDU:
LOG_D(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[REASSEMBLY PDU] TRY REASSEMBLY PDU FI=11 (00) Li=",
PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP));
case RLC_FI_1ST_BYTE_DATA_IS_1ST_BYTE_SDU_LAST_BYTE_DATA_IS_LAST_BYTE_SDU:
LOG_D(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[REASSEMBLY PDU] TRY REASSEMBLY PDU FI=11 (00) Li=",
PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP));
for (i=0; i < pdu_info->num_li; i++) {
LOG_D(RLC, "%d ",pdu_info->li_list[i]);
}
for (i=0; i < pdu_info->num_li; i++) {
LOG_D(RLC, "%d ",pdu_info->li_list[i]);
}
LOG_D(RLC, "\n");
//msg(" remaining size %d\n",size);
// N complete SDUs
rlc_am_send_sdu(ctxt_pP, rlc_pP);
j = 0;
for (i = 0; i < pdu_info->num_li; i++) {
rlc_am_reassembly (ctxt_pP, rlc_pP, &pdu_info->payload[j], pdu_info->li_list[i]);
LOG_D(RLC, "\n");
//msg(" remaining size %d\n",size);
// N complete SDUs
rlc_am_send_sdu(ctxt_pP, rlc_pP);
j = j + pdu_info->li_list[i];
}
j = 0;
if (pdu_info->hidden_size > 0) { // normally should always be > 0 but just for help debug
// data is already ok, done by last loop above
rlc_am_reassembly (ctxt_pP, rlc_pP, &pdu_info->payload[j], pdu_info->hidden_size);
for (i = 0; i < pdu_info->num_li; i++) {
rlc_am_reassembly (ctxt_pP, rlc_pP, &pdu_info->payload[j], pdu_info->li_list[i]);
rlc_am_send_sdu(ctxt_pP, rlc_pP);
j = j + pdu_info->li_list[i];
}
if (pdu_info->hidden_size > 0) { // normally should always be > 0 but just for help debug
// data is already ok, done by last loop above
rlc_am_reassembly (ctxt_pP, rlc_pP, &pdu_info->payload[j], pdu_info->hidden_size);
rlc_am_send_sdu(ctxt_pP, rlc_pP);
}
//rlc_pP->reassembly_missing_sn_detected = 0;
break;
case RLC_FI_1ST_BYTE_DATA_IS_1ST_BYTE_SDU_LAST_BYTE_DATA_IS_NOT_LAST_BYTE_SDU:
LOG_D(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[REASSEMBLY PDU] TRY REASSEMBLY PDU FI=10 (01) Li=",
PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP));
for (i=0; i < pdu_info->num_li; i++) {
LOG_D(RLC, "%d ",pdu_info->li_list[i]);
}
LOG_D(RLC, "\n");
//msg(" remaining size %d\n",size);
// N complete SDUs + one segment of SDU in PDU
rlc_am_send_sdu(ctxt_pP, rlc_pP);
}
j = 0;
//rlc_pP->reassembly_missing_sn_detected = 0;
break;
for (i = 0; i < pdu_info->num_li; i++) {
rlc_am_reassembly (ctxt_pP, rlc_pP, &pdu_info->payload[j], pdu_info->li_list[i]);
rlc_am_send_sdu(ctxt_pP, rlc_pP);
j = j + pdu_info->li_list[i];
}
case RLC_FI_1ST_BYTE_DATA_IS_1ST_BYTE_SDU_LAST_BYTE_DATA_IS_NOT_LAST_BYTE_SDU:
LOG_D(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[REASSEMBLY PDU] TRY REASSEMBLY PDU FI=10 (01) Li=",
PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP));
if (pdu_info->hidden_size > 0) { // normally should always be > 0 but just for help debug
// data is already ok, done by last loop above
rlc_am_reassembly (ctxt_pP, rlc_pP, &pdu_info->payload[j], pdu_info->hidden_size);
}
for (i=0; i < pdu_info->num_li; i++) {
LOG_D(RLC, "%d ",pdu_info->li_list[i]);
}
//rlc_pP->reassembly_missing_sn_detected = 0;
break;
LOG_D(RLC, "\n");
//msg(" remaining size %d\n",size);
// N complete SDUs + one segment of SDU in PDU
rlc_am_send_sdu(ctxt_pP, rlc_pP);
j = 0;
case RLC_FI_1ST_BYTE_DATA_IS_NOT_1ST_BYTE_SDU_LAST_BYTE_DATA_IS_LAST_BYTE_SDU:
LOG_D(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[REASSEMBLY PDU] TRY REASSEMBLY PDU FI=01 (10) Li=",
PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP));
for (i = 0; i < pdu_info->num_li; i++) {
rlc_am_reassembly (ctxt_pP, rlc_pP, &pdu_info->payload[j], pdu_info->li_list[i]);
rlc_am_send_sdu(ctxt_pP, rlc_pP);
j = j + pdu_info->li_list[i];
}
for (i=0; i < pdu_info->num_li; i++) {
LOG_D(RLC, "%d ",pdu_info->li_list[i]);
}
if (pdu_info->hidden_size > 0) { // normally should always be > 0 but just for help debug
// data is already ok, done by last loop above
rlc_am_reassembly (ctxt_pP, rlc_pP, &pdu_info->payload[j], pdu_info->hidden_size);
}
LOG_D(RLC, "\n");
//msg(" remaining size %d\n",size);
// one last segment of SDU + N complete SDUs in PDU
j = 0;
//rlc_pP->reassembly_missing_sn_detected = 0;
break;
for (i = 0; i < pdu_info->num_li; i++) {
rlc_am_reassembly (ctxt_pP, rlc_pP, &pdu_info->payload[j], pdu_info->li_list[i]);
rlc_am_send_sdu(ctxt_pP, rlc_pP);
j = j + pdu_info->li_list[i];
}
case RLC_FI_1ST_BYTE_DATA_IS_NOT_1ST_BYTE_SDU_LAST_BYTE_DATA_IS_LAST_BYTE_SDU:
LOG_D(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[REASSEMBLY PDU] TRY REASSEMBLY PDU FI=01 (10) Li=",
PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP));
if (pdu_info->hidden_size > 0) { // normally should always be > 0 but just for help debug
// data is already ok, done by last loop above
rlc_am_reassembly (ctxt_pP, rlc_pP, &pdu_info->payload[j], pdu_info->hidden_size);
rlc_am_send_sdu(ctxt_pP, rlc_pP);
}
for (i=0; i < pdu_info->num_li; i++) {
LOG_D(RLC, "%d ",pdu_info->li_list[i]);
}
//rlc_pP->reassembly_missing_sn_detected = 0;
break;
LOG_D(RLC, "\n");
//msg(" remaining size %d\n",size);
// one last segment of SDU + N complete SDUs in PDU
j = 0;
case RLC_FI_1ST_BYTE_DATA_IS_NOT_1ST_BYTE_SDU_LAST_BYTE_DATA_IS_NOT_LAST_BYTE_SDU:
LOG_D(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[REASSEMBLY PDU] TRY REASSEMBLY PDU FI=00 (11) Li=",
PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP));
for (i = 0; i < pdu_info->num_li; i++) {
rlc_am_reassembly (ctxt_pP, rlc_pP, &pdu_info->payload[j], pdu_info->li_list[i]);
rlc_am_send_sdu(ctxt_pP, rlc_pP);
j = j + pdu_info->li_list[i];
}
for (i=0; i < pdu_info->num_li; i++) {
LOG_D(RLC, "%d ",pdu_info->li_list[i]);
}
if (pdu_info->hidden_size > 0) { // normally should always be > 0 but just for help debug
// data is already ok, done by last loop above
rlc_am_reassembly (ctxt_pP, rlc_pP, &pdu_info->payload[j], pdu_info->hidden_size);
rlc_am_send_sdu(ctxt_pP, rlc_pP);
}
LOG_D(RLC, "\n");
//msg(" remaining size %d\n",size);
j = 0;
//rlc_pP->reassembly_missing_sn_detected = 0;
break;
for (i = 0; i < pdu_info->num_li; i++) {
rlc_am_reassembly (ctxt_pP, rlc_pP, &pdu_info->payload[j], pdu_info->li_list[i]);
rlc_am_send_sdu(ctxt_pP, rlc_pP);
j = j + pdu_info->li_list[i];
}
case RLC_FI_1ST_BYTE_DATA_IS_NOT_1ST_BYTE_SDU_LAST_BYTE_DATA_IS_NOT_LAST_BYTE_SDU:
LOG_D(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[REASSEMBLY PDU] TRY REASSEMBLY PDU FI=00 (11) Li=",
PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP));
if (pdu_info->hidden_size > 0) { // normally should always be > 0 but just for help debug
// data is already ok, done by last loop above
rlc_am_reassembly (ctxt_pP, rlc_pP, &pdu_info->payload[j], pdu_info->hidden_size);
}
for (i=0; i < pdu_info->num_li; i++) {
LOG_D(RLC, "%d ",pdu_info->li_list[i]);
}
//rlc_pP->reassembly_missing_sn_detected = 0;
break;
LOG_D(RLC, "\n");
//msg(" remaining size %d\n",size);
j = 0;
for (i = 0; i < pdu_info->num_li; i++) {
rlc_am_reassembly (ctxt_pP, rlc_pP, &pdu_info->payload[j], pdu_info->li_list[i]);
rlc_am_send_sdu(ctxt_pP, rlc_pP);
j = j + pdu_info->li_list[i];
}
if (pdu_info->hidden_size > 0) { // normally should always be > 0 but just for help debug
// data is already ok, done by last loop above
rlc_am_reassembly (ctxt_pP, rlc_pP, &pdu_info->payload[j], pdu_info->hidden_size);
}
//rlc_pP->reassembly_missing_sn_detected = 0;
break;
default:
//Assertion(eNB)_PRAN_DesignDocument_annex No.1429
LOG_E(RLC, "not RLC_E_FIXED_PART_DATA_FIELD_FOLLOW error pdu_info->fi[%d]\n", pdu_info->fi);
// assert(1 != 1);
default:
//Assertion(eNB)_PRAN_DesignDocument_annex No.1429
LOG_E(RLC, "not RLC_E_FIXED_PART_DATA_FIELD_FOLLOW error pdu_info->fi[%d]\n", pdu_info->fi);
// assert(1 != 1);
}
}
if (free_rlc_pdu) {
free_mem_block(tb_pP, __func__);
free_mem_block(tb_pP, __func__);
}
}
@@ -27,59 +27,19 @@
#include "platform_types.h"
//-----------------------------------------------------------------------------
#if ENABLE_ITTI
# include "intertask_interface.h"
#include "intertask_interface.h"
#endif
#include "assertions.h"
#include "list.h"
#include "rlc_am.h"
#include "common/utils/LOG/log.h"
# if ENABLE_ITTI
//-----------------------------------------------------------------------------
void
rlc_am_itti_display_status_ind_infos(
const protocol_ctxt_t* const ctxt_pP,
const rlc_am_entity_t *const rlc_pP,
const rlc_am_control_pdu_info_t *const pdu_info_pP)
{
char message_string[1000];
size_t message_string_size = 0;
MessageDef *msg_p;
int num_nack;
if (!pdu_info_pP->d_c) {
message_string_size += sprintf(&message_string[message_string_size], "Bearer : %u\n", rlc_pP->rb_id);
message_string_size += sprintf(&message_string[message_string_size], "CONTROL PDU ACK SN %04d", pdu_info_pP->ack_sn);
for (num_nack = 0; num_nack < pdu_info_pP->num_nack; num_nack++) {
if (pdu_info_pP->nack_list[num_nack].e2) {
message_string_size += sprintf(&message_string[message_string_size], "\n\tNACK SN %04d SO START %05d SO END %05d", pdu_info_pP->nack_list[num_nack].nack_sn,
pdu_info_pP->nack_list[num_nack].so_start,
pdu_info_pP->nack_list[num_nack].so_end);
} else {
message_string_size += sprintf(&message_string[message_string_size], "\n\tNACK SN %04d", pdu_info_pP->nack_list[num_nack].nack_sn);
}
}
message_string_size += sprintf(&message_string[message_string_size], "\n");
msg_p = itti_alloc_new_message_sized (ctxt_pP->enb_flag > 0 ? TASK_RLC_ENB:TASK_RLC_UE , RLC_AM_STATUS_PDU_IND, message_string_size + sizeof (IttiMsgText));
msg_p->ittiMsg.rlc_am_status_pdu_ind.size = message_string_size;
memcpy(&msg_p->ittiMsg.rlc_am_status_pdu_ind.text, message_string, message_string_size);
itti_send_msg_to_task(TASK_UNKNOWN, ctxt_pP->instance, msg_p);
}
}
# endif
//-----------------------------------------------------------------------------
uint16_t rlc_am_read_bit_field(
uint8_t** data_ppP,
unsigned int* bit_pos_pP,
const signed int bits_to_readP)
{
uint8_t **data_ppP,
unsigned int *bit_pos_pP,
const signed int bits_to_readP) {
uint16_t value = 0;
unsigned int bits_read = 0;
signed int bits_to_read = bits_to_readP;
@@ -113,11 +73,10 @@ uint16_t rlc_am_read_bit_field(
//-----------------------------------------------------------------------------
void
rlc_am_write8_bit_field(
uint8_t** data_ppP,
unsigned int* bit_pos_pP,
uint8_t **data_ppP,
unsigned int *bit_pos_pP,
const signed int bits_to_writeP,
const uint8_t valueP)
{
const uint8_t valueP) {
unsigned int available_bits;
signed int bits_to_write= bits_to_writeP;
@@ -148,11 +107,10 @@ rlc_am_write8_bit_field(
//-----------------------------------------------------------------------------
void
rlc_am_write16_bit_field(
uint8_t** data_ppP,
unsigned int* bit_pos_pP,
uint8_t **data_ppP,
unsigned int *bit_pos_pP,
signed int bits_to_writeP,
const uint16_t valueP)
{
const uint16_t valueP) {
//assert(bits_to_writeP <= 16);
if(bits_to_writeP > 16) {
LOG_E(RLC, "bits_to_writeP error. %d\n", bits_to_writeP);
@@ -168,15 +126,12 @@ rlc_am_write16_bit_field(
//-----------------------------------------------------------------------------
signed int
rlc_am_get_control_pdu_infos(
rlc_am_pdu_sn_10_t* const header_pP,
sdu_size_t * const total_size_pP,
rlc_am_control_pdu_info_t* const pdu_info_pP)
{
rlc_am_pdu_sn_10_t *const header_pP,
sdu_size_t *const total_size_pP,
rlc_am_control_pdu_info_t *const pdu_info_pP) {
memset(pdu_info_pP, 0, sizeof (rlc_am_control_pdu_info_t));
pdu_info_pP->d_c = header_pP->b1 >> 7;
if (!pdu_info_pP->d_c) {
pdu_info_pP->cpt = (header_pP->b1 >> 4) & 0x07;
@@ -191,7 +146,7 @@ rlc_am_get_control_pdu_infos(
if (pdu_info_pP->e1) {
unsigned int nack_to_read = 1;
unsigned int bit_pos = 7; // range from 0 (MSB/left) to 7 (LSB/right)
uint8_t* byte_pos_p = &header_pP->b2;
uint8_t *byte_pos_p = &header_pP->b2;
while (nack_to_read) {
pdu_info_pP->nack_list[pdu_info_pP->num_nack].nack_sn = rlc_am_read_bit_field(&byte_pos_p, &bit_pos, 10);
@@ -214,9 +169,11 @@ rlc_am_get_control_pdu_infos(
if (!pdu_info_pP->nack_list[pdu_info_pP->num_nack - 1].e1) {
nack_to_read = 0;
*total_size_pP = *total_size_pP - (sdu_size_t)((uint64_t)byte_pos_p + (uint64_t)((bit_pos + 7)/8) - (uint64_t)header_pP);
if (*total_size_pP != 0) {
LOG_E(RLC, "[RLC_AM_GET_CONTROL_PDU_INFOS][FIRST]header_pP->b1=%d,header_pP->b2=%d\n",header_pP->b1,header_pP->b2);
}
return 0;
}
@@ -230,9 +187,11 @@ rlc_am_get_control_pdu_infos(
} else {
*total_size_pP = *total_size_pP - 2;
}
if (*total_size_pP != 0) {
LOG_E(RLC, "[RLC_AM_GET_CONTROL_PDU_INFOS][SECOND]header_pP->b1=%d,header_pP->b2=%d\n",header_pP->b1,header_pP->b2);
}
return 0;
} else {
return -1;
@@ -241,9 +200,8 @@ rlc_am_get_control_pdu_infos(
//-----------------------------------------------------------------------------
void
rlc_am_display_control_pdu_infos(
const rlc_am_control_pdu_info_t* const pdu_info_pP
)
{
const rlc_am_control_pdu_info_t *const pdu_info_pP
) {
int num_nack;
if (!pdu_info_pP->d_c) {
@@ -267,25 +225,23 @@ rlc_am_display_control_pdu_infos(
//-----------------------------------------------------------------------------
void
rlc_am_receive_process_control_pdu(
const protocol_ctxt_t* const ctxt_pP,
const protocol_ctxt_t *const ctxt_pP,
rlc_am_entity_t *const rlc_pP,
mem_block_t* const tb_pP,
uint8_t** first_byte_ppP,
sdu_size_t * const tb_size_in_bytes_pP)
{
rlc_am_pdu_sn_10_t *rlc_am_pdu_sn_10_p = (rlc_am_pdu_sn_10_t*)*first_byte_ppP;
mem_block_t *const tb_pP,
uint8_t **first_byte_ppP,
sdu_size_t *const tb_size_in_bytes_pP) {
rlc_am_pdu_sn_10_t *rlc_am_pdu_sn_10_p = (rlc_am_pdu_sn_10_t *)*first_byte_ppP;
sdu_size_t initial_pdu_size = *tb_size_in_bytes_pP;
rlc_sn_t ack_sn = RLC_AM_NEXT_SN(rlc_pP->vt_a);
rlc_sn_t sn_cursor = rlc_pP->vt_a;
rlc_sn_t vt_a_new = rlc_pP->vt_a;
rlc_sn_t sn_data_cnf;
rlc_sn_t vt_a_new = rlc_pP->vt_a;
rlc_sn_t sn_data_cnf;
rlc_sn_t nack_sn,prev_nack_sn;
sdu_size_t data_cnf_so_stop = 0x7FFF;
sdu_size_t data_cnf_so_stop = 0x7FFF;
unsigned int nack_index;
boolean_t status = TRUE;
if (rlc_am_get_control_pdu_infos(rlc_am_pdu_sn_10_p, tb_size_in_bytes_pP, &rlc_pP->control_pdu_info) >= 0) {
rlc_am_tx_buffer_display(ctxt_pP, rlc_pP, " TX BUFFER BEFORE PROCESS OF STATUS PDU");
LOG_D(RLC, PROTOCOL_RLC_AM_CTXT_FMT" RX CONTROL PDU VT(A) %04d VT(S) %04d POLL_SN %04d ACK_SN %04d\n",
PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP),
@@ -294,7 +250,6 @@ rlc_am_receive_process_control_pdu(
rlc_pP->poll_sn,
rlc_pP->control_pdu_info.ack_sn);
rlc_am_display_control_pdu_infos(&rlc_pP->control_pdu_info);
ack_sn = rlc_pP->control_pdu_info.ack_sn;
// 5.2.1 Retransmission
//
@@ -326,8 +281,7 @@ rlc_am_receive_process_control_pdu(
/* Note : ackSn can be equal to current vtA only in case the status pdu contains a list of nack_sn with same value = vtA with SOStart/SOEnd */
/* and meaning the report is not complete due to not enough ressources to fill all SOStart/SOEnd of this NACK_SN */
if (RLC_AM_DIFF_SN(rlc_pP->vt_s,rlc_pP->vt_a) >= RLC_AM_DIFF_SN(ack_sn,rlc_pP->vt_a))
{
if (RLC_AM_DIFF_SN(rlc_pP->vt_s,rlc_pP->vt_a) >= RLC_AM_DIFF_SN(ack_sn,rlc_pP->vt_a)) {
if (rlc_pP->control_pdu_info.num_nack == 0) {
while (sn_cursor != ack_sn) {
rlc_am_ack_pdu(ctxt_pP, rlc_pP, sn_cursor,TRUE);
@@ -342,63 +296,56 @@ rlc_am_receive_process_control_pdu(
prev_nack_sn = 0x3FFF;
while (sn_cursor != nack_sn) {
rlc_am_ack_pdu(ctxt_pP, rlc_pP, sn_cursor,TRUE);
sn_cursor = RLC_AM_NEXT_SN(sn_cursor);
rlc_am_ack_pdu(ctxt_pP, rlc_pP, sn_cursor,TRUE);
sn_cursor = RLC_AM_NEXT_SN(sn_cursor);
}
vt_a_new = nack_sn;
// catch DataCfn
rlc_am_tx_data_pdu_management_t *tx_data_pdu_buffer_p = &rlc_pP->tx_data_pdu_buffer[nack_sn % RLC_AM_WINDOW_SIZE];
if (tx_data_pdu_buffer_p->retx_payload_size == tx_data_pdu_buffer_p->payload_size) {
sn_data_cnf = RLC_AM_PREV_SN(nack_sn);
}
else if (tx_data_pdu_buffer_p->nack_so_start != 0) {
sn_data_cnf = nack_sn;
data_cnf_so_stop = tx_data_pdu_buffer_p->nack_so_start - 1;
}
else {
sn_data_cnf = RLC_AM_PREV_SN(nack_sn);
}
if (tx_data_pdu_buffer_p->retx_payload_size == tx_data_pdu_buffer_p->payload_size) {
sn_data_cnf = RLC_AM_PREV_SN(nack_sn);
} else if (tx_data_pdu_buffer_p->nack_so_start != 0) {
sn_data_cnf = nack_sn;
data_cnf_so_stop = tx_data_pdu_buffer_p->nack_so_start - 1;
} else {
sn_data_cnf = RLC_AM_PREV_SN(nack_sn);
}
while ((sn_cursor != ack_sn) && (status)) {
if (sn_cursor != nack_sn) {
rlc_am_ack_pdu(ctxt_pP,
rlc_pP,
sn_cursor,
FALSE);
FALSE);
} else {
status = rlc_am_nack_pdu (ctxt_pP,
rlc_pP,
nack_sn,
prev_nack_sn,
rlc_pP->control_pdu_info.nack_list[nack_index].so_start,
rlc_pP->control_pdu_info.nack_list[nack_index].so_end);
status = rlc_am_nack_pdu (ctxt_pP,
rlc_pP,
nack_sn,
prev_nack_sn,
rlc_pP->control_pdu_info.nack_list[nack_index].so_start,
rlc_pP->control_pdu_info.nack_list[nack_index].so_end);
nack_index = nack_index + 1;
prev_nack_sn = nack_sn;
if (nack_index < rlc_pP->control_pdu_info.num_nack) {
nack_sn = rlc_pP->control_pdu_info.nack_list[nack_index].nack_sn;
}
else if (nack_sn != ack_sn) {
/* general case*/
nack_sn = ack_sn;
}
else {
/*specific case when the sender did not have enough TBS to fill all SOStart SOEnd for this NACK_SN */
break;
nack_sn = rlc_pP->control_pdu_info.nack_list[nack_index].nack_sn;
} else if (nack_sn != ack_sn) {
/* general case*/
nack_sn = ack_sn;
} else {
/*specific case when the sender did not have enough TBS to fill all SOStart SOEnd for this NACK_SN */
break;
}
}
if (prev_nack_sn != nack_sn) {
/* do not increment sn_cursor in case of several informations for the same nack_sn */
sn_cursor = (sn_cursor + 1) & RLC_AM_SN_MASK;
/* do not increment sn_cursor in case of several informations for the same nack_sn */
sn_cursor = (sn_cursor + 1) & RLC_AM_SN_MASK;
}
}
}
} else {
LOG_E(RLC, PROTOCOL_RLC_AM_CTXT_FMT" WARNING CONTROL PDU ACK SN %d OUT OF WINDOW vtA=%d vtS=%d\n",
PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP),ack_sn,rlc_pP->vt_a,rlc_pP->vt_s);
@@ -413,61 +360,57 @@ rlc_am_receive_process_control_pdu(
}
if (status) {
/* Check for Stopping TpollReTx */
if ((rlc_pP->poll_sn != RLC_SN_UNDEFINED) &&
(RLC_AM_DIFF_SN(ack_sn,rlc_pP->vt_a) > RLC_AM_DIFF_SN(rlc_pP->poll_sn,rlc_pP->vt_a))) {
rlc_am_stop_and_reset_timer_poll_retransmit(ctxt_pP, rlc_pP);
rlc_pP->poll_sn = RLC_SN_UNDEFINED;
/* Check for Stopping TpollReTx */
if ((rlc_pP->poll_sn != RLC_SN_UNDEFINED) &&
(RLC_AM_DIFF_SN(ack_sn,rlc_pP->vt_a) > RLC_AM_DIFF_SN(rlc_pP->poll_sn,rlc_pP->vt_a))) {
rlc_am_stop_and_reset_timer_poll_retransmit(ctxt_pP, rlc_pP);
rlc_pP->poll_sn = RLC_SN_UNDEFINED;
}
//TODO : this part does not cover all cases of Data Cnf and move it at the end of Status PDU processing
sn_cursor = rlc_pP->vt_a;
// Fix Issue 238 : check sn_data_cnf has been transmitted
if ((rlc_pP->tx_data_pdu_buffer[sn_data_cnf % RLC_AM_WINDOW_SIZE].flags.transmitted) &&
(rlc_pP->tx_data_pdu_buffer[sn_data_cnf % RLC_AM_WINDOW_SIZE].sn == sn_data_cnf)) {
/* Handle all acked PDU up to and excluding sn_data_cnf */
while (sn_cursor != sn_data_cnf) {
rlc_am_pdu_sdu_data_cnf(ctxt_pP,rlc_pP,sn_cursor);
sn_cursor = RLC_AM_NEXT_SN(sn_cursor);
}
//TODO : this part does not cover all cases of Data Cnf and move it at the end of Status PDU processing
sn_cursor = rlc_pP->vt_a;
// Fix Issue 238 : check sn_data_cnf has been transmitted
if ((rlc_pP->tx_data_pdu_buffer[sn_data_cnf % RLC_AM_WINDOW_SIZE].flags.transmitted) &&
(rlc_pP->tx_data_pdu_buffer[sn_data_cnf % RLC_AM_WINDOW_SIZE].sn == sn_data_cnf)) {
/* Handle all acked PDU up to and excluding sn_data_cnf */
while (sn_cursor != sn_data_cnf) {
rlc_am_pdu_sdu_data_cnf(ctxt_pP,rlc_pP,sn_cursor);
sn_cursor = RLC_AM_NEXT_SN(sn_cursor);
}
// Handle last SN. TO DO : case of PDU partially ACKED with SDU to be data conf
if (data_cnf_so_stop == 0x7FFF) {
rlc_am_pdu_sdu_data_cnf(ctxt_pP,rlc_pP,sn_data_cnf);
}
LOG_D(RLC, PROTOCOL_RLC_AM_CTXT_FMT" RECEIVE STATUS PDU ACK_SN=%d NewvtA=%d OldvtA=%d SnDataCnf=%d DataCnfSOStop=%d vtS=%d\n",
PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP),ack_sn,vt_a_new,rlc_pP->vt_a,sn_data_cnf,data_cnf_so_stop,rlc_pP->vt_s);
}
else {
LOG_D(RLC, PROTOCOL_RLC_AM_CTXT_FMT" RECEIVE STATUS PDU WITH NO SDU CNF ACK_SN=%d NewvtA=%d OldvtA=%d vtS=%d\n",
PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP),ack_sn,vt_a_new,rlc_pP->vt_a,rlc_pP->vt_s);
// Handle last SN. TO DO : case of PDU partially ACKED with SDU to be data conf
if (data_cnf_so_stop == 0x7FFF) {
rlc_am_pdu_sdu_data_cnf(ctxt_pP,rlc_pP,sn_data_cnf);
}
/* Update vtA and vtMS */
rlc_pP->vt_a = vt_a_new;
rlc_pP->vt_ms = (rlc_pP->vt_a + RLC_AM_WINDOW_SIZE) & RLC_AM_SN_MASK;
LOG_D(RLC, PROTOCOL_RLC_AM_CTXT_FMT" RECEIVE STATUS PDU ACK_SN=%d NewvtA=%d OldvtA=%d SnDataCnf=%d DataCnfSOStop=%d vtS=%d\n",
PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP),ack_sn,vt_a_new,rlc_pP->vt_a,sn_data_cnf,data_cnf_so_stop,rlc_pP->vt_s);
} else {
LOG_D(RLC, PROTOCOL_RLC_AM_CTXT_FMT" RECEIVE STATUS PDU WITH NO SDU CNF ACK_SN=%d NewvtA=%d OldvtA=%d vtS=%d\n",
PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP),ack_sn,vt_a_new,rlc_pP->vt_a,rlc_pP->vt_s);
}
/* Update vtA and vtMS */
rlc_pP->vt_a = vt_a_new;
rlc_pP->vt_ms = (rlc_pP->vt_a + RLC_AM_WINDOW_SIZE) & RLC_AM_SN_MASK;
}
*first_byte_ppP = (uint8_t*)((uint64_t)*first_byte_ppP + initial_pdu_size - *tb_size_in_bytes_pP);
*first_byte_ppP = (uint8_t *)((uint64_t)*first_byte_ppP + initial_pdu_size - *tb_size_in_bytes_pP);
free_mem_block(tb_pP, __func__);
rlc_am_tx_buffer_display(ctxt_pP, rlc_pP, NULL);
}
//-----------------------------------------------------------------------------
int
rlc_am_write_status_pdu(
const protocol_ctxt_t* const ctxt_pP,
const protocol_ctxt_t *const ctxt_pP,
rlc_am_entity_t *const rlc_pP,
rlc_am_pdu_sn_10_t* const rlc_am_pdu_sn_10_pP,
rlc_am_control_pdu_info_t* const pdu_info_pP)
{
rlc_am_pdu_sn_10_t *const rlc_am_pdu_sn_10_pP,
rlc_am_control_pdu_info_t *const pdu_info_pP) {
unsigned int bit_pos = 4; // range from 0 (MSB/left) to 7 (LSB/right)
uint8_t* byte_pos_p = &rlc_am_pdu_sn_10_pP->b1;
uint8_t *byte_pos_p = &rlc_am_pdu_sn_10_pP->b1;
unsigned int index = 0;
unsigned int num_bytes = 0;
rlc_am_write16_bit_field(&byte_pos_p, &bit_pos, 10, pdu_info_pP->ack_sn);
if (pdu_info_pP->num_nack > 0) {
@@ -495,20 +438,17 @@ rlc_am_write_status_pdu(
num_bytes += 1;
}
#if TRACE_RLC_AM_STATUS_CREATION
LOG_D(RLC, PROTOCOL_RLC_AM_CTXT_FMT" WROTE STATUS PDU %d BYTES\n",
PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP),
num_bytes);
#endif
return num_bytes;
}
//-----------------------------------------------------------------------------
void
rlc_am_send_status_pdu(
const protocol_ctxt_t* const ctxt_pP,
const protocol_ctxt_t *const ctxt_pP,
rlc_am_entity_t *const rlc_pP
)
{
) {
// When STATUS reporting has been triggered, the receiving side of an AM RLC entity shall:
// - if t-StatusProhibit is not running:
// - at the first transmission opportunity indicated by lower layer, construct a STATUS PDU and deliver it to lower layer;
@@ -530,10 +470,9 @@ rlc_am_send_status_pdu(
// - include in the STATUS PDU a set of NACK_SN, SOstart and SOend
// - set the ACK_SN to the SN of the next not received RLC Data PDU which is not indicated as missing in the
// resulting STATUS PDU.
signed int nb_bits_to_transmit = rlc_pP->nb_bytes_requested_by_mac << 3;
// minimum header size in bits to be transmitted: D/C + CPT + ACK_SN + E1
signed int nb_bits_transmitted = RLC_AM_PDU_D_C_BITS + RLC_AM_STATUS_PDU_CPT_LENGTH + RLC_AM_SN_BITS + RLC_AM_PDU_E_BITS;
signed int nb_bits_transmitted = RLC_AM_PDU_D_C_BITS + RLC_AM_STATUS_PDU_CPT_LENGTH + RLC_AM_SN_BITS + RLC_AM_PDU_E_BITS;
rlc_am_control_pdu_info_t control_pdu_info;
rlc_am_pdu_info_t *pdu_info_cursor_p = NULL;
rlc_sn_t sn_cursor = 0;
@@ -543,325 +482,278 @@ rlc_am_send_status_pdu(
int waited_so = 0;
mem_block_t *tb_p = NULL;
sdu_size_t pdu_size = 0;
boolean_t status_report_completed = false;
boolean_t segment_loop_end = false;
boolean_t status_report_completed = false;
boolean_t segment_loop_end = false;
memset(&control_pdu_info, 0, sizeof(rlc_am_control_pdu_info_t));
#if TRACE_RLC_AM_STATUS_CREATION
LOG_D(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[SEND-STATUS] nb_bits_to_transmit %d (15 already allocated for header)\n",
PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP),
nb_bits_to_transmit);
rlc_am_rx_list_display(rlc_pP, " DISPLAY BEFORE CONSTRUCTION OF STATUS REPORT");
#endif
/* Handle no NACK first */
if (rlc_pP->vr_r == rlc_pP->vr_ms) {
control_pdu_info.ack_sn = rlc_pP->vr_ms;
status_report_completed = true;
#if TRACE_RLC_AM_STATUS_CREATION
LOG_D(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[SEND-STATUS] LINE %d ALL ACK WITH ACK_SN %04d\n",
PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP),
__LINE__,
rlc_pP->vr_ms);
#endif
}
else if ((cursor_p != NULL) && ((nb_bits_transmitted + RLC_AM_SN_BITS + (RLC_AM_PDU_E_BITS << 1)) <= nb_bits_to_transmit)) {
pdu_info_cursor_p = &((rlc_am_rx_pdu_management_t*)(cursor_p->data))->pdu_info;
control_pdu_info.ack_sn = rlc_pP->vr_ms;
status_report_completed = true;
LOG_D(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[SEND-STATUS] LINE %d ALL ACK WITH ACK_SN %04d\n",
PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP),
__LINE__,
rlc_pP->vr_ms);
} else if ((cursor_p != NULL) && ((nb_bits_transmitted + RLC_AM_SN_BITS + (RLC_AM_PDU_E_BITS << 1)) <= nb_bits_to_transmit)) {
pdu_info_cursor_p = &((rlc_am_rx_pdu_management_t *)(cursor_p->data))->pdu_info;
sn_cursor = pdu_info_cursor_p->sn;
/* Set E1 bit for the presence of first NACK_SN/E1/E2 */
control_pdu_info.e1 = 1;
// 12 bits = size of NACK_SN field + E1, E2 bits
// 42 bits = size of NACK_SN field + SO_START, SO_END fields, E1, E2 bits
while ((!status_report_completed) && (RLC_AM_DIFF_SN(sn_nack,rlc_pP->vr_r) < RLC_AM_DIFF_SN(rlc_pP->vr_ms,rlc_pP->vr_r))
&& (cursor_p != NULL) && (nb_bits_transmitted <= nb_bits_to_transmit)) {
pdu_info_cursor_p = &((rlc_am_rx_pdu_management_t*)(cursor_p->data))->pdu_info;
&& (cursor_p != NULL) && (nb_bits_transmitted <= nb_bits_to_transmit)) {
pdu_info_cursor_p = &((rlc_am_rx_pdu_management_t *)(cursor_p->data))->pdu_info;
sn_cursor = pdu_info_cursor_p->sn;
all_segments_received = ((rlc_am_rx_pdu_management_t*)(cursor_p->data))->all_segments_received;
all_segments_received = ((rlc_am_rx_pdu_management_t *)(cursor_p->data))->all_segments_received;
/* First fill NACK_SN with each missing PDU between current sn_nack and sn_cursor */
while ((sn_nack != sn_cursor) && (RLC_AM_DIFF_SN(sn_nack,rlc_pP->vr_r) < RLC_AM_DIFF_SN(rlc_pP->vr_ms,rlc_pP->vr_r))) {
if (nb_bits_transmitted + RLC_AM_SN_BITS + (RLC_AM_PDU_E_BITS << 1) <= nb_bits_to_transmit) {
/* Fill NACK_SN infos */
control_pdu_info.nack_list[control_pdu_info.num_nack].nack_sn = sn_nack;
control_pdu_info.nack_list[control_pdu_info.num_nack].so_start = 0;
control_pdu_info.nack_list[control_pdu_info.num_nack].so_end = RLC_AM_STATUS_PDU_SO_END_ALL_BYTES;
control_pdu_info.nack_list[control_pdu_info.num_nack].e2 = 0;
/* Set E1 for next NACK_SN. The last one will be cleared */
control_pdu_info.nack_list[control_pdu_info.num_nack].e1 = 1;
control_pdu_info.num_nack += 1;
nb_bits_transmitted += (RLC_AM_SN_BITS + (RLC_AM_PDU_E_BITS << 1));
#if TRACE_RLC_AM_STATUS_CREATION
if (nb_bits_transmitted + RLC_AM_SN_BITS + (RLC_AM_PDU_E_BITS << 1) <= nb_bits_to_transmit) {
/* Fill NACK_SN infos */
control_pdu_info.nack_list[control_pdu_info.num_nack].nack_sn = sn_nack;
control_pdu_info.nack_list[control_pdu_info.num_nack].so_start = 0;
control_pdu_info.nack_list[control_pdu_info.num_nack].so_end = RLC_AM_STATUS_PDU_SO_END_ALL_BYTES;
control_pdu_info.nack_list[control_pdu_info.num_nack].e2 = 0;
/* Set E1 for next NACK_SN. The last one will be cleared */
control_pdu_info.nack_list[control_pdu_info.num_nack].e1 = 1;
control_pdu_info.num_nack += 1;
nb_bits_transmitted += (RLC_AM_SN_BITS + (RLC_AM_PDU_E_BITS << 1));
LOG_D(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[SEND-STATUS] LINE %d PREPARE SENDING NACK %04d\n",
PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP),
__LINE__,
sn_nack);
#endif
sn_nack = RLC_AM_NEXT_SN(sn_nack);
}
else {
/* Not enough UL TBS*/
/* latest value of sn_nack shall be used as ACK_SN */
control_pdu_info.ack_sn = sn_nack;
status_report_completed = true;
#if TRACE_RLC_AM_STATUS_CREATION
sn_nack);
sn_nack = RLC_AM_NEXT_SN(sn_nack);
} else {
/* Not enough UL TBS*/
/* latest value of sn_nack shall be used as ACK_SN */
control_pdu_info.ack_sn = sn_nack;
status_report_completed = true;
LOG_D(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[SEND-STATUS] LINE %d NOT ENOUGH TBS STOP WITH ACK_SN %04d\n",
PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP),
__LINE__,
sn_nack);
#endif
break;
}
sn_nack);
break;
}
}
if (sn_nack == rlc_pP->vr_ms) {
break;
break;
}
/* Now process all Segments of sn_cursor if PDU not fully received */
if ((!status_report_completed) && (all_segments_received == 0) && (sn_cursor != rlc_pP->vr_ms)) {
//AssertFatal (sn_nack == sn_cursor, "RLC AM Tx Status PDU Data sn_nack=%d and sn_cursor=%d should be equal LcId=%d\n",sn_nack,sn_cursor, rlc_pP->channel_id);
if(sn_nack != sn_cursor){
LOG_E(RLC, "RLC AM Tx Status PDU Data sn_nack=%d and sn_cursor=%d should be equal LcId=%d\n",sn_nack,sn_cursor, rlc_pP->channel_id);
}
/* First ensure there is enough TBS for at least 1 SOStart/SOEnd, else break */
//AssertFatal (sn_nack == sn_cursor, "RLC AM Tx Status PDU Data sn_nack=%d and sn_cursor=%d should be equal LcId=%d\n",sn_nack,sn_cursor, rlc_pP->channel_id);
if(sn_nack != sn_cursor) {
LOG_E(RLC, "RLC AM Tx Status PDU Data sn_nack=%d and sn_cursor=%d should be equal LcId=%d\n",sn_nack,sn_cursor, rlc_pP->channel_id);
}
/* First ensure there is enough TBS for at least 1 SOStart/SOEnd, else break */
else if ((nb_bits_transmitted + RLC_AM_SN_BITS + (RLC_AM_PDU_E_BITS << 1) + (RLC_AM_STATUS_PDU_SO_LENGTH << 1)) <= nb_bits_to_transmit) {
/* Init loop flags */
/* Check lsf */
segment_loop_end = (pdu_info_cursor_p->lsf == 1);
/* Init loop flags */
/* Check lsf */
segment_loop_end = (pdu_info_cursor_p->lsf == 1);
/* Init first SO Start according to first segment */
if (pdu_info_cursor_p->so) {
/* Fill the first SO */
/* Init first SO Start according to first segment */
if (pdu_info_cursor_p->so) {
/* Fill the first SO */
control_pdu_info.nack_list[control_pdu_info.num_nack].nack_sn = sn_cursor;
control_pdu_info.nack_list[control_pdu_info.num_nack].so_start = 0;
control_pdu_info.nack_list[control_pdu_info.num_nack].so_end = pdu_info_cursor_p->so - 1;
control_pdu_info.nack_list[control_pdu_info.num_nack].e2 = 1;
/* Set E1 for next NACK_SN. The last one will be cleared */
control_pdu_info.nack_list[control_pdu_info.num_nack].e1 = 1;
control_pdu_info.num_nack += 1;
nb_bits_transmitted += (RLC_AM_SN_BITS + (RLC_AM_PDU_E_BITS << 1) + (RLC_AM_STATUS_PDU_SO_LENGTH << 1));
LOG_D(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[SEND-STATUS] LINE %d PREPARE SENDING NACK %04d SO START %05d SO END %05d\n",
PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP),
__LINE__,
sn_cursor,
0,
pdu_info_cursor_p->so - 1);
waited_so = pdu_info_cursor_p->so + pdu_info_cursor_p->payload_size;
} else {
waited_so = pdu_info_cursor_p->payload_size;
}
/* Go to next segment */
cursor_p = cursor_p->next;
if (cursor_p != NULL) {
pdu_info_cursor_p = &((rlc_am_rx_pdu_management_t *)(cursor_p->data))->pdu_info;
}
/* Find the first discontinuity and then fill SOStart/SOEnd */
while (!segment_loop_end) {
if ((cursor_p != NULL) && (pdu_info_cursor_p->sn == sn_cursor)) {
/* PDU segment is for the same SN*/
/* Check lsf */
segment_loop_end = (pdu_info_cursor_p->lsf == 1);
if (waited_so < pdu_info_cursor_p->so) {
/* SO is greater than previous received portion : gap identified to fill */
if ((nb_bits_transmitted + RLC_AM_SN_BITS + (RLC_AM_PDU_E_BITS << 1) + (RLC_AM_STATUS_PDU_SO_LENGTH << 1)) <= nb_bits_to_transmit) {
control_pdu_info.nack_list[control_pdu_info.num_nack].nack_sn = sn_cursor;
control_pdu_info.nack_list[control_pdu_info.num_nack].so_start = 0;
control_pdu_info.nack_list[control_pdu_info.num_nack].so_start = waited_so;
control_pdu_info.nack_list[control_pdu_info.num_nack].so_end = pdu_info_cursor_p->so - 1;
control_pdu_info.nack_list[control_pdu_info.num_nack].e2 = 1;
/* Set E1 for next NACK_SN. The last one will be cleared */
control_pdu_info.nack_list[control_pdu_info.num_nack].e1 = 1;
control_pdu_info.num_nack += 1;
nb_bits_transmitted += (RLC_AM_SN_BITS + (RLC_AM_PDU_E_BITS << 1) + (RLC_AM_STATUS_PDU_SO_LENGTH << 1));
#if TRACE_RLC_AM_STATUS_CREATION
LOG_D(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[SEND-STATUS] LINE %d PREPARE SENDING NACK %04d SO START %05d SO END %05d\n",
PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP),
__LINE__,
sn_cursor,
0,
pdu_info_cursor_p->so - 1);
#endif
waited_so = pdu_info_cursor_p->so + pdu_info_cursor_p->payload_size;
}
else {
waited_so = pdu_info_cursor_p->payload_size;
}
/* Go to next segment */
cursor_p = cursor_p->next;
if (cursor_p != NULL)
{
pdu_info_cursor_p = &((rlc_am_rx_pdu_management_t*)(cursor_p->data))->pdu_info;
LOG_D(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[SEND-STATUS] LINE %d PREPARE SENDING NACK %04d SO START %05d SO END %05d\n",
PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP),
__LINE__,
sn_cursor,
waited_so,
pdu_info_cursor_p->so);
} else {
/* Not enough resources to set a SOStart/SEnd, then set ACK_SN to current NACK_SN and stop Status PDU build */
control_pdu_info.ack_sn = sn_cursor;
status_report_completed = true;
segment_loop_end = true;
break;
}
} else {
/* contiguous segment: only update waited_so */
/* Assuming so and payload_size updated according to duplication removal done at reception ... */
waited_so += pdu_info_cursor_p->payload_size;
}
/* Find the first discontinuity and then fill SOStart/SOEnd */
while (!segment_loop_end) {
if ((cursor_p != NULL) && (pdu_info_cursor_p->sn == sn_cursor)) {
/* Go to next received PDU or PDU Segment */
cursor_p = cursor_p->next;
/* PDU segment is for the same SN*/
/* Check lsf */
segment_loop_end = (pdu_info_cursor_p->lsf == 1);
if (cursor_p != NULL) {
pdu_info_cursor_p = &((rlc_am_rx_pdu_management_t *)(cursor_p->data))->pdu_info;
}
} //end if (cursor_p != NULL) && (pdu_info_cursor_p->sn == sn_cursor)
else {
/* Previous PDU segment was the last one and did not have lsf indication : fill the latest gap */
if ((nb_bits_transmitted + RLC_AM_SN_BITS + (RLC_AM_PDU_E_BITS << 1) + (RLC_AM_STATUS_PDU_SO_LENGTH << 1)) <= nb_bits_to_transmit) {
control_pdu_info.nack_list[control_pdu_info.num_nack].nack_sn = sn_cursor;
control_pdu_info.nack_list[control_pdu_info.num_nack].so_start = waited_so;
control_pdu_info.nack_list[control_pdu_info.num_nack].so_end = RLC_AM_STATUS_PDU_SO_END_ALL_BYTES;
control_pdu_info.nack_list[control_pdu_info.num_nack].e2 = 1;
/* Set E1 for next NACK_SN. The last one will be cleared */
control_pdu_info.nack_list[control_pdu_info.num_nack].e1 = 1;
control_pdu_info.num_nack += 1;
nb_bits_transmitted += (RLC_AM_SN_BITS + (RLC_AM_PDU_E_BITS << 1) + (RLC_AM_STATUS_PDU_SO_LENGTH << 1));
LOG_D(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[SEND-STATUS] LINE %d PREPARE SENDING LAST NACK %04d SO START %05d SO END %05d\n",
PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP),
__LINE__,
sn_cursor,
waited_so,
RLC_AM_STATUS_PDU_SO_END_ALL_BYTES);
} else {
/* Not enough resources to set a SOStart/SEnd, then set ACK_SN to current NACK_SN and stop Status PDU build */
control_pdu_info.ack_sn = sn_cursor;
status_report_completed = true;
}
if (waited_so < pdu_info_cursor_p->so) {
/* SO is greater than previous received portion : gap identified to fill */
if ((nb_bits_transmitted + RLC_AM_SN_BITS + (RLC_AM_PDU_E_BITS << 1) + (RLC_AM_STATUS_PDU_SO_LENGTH << 1)) <= nb_bits_to_transmit) {
control_pdu_info.nack_list[control_pdu_info.num_nack].nack_sn = sn_cursor;
control_pdu_info.nack_list[control_pdu_info.num_nack].so_start = waited_so;
control_pdu_info.nack_list[control_pdu_info.num_nack].so_end = pdu_info_cursor_p->so - 1;
control_pdu_info.nack_list[control_pdu_info.num_nack].e2 = 1;
/* Set E1 for next NACK_SN. The last one will be cleared */
control_pdu_info.nack_list[control_pdu_info.num_nack].e1 = 1;
control_pdu_info.num_nack += 1;
nb_bits_transmitted += (RLC_AM_SN_BITS + (RLC_AM_PDU_E_BITS << 1) + (RLC_AM_STATUS_PDU_SO_LENGTH << 1));
#if TRACE_RLC_AM_STATUS_CREATION
LOG_D(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[SEND-STATUS] LINE %d PREPARE SENDING NACK %04d SO START %05d SO END %05d\n",
PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP),
__LINE__,
sn_cursor,
waited_so,
pdu_info_cursor_p->so);
#endif
}
else {
/* Not enough resources to set a SOStart/SEnd, then set ACK_SN to current NACK_SN and stop Status PDU build */
control_pdu_info.ack_sn = sn_cursor;
status_report_completed = true;
segment_loop_end = true;
break;
}
}
else {
/* contiguous segment: only update waited_so */
/* Assuming so and payload_size updated according to duplication removal done at reception ... */
waited_so += pdu_info_cursor_p->payload_size;
}
/* Go to next received PDU or PDU Segment */
cursor_p = cursor_p->next;
if (cursor_p != NULL)
{
pdu_info_cursor_p = &((rlc_am_rx_pdu_management_t*)(cursor_p->data))->pdu_info;
}
} //end if (cursor_p != NULL) && (pdu_info_cursor_p->sn == sn_cursor)
else {
/* Previous PDU segment was the last one and did not have lsf indication : fill the latest gap */
if ((nb_bits_transmitted + RLC_AM_SN_BITS + (RLC_AM_PDU_E_BITS << 1) + (RLC_AM_STATUS_PDU_SO_LENGTH << 1)) <= nb_bits_to_transmit) {
control_pdu_info.nack_list[control_pdu_info.num_nack].nack_sn = sn_cursor;
control_pdu_info.nack_list[control_pdu_info.num_nack].so_start = waited_so;
control_pdu_info.nack_list[control_pdu_info.num_nack].so_end = RLC_AM_STATUS_PDU_SO_END_ALL_BYTES;
control_pdu_info.nack_list[control_pdu_info.num_nack].e2 = 1;
/* Set E1 for next NACK_SN. The last one will be cleared */
control_pdu_info.nack_list[control_pdu_info.num_nack].e1 = 1;
control_pdu_info.num_nack += 1;
nb_bits_transmitted += (RLC_AM_SN_BITS + (RLC_AM_PDU_E_BITS << 1) + (RLC_AM_STATUS_PDU_SO_LENGTH << 1));
#if TRACE_RLC_AM_STATUS_CREATION
LOG_D(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[SEND-STATUS] LINE %d PREPARE SENDING LAST NACK %04d SO START %05d SO END %05d\n",
PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP),
__LINE__,
sn_cursor,
waited_so,
RLC_AM_STATUS_PDU_SO_END_ALL_BYTES);
#endif
}
else {
/* Not enough resources to set a SOStart/SEnd, then set ACK_SN to current NACK_SN and stop Status PDU build */
control_pdu_info.ack_sn = sn_cursor;
status_report_completed = true;
}
segment_loop_end = true;
}
} //end while (!segment_loop_end)
} // end if enough resource for transmitting at least one SOStart/SOEnd
else {
/* Not enough UL TBS to set at least one SOStart/SOEnd */
/* latest value of sn_nack shall be used as ACK_SN */
control_pdu_info.ack_sn = sn_nack;
status_report_completed = true;
}
segment_loop_end = true;
}
} //end while (!segment_loop_end)
} // end if enough resource for transmitting at least one SOStart/SOEnd
else {
/* Not enough UL TBS to set at least one SOStart/SOEnd */
/* latest value of sn_nack shall be used as ACK_SN */
control_pdu_info.ack_sn = sn_nack;
status_report_completed = true;
}
} // end while on all PDU segments of sn_cursor
else {
/* Go to next received PDU or PDU segment with different SN */
do {
cursor_p = cursor_p->next;
} while ((cursor_p != NULL) && (((rlc_am_rx_pdu_management_t*)(cursor_p->data))->pdu_info.sn == sn_cursor));
/* Go to next received PDU or PDU segment with different SN */
do {
cursor_p = cursor_p->next;
} while ((cursor_p != NULL) && (((rlc_am_rx_pdu_management_t *)(cursor_p->data))->pdu_info.sn == sn_cursor));
}
/* Increment sn_nack except if sn_cursor = vrMS and if current SN was not fully received */
if (RLC_AM_DIFF_SN(sn_cursor,rlc_pP->vr_r) < RLC_AM_DIFF_SN(rlc_pP->vr_ms,rlc_pP->vr_r)) {
sn_nack = RLC_AM_NEXT_SN(sn_cursor);
sn_nack = RLC_AM_NEXT_SN(sn_cursor);
} else {
sn_nack = rlc_pP->vr_ms;
}
else {
sn_nack = rlc_pP->vr_ms;
}
} // End main while NACK_SN
/* Clear E1 of last nack_sn entry */
// AssertFatal ((control_pdu_info.num_nack) || (all_segments_received == 0), "RLC AM Tx Status PDU Data Error no NACK_SN vrR=%d vrMS=%d lastSN_NACK=%d Completed=%d NbBytesAvailable=%d LcId=%d\n",
// rlc_pP->vr_r,rlc_pP->vr_ms,sn_nack,status_report_completed,(nb_bits_to_transmit >> 3),rlc_pP->channel_id);
if (!((control_pdu_info.num_nack) || (all_segments_received == 0))){
LOG_E(RLC, "RLC AM Tx Status PDU Data Error no NACK_SN vrR=%d vrMS=%d lastSN_NACK=%d Completed=%d NbBytesAvailable=%d LcId=%d\n",
rlc_pP->vr_r,rlc_pP->vr_ms,sn_nack,status_report_completed,(nb_bits_to_transmit >> 3),rlc_pP->channel_id);
return;
}
if (control_pdu_info.num_nack) {
control_pdu_info.nack_list[control_pdu_info.num_nack - 1].e1 = 0;
}
/* Set ACK_SN unless it was set before */
if (!status_report_completed){
control_pdu_info.ack_sn = sn_nack;
// AssertFatal ((control_pdu_info.num_nack) || (all_segments_received == 0), "RLC AM Tx Status PDU Data Error no NACK_SN vrR=%d vrMS=%d lastSN_NACK=%d Completed=%d NbBytesAvailable=%d LcId=%d\n",
// rlc_pP->vr_r,rlc_pP->vr_ms,sn_nack,status_report_completed,(nb_bits_to_transmit >> 3),rlc_pP->channel_id);
if (!((control_pdu_info.num_nack) || (all_segments_received == 0))) {
LOG_E(RLC, "RLC AM Tx Status PDU Data Error no NACK_SN vrR=%d vrMS=%d lastSN_NACK=%d Completed=%d NbBytesAvailable=%d LcId=%d\n",
rlc_pP->vr_r,rlc_pP->vr_ms,sn_nack,status_report_completed,(nb_bits_to_transmit >> 3),rlc_pP->channel_id);
return;
}
if (control_pdu_info.num_nack) {
control_pdu_info.nack_list[control_pdu_info.num_nack - 1].e1 = 0;
}
/* Set ACK_SN unless it was set before */
if (!status_report_completed) {
control_pdu_info.ack_sn = sn_nack;
}
} else {
/* reception buffer empty or not enough TBS for filling at least 1 NACK_SN + E1 + E2 */
/* reception buffer empty or not enough TBS for filling at least 1 NACK_SN + E1 + E2 */
control_pdu_info.ack_sn = rlc_pP->vr_r;
#if TRACE_RLC_AM_STATUS_CREATION
LOG_D(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[SEND-STATUS] LINE %d PREPARE SENDING ACK %04d = VR(R)\n",
PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP),
__LINE__,
control_pdu_info.ack_sn);
#endif
}
//msg ("[FRAME %5u][%s][RLC_AM][MOD %u/%u][RB %u] nb_bits_to_transmit %d\n",
// rlc_pP->module_id, rlc_pP->rb_id, ctxt_pP->frame,nb_bits_to_transmit);
#if TRACE_RLC_AM_STATUS_CREATION
LOG_D(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[SEND-STATUS] LINE %d PREPARE SENDING ACK %04d NUM NACK %d\n",
PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP),
__LINE__,
control_pdu_info.ack_sn,
control_pdu_info.num_nack);
#endif
/* encode the control pdu */
pdu_size = (nb_bits_transmitted + 7) >> 3;
// AssertFatal (pdu_size <= rlc_pP->nb_bytes_requested_by_mac, "RLC AM Tx Status PDU Data size=%d bigger than remaining TBS=%d nb_bits_transmitted=%d LcId=%d\n",
// pdu_size,rlc_pP->nb_bytes_requested_by_mac,nb_bits_transmitted, rlc_pP->channel_id);
if(pdu_size > rlc_pP->nb_bytes_requested_by_mac){
LOG_E(RLC, "RLC AM Tx Status PDU Data size=%d bigger than remaining TBS=%d nb_bits_transmitted=%d LcId=%d\n",
pdu_size,rlc_pP->nb_bytes_requested_by_mac,nb_bits_transmitted, rlc_pP->channel_id);
return;
}
// AssertFatal (pdu_size <= rlc_pP->nb_bytes_requested_by_mac, "RLC AM Tx Status PDU Data size=%d bigger than remaining TBS=%d nb_bits_transmitted=%d LcId=%d\n",
// pdu_size,rlc_pP->nb_bytes_requested_by_mac,nb_bits_transmitted, rlc_pP->channel_id);
if(pdu_size > rlc_pP->nb_bytes_requested_by_mac) {
LOG_E(RLC, "RLC AM Tx Status PDU Data size=%d bigger than remaining TBS=%d nb_bits_transmitted=%d LcId=%d\n",
pdu_size,rlc_pP->nb_bytes_requested_by_mac,nb_bits_transmitted, rlc_pP->channel_id);
return;
}
#if TRACE_RLC_AM_STATUS_CREATION
LOG_D(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[SEND-STATUS] LINE %d forecast pdu_size %d\n",
PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP),
__LINE__,
pdu_size);
#endif
tb_p = get_free_mem_block(sizeof(struct mac_tb_req) + pdu_size, __func__);
if(tb_p == NULL) return;
memset(tb_p->data, 0, sizeof(struct mac_tb_req) + pdu_size);
//estimation only ((struct mac_tb_req*)(tb_p->data))->tb_size = pdu_size;
((struct mac_tb_req*)(tb_p->data))->data_ptr = (uint8_t*)&(tb_p->data[sizeof(struct mac_tb_req)]);
((struct mac_tb_req *)(tb_p->data))->data_ptr = (uint8_t *)&(tb_p->data[sizeof(struct mac_tb_req)]);
// warning reuse of pdu_size
// TODO : rlc_am_write_status_pdu should be rewritten as not very tested ...
pdu_size = rlc_am_write_status_pdu(ctxt_pP, rlc_pP,(rlc_am_pdu_sn_10_t*)(((struct mac_tb_req*)(tb_p->data))->data_ptr), &control_pdu_info);
((struct mac_tb_req*)(tb_p->data))->tb_size = pdu_size;
pdu_size = rlc_am_write_status_pdu(ctxt_pP, rlc_pP,(rlc_am_pdu_sn_10_t *)(((struct mac_tb_req *)(tb_p->data))->data_ptr), &control_pdu_info);
((struct mac_tb_req *)(tb_p->data))->tb_size = pdu_size;
//assert((((struct mac_tb_req*)(tb_p->data))->tb_size) < 3000);
#if TRACE_RLC_AM_STATUS_CREATION
LOG_D(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[SEND-STATUS] SEND STATUS PDU SIZE %d, rlc_pP->nb_bytes_requested_by_mac %d, nb_bits_to_transmit>>3 %d\n",
PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP),
pdu_size,
rlc_pP->nb_bytes_requested_by_mac,
nb_bits_to_transmit >> 3);
#endif
// AssertFatal (pdu_size == ((nb_bits_transmitted + 7) >> 3), "RLC AM Tx Status PDU Data encoding size=%d different than expected=%d LcId=%d\n",
// pdu_size,((nb_bits_transmitted + 7) >> 3), rlc_pP->channel_id);
if(pdu_size != ((nb_bits_transmitted + 7) >> 3)){
LOG_E(RLC, "RLC AM Tx Status PDU Data encoding size=%d different than expected=%d LcId=%d\n",
pdu_size,((nb_bits_transmitted + 7) >> 3), rlc_pP->channel_id);
pdu_size = 0;
return;
}
// AssertFatal (pdu_size == ((nb_bits_transmitted + 7) >> 3), "RLC AM Tx Status PDU Data encoding size=%d different than expected=%d LcId=%d\n",
// pdu_size,((nb_bits_transmitted + 7) >> 3), rlc_pP->channel_id);
if(pdu_size != ((nb_bits_transmitted + 7) >> 3)) {
LOG_E(RLC, "RLC AM Tx Status PDU Data encoding size=%d different than expected=%d LcId=%d\n",
pdu_size,((nb_bits_transmitted + 7) >> 3), rlc_pP->channel_id);
pdu_size = 0;
return;
}
// remaining bytes to transmit for RLC (retrans pdus and new data pdus)
rlc_pP->nb_bytes_requested_by_mac = rlc_pP->nb_bytes_requested_by_mac - pdu_size;
@@ -869,7 +761,6 @@ rlc_am_send_status_pdu(
list_add_head(tb_p, &rlc_pP->control_pdu_list);
rlc_pP->stat_tx_control_pdu += 1;
rlc_pP->stat_tx_control_bytes += pdu_size;
}
File diff suppressed because it is too large Load Diff
+321 -347
View File
@@ -34,23 +34,23 @@
#include "common/utils/LOG/log.h"
#include "UTIL/OCG/OCG_vars.h"
#include "common/utils/LOG/vcd_signal_dumper.h"
#include "targets/COMMON/openairinterface5g_limits.h"
#include "assertions.h"
extern boolean_t pdcp_data_ind(
const protocol_ctxt_t* const ctxt_pP,
const protocol_ctxt_t *const ctxt_pP,
const srb_flag_t srb_flagP,
const MBMS_flag_t MBMS_flagP,
const rb_id_t rb_idP,
const sdu_size_t sdu_buffer_sizeP,
mem_block_t* const sdu_buffer_pP);
mem_block_t *const sdu_buffer_pP);
#define DEBUG_RLC_PDCP_INTERFACE 1
//#define TRACE_RLC_PAYLOAD 1
#define DEBUG_RLC_DATA_REQ 1
//-----------------------------------------------------------------------------
void rlc_util_print_hex_octets(comp_name_t componentP, unsigned char* dataP, const signed long sizeP)
void rlc_util_print_hex_octets(comp_name_t componentP, unsigned char *dataP, const signed long sizeP)
//-----------------------------------------------------------------------------
{
unsigned long octet_index = 0;
@@ -59,9 +59,6 @@ void rlc_util_print_hex_octets(comp_name_t componentP, unsigned char* dataP, con
return;
}
LOG_T(componentP, "+-----+-------------------------------------------------+\n");
LOG_T(componentP, "| | 0 1 2 3 4 5 6 7 8 9 a b c d e f |\n");
LOG_T(componentP, "+-----+-------------------------------------------------+\n");
@@ -98,38 +95,37 @@ void rlc_util_print_hex_octets(comp_name_t componentP, unsigned char* dataP, con
//-----------------------------------------------------------------------------
rlc_op_status_t rlc_stat_req (
const protocol_ctxt_t* const ctxt_pP,
const protocol_ctxt_t *const ctxt_pP,
const srb_flag_t srb_flagP,
const rb_id_t rb_idP,
unsigned int* stat_rlc_mode,
unsigned int* stat_tx_pdcp_sdu,
unsigned int* stat_tx_pdcp_bytes,
unsigned int* stat_tx_pdcp_sdu_discarded,
unsigned int* stat_tx_pdcp_bytes_discarded,
unsigned int* stat_tx_data_pdu,
unsigned int* stat_tx_data_bytes,
unsigned int* stat_tx_retransmit_pdu_by_status,
unsigned int* stat_tx_retransmit_bytes_by_status,
unsigned int* stat_tx_retransmit_pdu,
unsigned int* stat_tx_retransmit_bytes,
unsigned int* stat_tx_control_pdu,
unsigned int* stat_tx_control_bytes,
unsigned int* stat_rx_pdcp_sdu,
unsigned int* stat_rx_pdcp_bytes,
unsigned int* stat_rx_data_pdus_duplicate,
unsigned int* stat_rx_data_bytes_duplicate,
unsigned int* stat_rx_data_pdu,
unsigned int* stat_rx_data_bytes,
unsigned int* stat_rx_data_pdu_dropped,
unsigned int* stat_rx_data_bytes_dropped,
unsigned int* stat_rx_data_pdu_out_of_window,
unsigned int* stat_rx_data_bytes_out_of_window,
unsigned int* stat_rx_control_pdu,
unsigned int* stat_rx_control_bytes,
unsigned int* stat_timer_reordering_timed_out,
unsigned int* stat_timer_poll_retransmit_timed_out,
unsigned int* stat_timer_status_prohibit_timed_out)
{
unsigned int *stat_rlc_mode,
unsigned int *stat_tx_pdcp_sdu,
unsigned int *stat_tx_pdcp_bytes,
unsigned int *stat_tx_pdcp_sdu_discarded,
unsigned int *stat_tx_pdcp_bytes_discarded,
unsigned int *stat_tx_data_pdu,
unsigned int *stat_tx_data_bytes,
unsigned int *stat_tx_retransmit_pdu_by_status,
unsigned int *stat_tx_retransmit_bytes_by_status,
unsigned int *stat_tx_retransmit_pdu,
unsigned int *stat_tx_retransmit_bytes,
unsigned int *stat_tx_control_pdu,
unsigned int *stat_tx_control_bytes,
unsigned int *stat_rx_pdcp_sdu,
unsigned int *stat_rx_pdcp_bytes,
unsigned int *stat_rx_data_pdus_duplicate,
unsigned int *stat_rx_data_bytes_duplicate,
unsigned int *stat_rx_data_pdu,
unsigned int *stat_rx_data_bytes,
unsigned int *stat_rx_data_pdu_dropped,
unsigned int *stat_rx_data_bytes_dropped,
unsigned int *stat_rx_data_pdu_out_of_window,
unsigned int *stat_rx_data_bytes_out_of_window,
unsigned int *stat_rx_control_pdu,
unsigned int *stat_rx_control_bytes,
unsigned int *stat_timer_reordering_timed_out,
unsigned int *stat_timer_poll_retransmit_timed_out,
unsigned int *stat_timer_status_prohibit_timed_out) {
//-----------------------------------------------------------------------------
rlc_mode_t rlc_mode = RLC_MODE_NONE;
rlc_union_t *rlc_union_p = NULL;
@@ -137,182 +133,183 @@ rlc_op_status_t rlc_stat_req (
hashtable_rc_t h_rc;
//AssertFatal (rb_idP < NB_RB_MAX, "RB id is too high (%u/%d)!\n", rb_idP, NB_RB_MAX);
if(rb_idP >= NB_RB_MAX){
LOG_E(RLC, "RB id is too high (%u/%d)!\n", rb_idP, NB_RB_MAX);
return RLC_OP_STATUS_BAD_PARAMETER;
}
if(rb_idP >= NB_RB_MAX) {
LOG_E(RLC, "RB id is too high (%u/%d)!\n", rb_idP, NB_RB_MAX);
return RLC_OP_STATUS_BAD_PARAMETER;
}
key = RLC_COLL_KEY_VALUE(ctxt_pP->module_id, ctxt_pP->rnti, ctxt_pP->enb_flag, rb_idP, srb_flagP);
h_rc = hashtable_get(rlc_coll_p, key, (void**)&rlc_union_p);
h_rc = hashtable_get(rlc_coll_p, key, (void **)&rlc_union_p);
if (h_rc == HASH_TABLE_OK) {
rlc_mode = rlc_union_p->mode;
}
*stat_rlc_mode = rlc_mode;
switch (rlc_mode) {
case RLC_MODE_NONE:
*stat_tx_pdcp_sdu = 0;
*stat_tx_pdcp_bytes = 0;
*stat_tx_pdcp_sdu_discarded = 0;
*stat_tx_pdcp_bytes_discarded = 0;
*stat_tx_data_pdu = 0;
*stat_tx_data_bytes = 0;
*stat_tx_retransmit_pdu_by_status = 0;
*stat_tx_retransmit_bytes_by_status = 0;
*stat_tx_retransmit_pdu = 0;
*stat_tx_retransmit_bytes = 0;
*stat_tx_control_pdu = 0;
*stat_tx_control_bytes = 0;
*stat_rx_pdcp_sdu = 0;
*stat_rx_pdcp_bytes = 0;
*stat_rx_data_pdus_duplicate = 0;
*stat_rx_data_bytes_duplicate = 0;
*stat_rx_data_pdu = 0;
*stat_rx_data_bytes = 0;
*stat_rx_data_pdu_dropped = 0;
*stat_rx_data_bytes_dropped = 0;
*stat_rx_data_pdu_out_of_window = 0;
*stat_rx_data_bytes_out_of_window = 0;
*stat_rx_control_pdu = 0;
*stat_rx_control_bytes = 0;
*stat_timer_reordering_timed_out = 0;
*stat_timer_poll_retransmit_timed_out = 0;
*stat_timer_status_prohibit_timed_out = 0;
return RLC_OP_STATUS_BAD_PARAMETER;
break;
case RLC_MODE_NONE:
*stat_tx_pdcp_sdu = 0;
*stat_tx_pdcp_bytes = 0;
*stat_tx_pdcp_sdu_discarded = 0;
*stat_tx_pdcp_bytes_discarded = 0;
*stat_tx_data_pdu = 0;
*stat_tx_data_bytes = 0;
*stat_tx_retransmit_pdu_by_status = 0;
*stat_tx_retransmit_bytes_by_status = 0;
*stat_tx_retransmit_pdu = 0;
*stat_tx_retransmit_bytes = 0;
*stat_tx_control_pdu = 0;
*stat_tx_control_bytes = 0;
*stat_rx_pdcp_sdu = 0;
*stat_rx_pdcp_bytes = 0;
*stat_rx_data_pdus_duplicate = 0;
*stat_rx_data_bytes_duplicate = 0;
*stat_rx_data_pdu = 0;
*stat_rx_data_bytes = 0;
*stat_rx_data_pdu_dropped = 0;
*stat_rx_data_bytes_dropped = 0;
*stat_rx_data_pdu_out_of_window = 0;
*stat_rx_data_bytes_out_of_window = 0;
*stat_rx_control_pdu = 0;
*stat_rx_control_bytes = 0;
*stat_timer_reordering_timed_out = 0;
*stat_timer_poll_retransmit_timed_out = 0;
*stat_timer_status_prohibit_timed_out = 0;
return RLC_OP_STATUS_BAD_PARAMETER;
break;
case RLC_MODE_AM:
rlc_am_stat_req(ctxt_pP,
&rlc_union_p->rlc.am,
stat_tx_pdcp_sdu,
stat_tx_pdcp_bytes,
stat_tx_pdcp_sdu_discarded,
stat_tx_pdcp_bytes_discarded,
stat_tx_data_pdu,
stat_tx_data_bytes,
stat_tx_retransmit_pdu_by_status,
stat_tx_retransmit_bytes_by_status,
stat_tx_retransmit_pdu,
stat_tx_retransmit_bytes,
stat_tx_control_pdu,
stat_tx_control_bytes,
stat_rx_pdcp_sdu,
stat_rx_pdcp_bytes,
stat_rx_data_pdus_duplicate,
stat_rx_data_bytes_duplicate,
stat_rx_data_pdu,
stat_rx_data_bytes,
stat_rx_data_pdu_dropped,
stat_rx_data_bytes_dropped,
stat_rx_data_pdu_out_of_window,
stat_rx_data_bytes_out_of_window,
stat_rx_control_pdu,
stat_rx_control_bytes,
stat_timer_reordering_timed_out,
stat_timer_poll_retransmit_timed_out,
stat_timer_status_prohibit_timed_out);
return RLC_OP_STATUS_OK;
break;
case RLC_MODE_AM:
rlc_am_stat_req(ctxt_pP,
&rlc_union_p->rlc.am,
stat_tx_pdcp_sdu,
stat_tx_pdcp_bytes,
stat_tx_pdcp_sdu_discarded,
stat_tx_pdcp_bytes_discarded,
stat_tx_data_pdu,
stat_tx_data_bytes,
stat_tx_retransmit_pdu_by_status,
stat_tx_retransmit_bytes_by_status,
stat_tx_retransmit_pdu,
stat_tx_retransmit_bytes,
stat_tx_control_pdu,
stat_tx_control_bytes,
stat_rx_pdcp_sdu,
stat_rx_pdcp_bytes,
stat_rx_data_pdus_duplicate,
stat_rx_data_bytes_duplicate,
stat_rx_data_pdu,
stat_rx_data_bytes,
stat_rx_data_pdu_dropped,
stat_rx_data_bytes_dropped,
stat_rx_data_pdu_out_of_window,
stat_rx_data_bytes_out_of_window,
stat_rx_control_pdu,
stat_rx_control_bytes,
stat_timer_reordering_timed_out,
stat_timer_poll_retransmit_timed_out,
stat_timer_status_prohibit_timed_out);
return RLC_OP_STATUS_OK;
break;
case RLC_MODE_UM:
*stat_tx_retransmit_pdu_by_status = 0;
*stat_tx_retransmit_bytes_by_status = 0;
*stat_tx_retransmit_pdu = 0;
*stat_tx_retransmit_bytes = 0;
*stat_tx_control_pdu = 0;
*stat_tx_control_bytes = 0;
*stat_rx_data_pdu_dropped = 0;
*stat_rx_data_bytes_dropped = 0;
*stat_rx_data_pdu_out_of_window = 0;
*stat_rx_data_bytes_out_of_window = 0;
*stat_timer_poll_retransmit_timed_out = 0;
*stat_timer_status_prohibit_timed_out = 0;
rlc_um_stat_req (&rlc_union_p->rlc.um,
stat_tx_pdcp_sdu,
stat_tx_pdcp_bytes,
stat_tx_pdcp_sdu_discarded,
stat_tx_pdcp_bytes_discarded,
stat_tx_data_pdu,
stat_tx_data_bytes,
stat_rx_pdcp_sdu,
stat_rx_pdcp_bytes,
stat_rx_data_pdus_duplicate,
stat_rx_data_bytes_duplicate,
stat_rx_data_pdu,
stat_rx_data_bytes,
stat_rx_data_pdu_dropped,
stat_rx_data_bytes_dropped,
stat_rx_data_pdu_out_of_window,
stat_rx_data_bytes_out_of_window,
stat_timer_reordering_timed_out);
return RLC_OP_STATUS_OK;
break;
case RLC_MODE_UM:
*stat_tx_retransmit_pdu_by_status = 0;
*stat_tx_retransmit_bytes_by_status = 0;
*stat_tx_retransmit_pdu = 0;
*stat_tx_retransmit_bytes = 0;
*stat_tx_control_pdu = 0;
*stat_tx_control_bytes = 0;
*stat_rx_data_pdu_dropped = 0;
*stat_rx_data_bytes_dropped = 0;
*stat_rx_data_pdu_out_of_window = 0;
*stat_rx_data_bytes_out_of_window = 0;
*stat_timer_poll_retransmit_timed_out = 0;
*stat_timer_status_prohibit_timed_out = 0;
rlc_um_stat_req (&rlc_union_p->rlc.um,
stat_tx_pdcp_sdu,
stat_tx_pdcp_bytes,
stat_tx_pdcp_sdu_discarded,
stat_tx_pdcp_bytes_discarded,
stat_tx_data_pdu,
stat_tx_data_bytes,
stat_rx_pdcp_sdu,
stat_rx_pdcp_bytes,
stat_rx_data_pdus_duplicate,
stat_rx_data_bytes_duplicate,
stat_rx_data_pdu,
stat_rx_data_bytes,
stat_rx_data_pdu_dropped,
stat_rx_data_bytes_dropped,
stat_rx_data_pdu_out_of_window,
stat_rx_data_bytes_out_of_window,
stat_timer_reordering_timed_out);
return RLC_OP_STATUS_OK;
break;
case RLC_MODE_TM:
*stat_tx_pdcp_sdu = 0;
*stat_tx_pdcp_bytes = 0;
*stat_tx_pdcp_sdu_discarded = 0;
*stat_tx_pdcp_bytes_discarded = 0;
*stat_tx_data_pdu = 0;
*stat_tx_data_bytes = 0;
*stat_tx_retransmit_pdu_by_status = 0;
*stat_tx_retransmit_bytes_by_status = 0;
*stat_tx_retransmit_pdu = 0;
*stat_tx_retransmit_bytes = 0;
*stat_tx_control_pdu = 0;
*stat_tx_control_bytes = 0;
*stat_rx_pdcp_sdu = 0;
*stat_rx_pdcp_bytes = 0;
*stat_rx_data_pdus_duplicate = 0;
*stat_rx_data_bytes_duplicate = 0;
*stat_rx_data_pdu = 0;
*stat_rx_data_bytes = 0;
*stat_rx_data_pdu_dropped = 0;
*stat_rx_data_bytes_dropped = 0;
*stat_rx_data_pdu_out_of_window = 0;
*stat_rx_data_bytes_out_of_window = 0;
*stat_rx_control_pdu = 0;
*stat_rx_control_bytes = 0;
*stat_timer_reordering_timed_out = 0;
*stat_timer_poll_retransmit_timed_out = 0;
*stat_timer_status_prohibit_timed_out = 0;
return RLC_OP_STATUS_BAD_PARAMETER;
break;
case RLC_MODE_TM:
*stat_tx_pdcp_sdu = 0;
*stat_tx_pdcp_bytes = 0;
*stat_tx_pdcp_sdu_discarded = 0;
*stat_tx_pdcp_bytes_discarded = 0;
*stat_tx_data_pdu = 0;
*stat_tx_data_bytes = 0;
*stat_tx_retransmit_pdu_by_status = 0;
*stat_tx_retransmit_bytes_by_status = 0;
*stat_tx_retransmit_pdu = 0;
*stat_tx_retransmit_bytes = 0;
*stat_tx_control_pdu = 0;
*stat_tx_control_bytes = 0;
*stat_rx_pdcp_sdu = 0;
*stat_rx_pdcp_bytes = 0;
*stat_rx_data_pdus_duplicate = 0;
*stat_rx_data_bytes_duplicate = 0;
*stat_rx_data_pdu = 0;
*stat_rx_data_bytes = 0;
*stat_rx_data_pdu_dropped = 0;
*stat_rx_data_bytes_dropped = 0;
*stat_rx_data_pdu_out_of_window = 0;
*stat_rx_data_bytes_out_of_window = 0;
*stat_rx_control_pdu = 0;
*stat_rx_control_bytes = 0;
*stat_timer_reordering_timed_out = 0;
*stat_timer_poll_retransmit_timed_out = 0;
*stat_timer_status_prohibit_timed_out = 0;
return RLC_OP_STATUS_BAD_PARAMETER;
break;
default:
*stat_tx_pdcp_sdu = 0;
*stat_tx_pdcp_bytes = 0;
*stat_tx_pdcp_sdu_discarded = 0;
*stat_tx_pdcp_bytes_discarded = 0;
*stat_tx_data_pdu = 0;
*stat_tx_data_bytes = 0;
*stat_tx_retransmit_pdu_by_status = 0;
*stat_tx_retransmit_bytes_by_status = 0;
*stat_tx_retransmit_pdu = 0;
*stat_tx_retransmit_bytes = 0;
*stat_tx_control_pdu = 0;
*stat_tx_control_bytes = 0;
*stat_rx_pdcp_sdu = 0;
*stat_rx_pdcp_bytes = 0;
*stat_rx_data_pdus_duplicate = 0;
*stat_rx_data_bytes_duplicate = 0;
*stat_rx_data_pdu = 0;
*stat_rx_data_bytes = 0;
*stat_rx_data_pdu_dropped = 0;
*stat_rx_data_bytes_dropped = 0;
*stat_rx_data_pdu_out_of_window = 0;
*stat_rx_data_bytes_out_of_window = 0;
*stat_rx_control_pdu = 0;
*stat_rx_control_bytes = 0;
*stat_timer_poll_retransmit_timed_out = 0;
*stat_timer_status_prohibit_timed_out = 0;
return RLC_OP_STATUS_BAD_PARAMETER;
default:
*stat_tx_pdcp_sdu = 0;
*stat_tx_pdcp_bytes = 0;
*stat_tx_pdcp_sdu_discarded = 0;
*stat_tx_pdcp_bytes_discarded = 0;
*stat_tx_data_pdu = 0;
*stat_tx_data_bytes = 0;
*stat_tx_retransmit_pdu_by_status = 0;
*stat_tx_retransmit_bytes_by_status = 0;
*stat_tx_retransmit_pdu = 0;
*stat_tx_retransmit_bytes = 0;
*stat_tx_control_pdu = 0;
*stat_tx_control_bytes = 0;
*stat_rx_pdcp_sdu = 0;
*stat_rx_pdcp_bytes = 0;
*stat_rx_data_pdus_duplicate = 0;
*stat_rx_data_bytes_duplicate = 0;
*stat_rx_data_pdu = 0;
*stat_rx_data_bytes = 0;
*stat_rx_data_pdu_dropped = 0;
*stat_rx_data_bytes_dropped = 0;
*stat_rx_data_pdu_out_of_window = 0;
*stat_rx_data_bytes_out_of_window = 0;
*stat_rx_control_pdu = 0;
*stat_rx_control_bytes = 0;
*stat_timer_poll_retransmit_timed_out = 0;
*stat_timer_status_prohibit_timed_out = 0;
return RLC_OP_STATUS_BAD_PARAMETER;
}
}
//-----------------------------------------------------------------------------
rlc_op_status_t rlc_data_req (const protocol_ctxt_t* const ctxt_pP,
rlc_op_status_t rlc_data_req (const protocol_ctxt_t *const ctxt_pP,
const srb_flag_t srb_flagP,
const MBMS_flag_t MBMS_flagP,
const rb_id_t rb_idP,
@@ -321,18 +318,16 @@ rlc_op_status_t rlc_data_req (const protocol_ctxt_t* const ctxt_pP,
sdu_size_t sdu_sizeP,
mem_block_t *sdu_pP
#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
,const uint32_t * const sourceL2Id
,const uint32_t * const destinationL2Id
,const uint32_t *const sourceL2Id
,const uint32_t *const destinationL2Id
#endif
)
{
) {
//-----------------------------------------------------------------------------
mem_block_t *new_sdu_p = NULL;
rlc_mode_t rlc_mode = RLC_MODE_NONE;
rlc_union_t *rlc_union_p = NULL;
hash_key_t key = HASHTABLE_NOT_A_KEY_VALUE;
hashtable_rc_t h_rc;
#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0))
rlc_mbms_id_t *mbms_id_p = NULL;
logical_chan_id_t log_ch_id = 0;
@@ -351,32 +346,33 @@ rlc_op_status_t rlc_data_req (const protocol_ctxt_t* const ctxt_pP,
#else
AssertFatal(MBMS_flagP == 0, "MBMS_flagP %u", MBMS_flagP);
#endif
#if T_TRACER
if (ctxt_pP->enb_flag)
T(T_ENB_RLC_DL, T_INT(ctxt_pP->module_id), T_INT(ctxt_pP->rnti), T_INT(rb_idP), T_INT(sdu_sizeP));
#endif
if (MBMS_flagP) {
//AssertFatal (rb_idP < NB_RB_MBMS_MAX, "RB id is too high (%u/%d)!\n", rb_idP, NB_RB_MBMS_MAX);
if(rb_idP >= NB_RB_MBMS_MAX){
LOG_E(RLC, "RB id is too high (%u/%d)!\n", rb_idP, NB_RB_MBMS_MAX);
return RLC_OP_STATUS_BAD_PARAMETER;
}
if(rb_idP >= NB_RB_MBMS_MAX) {
LOG_E(RLC, "RB id is too high (%u/%d)!\n", rb_idP, NB_RB_MBMS_MAX);
return RLC_OP_STATUS_BAD_PARAMETER;
}
} else {
//AssertFatal (rb_idP < NB_RB_MAX, "RB id is too high (%u/%d)!\n", rb_idP, NB_RB_MAX);
if(rb_idP >= NB_RB_MAX){
LOG_E(RLC, "RB id is too high (%u/%d)!\n", rb_idP, NB_RB_MAX);
return RLC_OP_STATUS_BAD_PARAMETER;
}
if(rb_idP >= NB_RB_MAX) {
LOG_E(RLC, "RB id is too high (%u/%d)!\n", rb_idP, NB_RB_MAX);
return RLC_OP_STATUS_BAD_PARAMETER;
}
}
//DevAssert(sdu_pP != NULL);
if(sdu_pP == NULL){
LOG_E(RLC, "sdu_pP == NULL\n");
return RLC_OP_STATUS_BAD_PARAMETER;
}
if(sdu_pP == NULL) {
LOG_E(RLC, "sdu_pP == NULL\n");
return RLC_OP_STATUS_BAD_PARAMETER;
}
//DevCheck(sdu_sizeP > 0, sdu_sizeP, 0, 0);
if(sdu_sizeP <= 0) {
LOG_E(RLC, "sdu_sizeP %d, file %s, line %d\n", sdu_sizeP, __FILE__ ,__LINE__);
@@ -386,9 +382,7 @@ rlc_op_status_t rlc_data_req (const protocol_ctxt_t* const ctxt_pP,
#if (LTE_RRC_VERSION < MAKE_VERSION(10, 0, 0))
DevCheck(MBMS_flagP == 0, MBMS_flagP, 0, 0);
#endif
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RLC_DATA_REQ,VCD_FUNCTION_IN);
#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0))
if (MBMS_flagP == TRUE) {
@@ -402,31 +396,31 @@ rlc_op_status_t rlc_data_req (const protocol_ctxt_t* const ctxt_pP,
key = RLC_COLL_KEY_MBMS_VALUE(ctxt_pP->module_id, ctxt_pP->rnti, ctxt_pP->enb_flag, mbms_id_p->service_id, mbms_id_p->session_id);
}
if (sourceL2Id && destinationL2Id){
LOG_I (RLC, "RLC_COLL_KEY_VALUE: ctxt_pP->module_id: %d, ctxt_pP->rnti: %d, ctxt_pP->enb_flag: %d, rb_idP:%d, srb_flagP: %d \n \n", ctxt_pP->module_id, ctxt_pP->rnti, ctxt_pP->enb_flag, rb_idP, srb_flagP);
key = RLC_COLL_KEY_VALUE(ctxt_pP->module_id, ctxt_pP->rnti, ctxt_pP->enb_flag, rb_idP, srb_flagP);
//Thinh's line originally uncommented
//key = RLC_COLL_KEY_SOURCE_DEST_VALUE(ctxt_pP->module_id, ctxt_pP->rnti, ctxt_pP->enb_flag, rb_idP, *sourceL2Id, *destinationL2Id, srb_flagP);
//key_lcid = RLC_COLL_KEY_LCID_SOURCE_DEST_VALUE(ctxt_pP->module_id, ctxt_pP->rnti, ctxt_pP->enb_flag, chan_idP, *sourceL2Id, *destinationL2Id, srb_flagP);
if (sourceL2Id && destinationL2Id) {
LOG_D (RLC, "RLC_COLL_KEY_VALUE: ctxt_pP->module_id: %d, ctxt_pP->rnti: %d, ctxt_pP->enb_flag: %d, rb_idP:%d, srb_flagP: %d \n \n", ctxt_pP->module_id, ctxt_pP->rnti, ctxt_pP->enb_flag, rb_idP,
srb_flagP);
key = RLC_COLL_KEY_VALUE(ctxt_pP->module_id, ctxt_pP->rnti, ctxt_pP->enb_flag, rb_idP, srb_flagP);
//Thinh's line originally uncommented
//key = RLC_COLL_KEY_SOURCE_DEST_VALUE(ctxt_pP->module_id, ctxt_pP->rnti, ctxt_pP->enb_flag, rb_idP, *sourceL2Id, *destinationL2Id, srb_flagP);
//key_lcid = RLC_COLL_KEY_LCID_SOURCE_DEST_VALUE(ctxt_pP->module_id, ctxt_pP->rnti, ctxt_pP->enb_flag, chan_idP, *sourceL2Id, *destinationL2Id, srb_flagP);
} else
#endif
{
LOG_I (RLC, "RLC_COLL_KEY_VALUE: ctxt_pP->module_id: %d, ctxt_pP->rnti: %d, ctxt_pP->enb_flag: %d, rb_idP:%d, srb_flagP: %d \n \n", ctxt_pP->module_id, ctxt_pP->rnti, ctxt_pP->enb_flag, rb_idP, srb_flagP);
LOG_D (RLC, "RLC_COLL_KEY_VALUE: ctxt_pP->module_id: %d, ctxt_pP->rnti: %d, ctxt_pP->enb_flag: %d, rb_idP:%d, srb_flagP: %d \n \n", ctxt_pP->module_id, ctxt_pP->rnti, ctxt_pP->enb_flag, rb_idP,
srb_flagP);
key = RLC_COLL_KEY_VALUE(ctxt_pP->module_id, ctxt_pP->rnti, ctxt_pP->enb_flag, rb_idP, srb_flagP);
}
h_rc = hashtable_get(rlc_coll_p, key, (void**)&rlc_union_p);
h_rc = hashtable_get(rlc_coll_p, key, (void **)&rlc_union_p);
if (h_rc == HASH_TABLE_OK) {
rlc_mode = rlc_union_p->mode;
} else {
rlc_mode = RLC_MODE_NONE;
//AssertFatal (0 , "RLC not configured key %ju\n", key);
LOG_E(RLC, "not configured key %lu\n", key);
return RLC_OP_STATUS_OUT_OF_RESSOURCES;
LOG_E(RLC, "not configured key %lu\n", key);
return RLC_OP_STATUS_OUT_OF_RESSOURCES;
}
if (MBMS_flagP == 0) {
@@ -434,111 +428,105 @@ rlc_op_status_t rlc_data_req (const protocol_ctxt_t* const ctxt_pP,
PROTOCOL_CTXT_ARGS(ctxt_pP),
rb_idP);
#if defined(TRACE_RLC_PAYLOAD)
rlc_util_print_hex_octets(RLC, (unsigned char*)sdu_pP->data, sdu_sizeP);
rlc_util_print_hex_octets(RLC, (unsigned char *)sdu_pP->data, sdu_sizeP);
#endif
#ifdef DEBUG_RLC_DATA_REQ
LOG_D(RLC,"RLC_TYPE : %d\n", rlc_mode);
#endif
switch (rlc_mode) {
case RLC_MODE_NONE:
free_mem_block(sdu_pP, __func__);
LOG_E(RLC, PROTOCOL_CTXT_FMT" Received RLC_MODE_NONE as rlc_type for rb_id %u\n",
PROTOCOL_CTXT_ARGS(ctxt_pP),
rb_idP);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RLC_DATA_REQ,VCD_FUNCTION_OUT);
return RLC_OP_STATUS_BAD_PARAMETER;
case RLC_MODE_NONE:
free_mem_block(sdu_pP, __func__);
LOG_E(RLC, PROTOCOL_CTXT_FMT" Received RLC_MODE_NONE as rlc_type for rb_id %u\n",
PROTOCOL_CTXT_ARGS(ctxt_pP),
rb_idP);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RLC_DATA_REQ,VCD_FUNCTION_OUT);
return RLC_OP_STATUS_BAD_PARAMETER;
case RLC_MODE_AM:
case RLC_MODE_AM:
#ifdef DEBUG_RLC_DATA_REQ
LOG_D(RLC,"RLC_MODE_AM\n");
LOG_D(RLC,"RLC_MODE_AM\n");
#endif
new_sdu_p = get_free_mem_block (sdu_sizeP + sizeof (struct rlc_am_data_req_alloc), __func__);
new_sdu_p = get_free_mem_block (sdu_sizeP + sizeof (struct rlc_am_data_req_alloc), __func__);
if (new_sdu_p != NULL) {
// PROCESS OF COMPRESSION HERE:
memset (new_sdu_p->data, 0, sizeof (struct rlc_am_data_req_alloc));
memcpy (&new_sdu_p->data[sizeof (struct rlc_am_data_req_alloc)], &sdu_pP->data[0], sdu_sizeP);
if (new_sdu_p != NULL) {
// PROCESS OF COMPRESSION HERE:
memset (new_sdu_p->data, 0, sizeof (struct rlc_am_data_req_alloc));
memcpy (&new_sdu_p->data[sizeof (struct rlc_am_data_req_alloc)], &sdu_pP->data[0], sdu_sizeP);
((struct rlc_am_data_req *) (new_sdu_p->data))->data_size = sdu_sizeP;
((struct rlc_am_data_req *) (new_sdu_p->data))->conf = confirmP;
((struct rlc_am_data_req *) (new_sdu_p->data))->mui = muiP;
((struct rlc_am_data_req *) (new_sdu_p->data))->data_offset = sizeof (struct rlc_am_data_req_alloc);
free_mem_block(sdu_pP, __func__);
rlc_am_data_req(ctxt_pP, &rlc_union_p->rlc.am, new_sdu_p);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RLC_DATA_REQ,VCD_FUNCTION_OUT);
return RLC_OP_STATUS_OK;
} else {
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RLC_DATA_REQ,VCD_FUNCTION_OUT);
free_mem_block(sdu_pP, __func__);
return RLC_OP_STATUS_INTERNAL_ERROR;
}
((struct rlc_am_data_req *) (new_sdu_p->data))->data_size = sdu_sizeP;
((struct rlc_am_data_req *) (new_sdu_p->data))->conf = confirmP;
((struct rlc_am_data_req *) (new_sdu_p->data))->mui = muiP;
((struct rlc_am_data_req *) (new_sdu_p->data))->data_offset = sizeof (struct rlc_am_data_req_alloc);
break;
case RLC_MODE_UM:
/* TODO: this is a hack, needs better solution. Let's not use too
* much memory and store at maximum 5 millions bytes.
*/
/* look for HACK_RLC_UM_LIMIT for others places related to the hack. Please do not remove this comment. */
if (rlc_um_get_buffer_occupancy(&rlc_union_p->rlc.um) > 5000000) {
free_mem_block(sdu_pP, __func__);
return RLC_OP_STATUS_OUT_OF_RESSOURCES;
}
new_sdu_p = get_free_mem_block (sdu_sizeP + sizeof (struct rlc_um_data_req_alloc), __func__);
if (new_sdu_p != NULL) {
// PROCESS OF COMPRESSION HERE:
memset (new_sdu_p->data, 0, sizeof (struct rlc_um_data_req_alloc));
memcpy (&new_sdu_p->data[sizeof (struct rlc_um_data_req_alloc)], &sdu_pP->data[0], sdu_sizeP);
((struct rlc_um_data_req *) (new_sdu_p->data))->data_size = sdu_sizeP;
((struct rlc_um_data_req *) (new_sdu_p->data))->data_offset = sizeof (struct rlc_um_data_req_alloc);
free_mem_block(sdu_pP, __func__);
rlc_um_data_req(ctxt_pP, &rlc_union_p->rlc.um, new_sdu_p);
//free_mem_block(new_sdu, __func__);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RLC_DATA_REQ,VCD_FUNCTION_OUT);
return RLC_OP_STATUS_OK;
} else {
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RLC_DATA_REQ,VCD_FUNCTION_OUT);
free_mem_block(sdu_pP, __func__);
return RLC_OP_STATUS_INTERNAL_ERROR;
}
break;
case RLC_MODE_TM:
new_sdu_p = get_free_mem_block (sdu_sizeP + sizeof (struct rlc_tm_data_req_alloc), __func__);
if (new_sdu_p != NULL) {
// PROCESS OF COMPRESSION HERE:
memset (new_sdu_p->data, 0, sizeof (struct rlc_tm_data_req_alloc));
memcpy (&new_sdu_p->data[sizeof (struct rlc_tm_data_req_alloc)], &sdu_pP->data[0], sdu_sizeP);
((struct rlc_tm_data_req *) (new_sdu_p->data))->data_size = sdu_sizeP;
((struct rlc_tm_data_req *) (new_sdu_p->data))->data_offset = sizeof (struct rlc_tm_data_req_alloc);
free_mem_block(sdu_pP, __func__);
rlc_tm_data_req(ctxt_pP, &rlc_union_p->rlc.tm, new_sdu_p);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RLC_DATA_REQ,VCD_FUNCTION_OUT);
return RLC_OP_STATUS_OK;
} else {
//handle_event(ERROR,"FILE %s FONCTION rlc_data_req() LINE %s : out of memory\n", __FILE__, __LINE__);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RLC_DATA_REQ,VCD_FUNCTION_OUT);
free_mem_block(sdu_pP, __func__);
return RLC_OP_STATUS_INTERNAL_ERROR;
}
break;
default:
free_mem_block(sdu_pP, __func__);
rlc_am_data_req(ctxt_pP, &rlc_union_p->rlc.am, new_sdu_p);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RLC_DATA_REQ,VCD_FUNCTION_OUT);
return RLC_OP_STATUS_OK;
} else {
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RLC_DATA_REQ,VCD_FUNCTION_OUT);
free_mem_block(sdu_pP, __func__);
return RLC_OP_STATUS_INTERNAL_ERROR;
}
break;
case RLC_MODE_UM:
/* TODO: this is a hack, needs better solution. Let's not use too
* much memory and store at maximum 5 millions bytes.
*/
/* look for HACK_RLC_UM_LIMIT for others places related to the hack. Please do not remove this comment. */
if (rlc_um_get_buffer_occupancy(&rlc_union_p->rlc.um) > 5000000) {
free_mem_block(sdu_pP, __func__);
return RLC_OP_STATUS_OUT_OF_RESSOURCES;
}
new_sdu_p = get_free_mem_block (sdu_sizeP + sizeof (struct rlc_um_data_req_alloc), __func__);
if (new_sdu_p != NULL) {
// PROCESS OF COMPRESSION HERE:
memset (new_sdu_p->data, 0, sizeof (struct rlc_um_data_req_alloc));
memcpy (&new_sdu_p->data[sizeof (struct rlc_um_data_req_alloc)], &sdu_pP->data[0], sdu_sizeP);
((struct rlc_um_data_req *) (new_sdu_p->data))->data_size = sdu_sizeP;
((struct rlc_um_data_req *) (new_sdu_p->data))->data_offset = sizeof (struct rlc_um_data_req_alloc);
free_mem_block(sdu_pP, __func__);
rlc_um_data_req(ctxt_pP, &rlc_union_p->rlc.um, new_sdu_p);
//free_mem_block(new_sdu, __func__);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RLC_DATA_REQ,VCD_FUNCTION_OUT);
return RLC_OP_STATUS_OK;
} else {
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RLC_DATA_REQ,VCD_FUNCTION_OUT);
free_mem_block(sdu_pP, __func__);
return RLC_OP_STATUS_INTERNAL_ERROR;
}
break;
case RLC_MODE_TM:
new_sdu_p = get_free_mem_block (sdu_sizeP + sizeof (struct rlc_tm_data_req_alloc), __func__);
if (new_sdu_p != NULL) {
// PROCESS OF COMPRESSION HERE:
memset (new_sdu_p->data, 0, sizeof (struct rlc_tm_data_req_alloc));
memcpy (&new_sdu_p->data[sizeof (struct rlc_tm_data_req_alloc)], &sdu_pP->data[0], sdu_sizeP);
((struct rlc_tm_data_req *) (new_sdu_p->data))->data_size = sdu_sizeP;
((struct rlc_tm_data_req *) (new_sdu_p->data))->data_offset = sizeof (struct rlc_tm_data_req_alloc);
free_mem_block(sdu_pP, __func__);
rlc_tm_data_req(ctxt_pP, &rlc_union_p->rlc.tm, new_sdu_p);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RLC_DATA_REQ,VCD_FUNCTION_OUT);
return RLC_OP_STATUS_OK;
} else {
//handle_event(ERROR,"FILE %s FONCTION rlc_data_req() LINE %s : out of memory\n", __FILE__, __LINE__);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RLC_DATA_REQ,VCD_FUNCTION_OUT);
free_mem_block(sdu_pP, __func__);
return RLC_OP_STATUS_INTERNAL_ERROR;
}
break;
default:
free_mem_block(sdu_pP, __func__);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RLC_DATA_REQ,VCD_FUNCTION_OUT);
return RLC_OP_STATUS_INTERNAL_ERROR;
}
#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0))
@@ -557,7 +545,6 @@ rlc_op_status_t rlc_data_req (const protocol_ctxt_t* const ctxt_pP,
((struct rlc_um_data_req *) (new_sdu_p->data))->data_offset = sizeof (struct rlc_um_data_req_alloc);
free_mem_block(sdu_pP, __func__);
rlc_um_data_req(ctxt_pP, &rlc_union_p->rlc.um, new_sdu_p);
//free_mem_block(new_sdu, __func__);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RLC_DATA_REQ,VCD_FUNCTION_OUT);
return RLC_OP_STATUS_OK;
@@ -578,8 +565,7 @@ rlc_op_status_t rlc_data_req (const protocol_ctxt_t* const ctxt_pP,
#else
}
else /* MBMS_flag != 0 */
{
else { /* MBMS_flag != 0 */
free_mem_block(sdu_pP, __func__);
LOG_E(RLC, "MBMS_flag != 0 while Rel10/Rel14 is not defined...\n");
//handle_event(ERROR,"FILE %s FONCTION rlc_data_req() LINE %s : parameter module_id out of bounds :%d\n", __FILE__, __LINE__, module_idP);
@@ -592,32 +578,27 @@ rlc_op_status_t rlc_data_req (const protocol_ctxt_t* const ctxt_pP,
//-----------------------------------------------------------------------------
void rlc_data_ind (
const protocol_ctxt_t* const ctxt_pP,
const protocol_ctxt_t *const ctxt_pP,
const srb_flag_t srb_flagP,
const MBMS_flag_t MBMS_flagP,
const rb_id_t rb_idP,
const sdu_size_t sdu_sizeP,
mem_block_t *sdu_pP)
{
mem_block_t *sdu_pP) {
//-----------------------------------------------------------------------------
#if defined(TRACE_RLC_PAYLOAD)
LOG_D(RLC, PROTOCOL_CTXT_FMT"[%s %u] Display of rlc_data_ind: size %u\n",
PROTOCOL_CTXT_ARGS(ctxt_pP),
(srb_flagP) ? "SRB" : "DRB",
rb_idP,
sdu_sizeP);
rlc_util_print_hex_octets(RLC, (unsigned char*)sdu_pP->data, sdu_sizeP);
rlc_util_print_hex_octets(RLC, (unsigned char *)sdu_pP->data, sdu_sizeP);
#endif
#if T_TRACER
if (ctxt_pP->enb_flag)
T(T_ENB_RLC_UL, T_INT(ctxt_pP->module_id), T_INT(ctxt_pP->rnti), T_INT(rb_idP), T_INT(sdu_sizeP));
#endif
pdcp_data_ind (
ctxt_pP,
srb_flagP,
@@ -627,14 +608,12 @@ void rlc_data_ind (
sdu_pP);
}
//-----------------------------------------------------------------------------
void rlc_data_conf (const protocol_ctxt_t* const ctxt_pP,
void rlc_data_conf (const protocol_ctxt_t *const ctxt_pP,
const srb_flag_t srb_flagP,
const rb_id_t rb_idP,
const mui_t muiP,
const rlc_tx_status_t statusP)
{
const rlc_tx_status_t statusP) {
//-----------------------------------------------------------------------------
if (srb_flagP) {
if (rlc_rrc_data_conf != NULL) {
rlc_rrc_data_conf (ctxt_pP, rb_idP , muiP, statusP);
@@ -643,20 +622,17 @@ void rlc_data_conf (const protocol_ctxt_t* const ctxt_pP,
}
//-----------------------------------------------------------------------------
int
rlc_module_init (void)
{
rlc_module_init (void) {
//-----------------------------------------------------------------------------
int k;
module_id_t module_id1;
/* for no gcc warnings */
(void)k;
LOG_D(RLC, "MODULE INIT\n");
rlc_rrc_data_ind = NULL;
rlc_rrc_data_conf = NULL;
rlc_coll_p = hashtable_create ((LTE_maxDRB + 2) * NUMBER_OF_UE_MAX, NULL, rb_free_rlc_union);
rlc_coll_p = hashtable_create ((LTE_maxDRB + 2) * 16, NULL, rb_free_rlc_union);
//AssertFatal(rlc_coll_p != NULL, "UNRECOVERABLE error, RLC hashtable_create failed");
if(rlc_coll_p == NULL) {
LOG_E(RLC, "UNRECOVERABLE error, RLC hashtable_create failed\n");
@@ -694,7 +670,6 @@ rlc_module_init (void)
}
pool_buffer_init();
return(0);
}
//-----------------------------------------------------------------------------
@@ -706,8 +681,7 @@ rlc_module_cleanup (void)
}
//-----------------------------------------------------------------------------
void
rlc_layer_init (void)
{
rlc_layer_init (void) {
//-----------------------------------------------------------------------------
}
//-----------------------------------------------------------------------------
+10
View File
@@ -64,6 +64,8 @@
#include "rrc_nas_primitives.h"
#include "COMMON/platform_types.h"
#define MAKE_VERSION(a,b,c) ((a)*256+(b)*16+(c))
struct rb_entity {
nasRadioBearerId_t rab_id;
nasSapId_t sapi;
@@ -160,6 +162,10 @@ typedef struct pdcp_data_req_header_s {
sdu_size_t data_size;
signed int inst;
ip_traffic_type_t traffic_type;
#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
uint32_t sourceL2Id;
uint32_t destinationL2Id;
#endif
} pdcp_data_req_header_t;
typedef struct pdcp_data_ind_header_s {
@@ -167,6 +173,10 @@ typedef struct pdcp_data_ind_header_s {
sdu_size_t data_size;
signed int inst;
ip_traffic_type_t dummy_traffic_type;
#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
uint32_t sourceL2Id;
uint32_t destinationL2Id;
#endif
} pdcp_data_ind_header_t;
extern struct net_device *nasdev[NB_INSTANCES_MAX];
+10 -1
View File
@@ -304,7 +304,16 @@ ue_ip_common_ip2wireless(
if (dst_addr) {
printk("[UE_IP_DRV][%s] Dest %d.%d.%d.%d\n",__FUNCTION__, dst_addr[0],dst_addr[1],dst_addr[2],dst_addr[3]);
}
// modify inst by IP address for the U-Plane of multiple UEs while L2 fapi simulator start
#ifdef UESIM_EXPANSION
if ((src_addr[3] - 2)> instP) {
pdcph.inst = src_addr[3] - 2;
printk("[UE_IP_DRV] change INST from %d to %d\n",instP, pdcph.inst);
instP = src_addr[3] - 2;
priv_p=netdev_priv(ue_ip_dev[instP]);
}
#endif
// modify inst by IP address for the U-Plane of multiple UEs while L2 fapi simulator end
//get Ipv4 address and pass to PCDP header
printk("[UE_IP_DRV] source Id: 0x%08x\n",pdcph.sourceL2Id );
printk("[UE_IP_DRV] destinationL2Id Id: 0x%08x\n",pdcph.destinationL2Id );
+1 -1
View File
@@ -394,7 +394,7 @@ int init_module (void)
for (inst=0; inst<UE_IP_NB_INSTANCES_MAX; inst++) {
printk("[UE_IP_DRV][%s] begin init instance %d\n", __FUNCTION__,inst);
sprintf(devicename,"oip%d",inst);
sprintf(devicename,"oip%d",inst+1);
#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 17, 0)
ue_ip_dev[inst] = alloc_netdev(sizeof(ue_ip_priv_t),devicename, ue_ip_init);
#else
+11
View File
@@ -128,6 +128,17 @@ typedef struct IF_Module_s{
pthread_mutex_t if_mutex;
}IF_Module_t;
// These mutex is used for multiple UEs L2 FAPI simulator.
// Each UEs set these value in UL and UL_INFO is shared in all UE's thread.
typedef struct {
pthread_mutex_t rx_mutex;
pthread_mutex_t crc_mutex;
pthread_mutex_t sr_mutex;
pthread_mutex_t harq_mutex;
pthread_mutex_t cqi_mutex;
pthread_mutex_t rach_mutex;
}FILL_UL_INFO_MUTEX_t;
/*Initial */
IF_Module_t *IF_Module_init(int Mod_id);
void IF_Module_kill(int Mod_id);
+82 -22
View File
@@ -25,7 +25,11 @@ extern int oai_nfapi_rach_ind(nfapi_rach_indication_t *rach_ind);
void configure_nfapi_pnf(char *vnf_ip_addr, int vnf_p5_port, char *pnf_ip_addr, int pnf_p7_port, int vnf_p7_port);
UL_IND_t *UL_INFO = NULL;
nfapi_tx_request_pdu_t* tx_request_pdu_list = NULL;
nfapi_dl_config_request_t* dl_config_req = NULL;
nfapi_ul_config_request_t* ul_config_req = NULL;
nfapi_hi_dci0_request_t* hi_dci0_req = NULL;
//extern uint8_t nfapi_pnf;
//UL_IND_t *UL_INFO;
@@ -47,7 +51,9 @@ void fill_rx_indication_UE_MAC(module_id_t Mod_id,int frame,int subframe, UL_IND
int timing_advance_update;
pthread_mutex_lock(&UE_mac_inst[Mod_id].UL_INFO_mutex);
// pthread_mutex_lock(&UE_mac_inst[Mod_id].UL_INFO_mutex);
// change for mutiple UE's simulation.
pthread_mutex_lock(&fill_ul_mutex.rx_mutex);
UL_INFO->rx_ind.sfn_sf = frame<<4| subframe;
@@ -65,7 +71,11 @@ void fill_rx_indication_UE_MAC(module_id_t Mod_id,int frame,int subframe, UL_IND
//pdu->rx_indication_rel8.length = eNB->ulsch[UE_id]->harq_processes[harq_pid]->TBS>>3;
pdu->rx_indication_rel8.length = buflen;
pdu->rx_indication_rel8.offset = 1; // DJP - I dont understand - but broken unless 1 ???? 0; // filled in at the end of the UL_INFO formation
pdu->data = ulsch_buffer;
// ulsch_buffer is necessary to keep its value.
//pdu->data = ulsch_buffer;
pdu->data = malloc(buflen);
memcpy(pdu->data,ulsch_buffer,buflen);
// estimate timing advance for MAC
//sync_pos = lte_est_timing_advance_pusch(eNB,UE_id);
timing_advance_update = 0; // Don't know what to put here
@@ -80,7 +90,9 @@ void fill_rx_indication_UE_MAC(module_id_t Mod_id,int frame,int subframe, UL_IND
UL_INFO->rx_ind.rx_indication_body.number_of_pdus++;
UL_INFO->rx_ind.sfn_sf = frame<<4 | subframe;
pthread_mutex_unlock(&UE_mac_inst[Mod_id].UL_INFO_mutex);
// pthread_mutex_unlock(&UE_mac_inst[Mod_id].UL_INFO_mutex);
// change for mutiple UE's simulation.
pthread_mutex_unlock(&fill_ul_mutex.rx_mutex);
}
@@ -88,7 +100,9 @@ void fill_rx_indication_UE_MAC(module_id_t Mod_id,int frame,int subframe, UL_IND
void fill_sr_indication_UE_MAC(int Mod_id,int frame,int subframe, UL_IND_t *UL_INFO, uint16_t rnti) {
pthread_mutex_lock(&UE_mac_inst[Mod_id].UL_INFO_mutex);
// change for mutiple UE's simulation.
//pthread_mutex_lock(&UE_mac_inst[Mod_id].UL_INFO_mutex);
pthread_mutex_lock(&fill_ul_mutex.sr_mutex);
nfapi_sr_indication_t *sr_ind = &UL_INFO->sr_ind;
nfapi_sr_indication_body_t *sr_ind_body = &sr_ind->sr_indication_body;
@@ -122,13 +136,17 @@ void fill_sr_indication_UE_MAC(int Mod_id,int frame,int subframe, UL_IND_t *UL_I
//UL_INFO->rx_ind.rx_indication_body.number_of_pdus++;
sr_ind_body->number_of_srs++;
pthread_mutex_unlock(&UE_mac_inst[Mod_id].UL_INFO_mutex);
// change for mutiple UE's simulation.
// pthread_mutex_unlock(&UE_mac_inst[Mod_id].UL_INFO_mutex);
pthread_mutex_unlock(&fill_ul_mutex.sr_mutex);
}
void fill_crc_indication_UE_MAC(int Mod_id,int frame,int subframe, UL_IND_t *UL_INFO, uint8_t crc_flag, int index, uint16_t rnti) {
pthread_mutex_lock(&UE_mac_inst[Mod_id].UL_INFO_mutex);
// change for mutiple UE's simulation.
//pthread_mutex_lock(&UE_mac_inst[Mod_id].UL_INFO_mutex);
pthread_mutex_lock(&fill_ul_mutex.crc_mutex);
// REMEMBER HAVE EXCHANGED THE FOLLOWING TWO LINES HERE!
nfapi_crc_indication_pdu_t *pdu = &UL_INFO->crc_ind.crc_indication_body.crc_pdu_list[UL_INFO->crc_ind.crc_indication_body.number_of_crcs];
@@ -151,14 +169,21 @@ void fill_crc_indication_UE_MAC(int Mod_id,int frame,int subframe, UL_IND_t *UL_
LOG_D(PHY, "%s() rnti:%04x pdus:%d\n", __FUNCTION__, pdu->rx_ue_information.rnti, UL_INFO->crc_ind.crc_indication_body.number_of_crcs);
pthread_mutex_unlock(&UE_mac_inst[Mod_id].UL_INFO_mutex);
// change for mutiple UE's simulation.
// pthread_mutex_unlock(&UE_mac_inst[Mod_id].UL_INFO_mutex);
pthread_mutex_unlock(&fill_ul_mutex.crc_mutex);
}
void fill_rach_indication_UE_MAC(int Mod_id,int frame,int subframe, UL_IND_t *UL_INFO, uint8_t ra_PreambleIndex, uint16_t ra_RNTI) {
LOG_D(MAC, "fill_rach_indication_UE_MAC 1 \n");
pthread_mutex_lock(&UE_mac_inst[Mod_id].UL_INFO_mutex);
UL_INFO = (UL_IND_t*)malloc(sizeof(UL_IND_t));
// change for mutiple UE's simulation.
// pthread_mutex_lock(&UE_mac_inst[Mod_id].UL_INFO_mutex);
pthread_mutex_lock(&fill_ul_mutex.rach_mutex);
// memory allocation and free memory of UL_INFO are done in UE_phy_stub_single_thread_rxn_txnp4.
// UL_INFO = (UL_IND_t*)malloc(sizeof(UL_IND_t));
UL_INFO->rach_ind.rach_indication_body.number_of_preambles = 1;
@@ -195,16 +220,22 @@ void fill_rach_indication_UE_MAC(int Mod_id,int frame,int subframe, UL_IND_t *UL
// with that branch.
oai_nfapi_rach_ind(&UL_INFO->rach_ind);
free(UL_INFO->rach_ind.rach_indication_body.preamble_list);
free(UL_INFO);
// memory allocation and free memory of UL_INFO are done in UE_phy_stub_single_thread_rxn_txnp4.
//free(UL_INFO);
//}
pthread_mutex_unlock(&UE_mac_inst[Mod_id].UL_INFO_mutex);
// change for mutiple UE's simulation.
// pthread_mutex_unlock(&UE_mac_inst[Mod_id].UL_INFO_mutex);
pthread_mutex_unlock(&fill_ul_mutex.rach_mutex);
}
void fill_ulsch_cqi_indication_UE_MAC(int Mod_id, uint16_t frame,uint8_t subframe, UL_IND_t *UL_INFO, uint16_t rnti) {
pthread_mutex_lock(&UE_mac_inst[Mod_id].UL_INFO_mutex);
// change for mutiple UE's simulation.
//pthread_mutex_lock(&UE_mac_inst[Mod_id].UL_INFO_mutex);
pthread_mutex_lock(&fill_ul_mutex.cqi_mutex);
nfapi_cqi_indication_pdu_t *pdu = &UL_INFO->cqi_ind.cqi_pdu_list[UL_INFO->cqi_ind.number_of_cqis];
nfapi_cqi_indication_raw_pdu_t *raw_pdu = &UL_INFO->cqi_ind.cqi_raw_pdu_list[UL_INFO->cqi_ind.number_of_cqis];
@@ -233,14 +264,18 @@ void fill_ulsch_cqi_indication_UE_MAC(int Mod_id, uint16_t frame,uint8_t subfram
UL_INFO->cqi_ind.number_of_cqis++;
pthread_mutex_unlock(&UE_mac_inst[Mod_id].UL_INFO_mutex);
// change for mutiple UE's simulation.
//pthread_mutex_unlock(&UE_mac_inst[Mod_id].UL_INFO_mutex);
pthread_mutex_unlock(&fill_ul_mutex.cqi_mutex);
}
void fill_ulsch_harq_indication_UE_MAC(int Mod_id, int frame,int subframe, UL_IND_t *UL_INFO, nfapi_ul_config_ulsch_harq_information *harq_information, uint16_t rnti)
{
pthread_mutex_lock(&UE_mac_inst[Mod_id].UL_INFO_mutex);
// change for mutiple UE's simulation.
//pthread_mutex_lock(&UE_mac_inst[Mod_id].UL_INFO_mutex);
pthread_mutex_lock(&fill_ul_mutex.harq_mutex);
nfapi_harq_indication_pdu_t *pdu = &UL_INFO->harq_ind.harq_indication_body.harq_pdu_list[UL_INFO->harq_ind.harq_indication_body.number_of_harqs];
int i;
@@ -271,8 +306,9 @@ void fill_ulsch_harq_indication_UE_MAC(int Mod_id, int frame,int subframe, UL_IN
}
UL_INFO->harq_ind.harq_indication_body.number_of_harqs++;
pthread_mutex_unlock(&UE_mac_inst[Mod_id].UL_INFO_mutex);
}
// change for mutiple UE's simulation.
//pthread_mutex_unlock(&UE_mac_inst[Mod_id].UL_INFO_mutex);
pthread_mutex_unlock(&fill_ul_mutex.harq_mutex);}
void fill_uci_harq_indication_UE_MAC(int Mod_id,
@@ -285,7 +321,10 @@ void fill_uci_harq_indication_UE_MAC(int Mod_id,
uint16_t tdd_multiplexing_mask*/) {
pthread_mutex_lock(&UE_mac_inst[Mod_id].UL_INFO_mutex);
// change for mutiple UE's simulation.
//pthread_mutex_lock(&UE_mac_inst[Mod_id].UL_INFO_mutex);
pthread_mutex_lock(&fill_ul_mutex.harq_mutex);
nfapi_harq_indication_t *ind = &UL_INFO->harq_ind;
nfapi_harq_indication_body_t *body = &ind->harq_indication_body;
nfapi_harq_indication_pdu_t *pdu = &body->harq_pdu_list[UL_INFO->harq_ind.harq_indication_body.number_of_harqs];
@@ -311,6 +350,7 @@ void fill_uci_harq_indication_UE_MAC(int Mod_id,
else if (SNRtimes10 > 635) pdu->ul_cqi_information.ul_cqi=255;
else pdu->ul_cqi_information.ul_cqi=(640+SNRtimes10)/5;
pdu->ul_cqi_information.channel = 0;
if(harq_information->harq_information_rel9_fdd.tl.tag == NFAPI_UL_CONFIG_REQUEST_HARQ_INFORMATION_REL9_FDD_TAG){
if ((harq_information->harq_information_rel9_fdd.ack_nack_mode == 0) &&
(harq_information->harq_information_rel9_fdd.harq_size == 1)) {
@@ -332,12 +372,31 @@ void fill_uci_harq_indication_UE_MAC(int Mod_id,
pdu->harq_indication_fdd_rel13.harq_tb_n[1] = 1; // Assuming always an ACK (No NACK or DTX)
}
else AssertFatal(1==0,"only format 1a/b for now, received \n");
}else if(harq_information->harq_information_rel10_tdd.tl.tag == NFAPI_UL_CONFIG_REQUEST_HARQ_INFORMATION_REL10_TDD_TAG ){
if ((harq_information->harq_information_rel10_tdd.ack_nack_mode == 0) &&
(harq_information->harq_information_rel10_tdd.harq_size == 1)) {
pdu->harq_indication_tdd_rel13.tl.tag = NFAPI_HARQ_INDICATION_TDD_REL13_TAG;
pdu->harq_indication_tdd_rel13.mode = 0;
pdu->harq_indication_tdd_rel13.number_of_ack_nack = 1;
pdu->harq_indication_tdd_rel13.harq_data[0].bundling.value_0 = 1;
} else if ((harq_information->harq_information_rel10_tdd.ack_nack_mode == 1) &&
(harq_information->harq_information_rel10_tdd.harq_size == 2)) {
pdu->harq_indication_tdd_rel13.tl.tag = NFAPI_HARQ_INDICATION_TDD_REL13_TAG;
pdu->harq_indication_tdd_rel13.mode = 0;
pdu->harq_indication_tdd_rel13.number_of_ack_nack = 1;
pdu->harq_indication_tdd_rel13.harq_data[0].bundling.value_0 = 1;
pdu->harq_indication_tdd_rel13.harq_data[1].bundling.value_0 = 1;
}
} else AssertFatal(1==0,"only format 1a/b for now, received \n");
UL_INFO->harq_ind.harq_indication_body.number_of_harqs++;
LOG_D(PHY,"Incremented eNB->UL_INFO.harq_ind.number_of_harqs:%d\n", UL_INFO->harq_ind.harq_indication_body.number_of_harqs);
pthread_mutex_unlock(&UE_mac_inst[Mod_id].UL_INFO_mutex);
// change for mutiple UE's simulation.
//pthread_mutex_unlock(&UE_mac_inst[Mod_id].UL_INFO_mutex);
pthread_mutex_unlock(&fill_ul_mutex.harq_mutex);
}
@@ -622,7 +681,8 @@ int dl_config_req_UE_MAC(nfapi_dl_config_request_t* req, module_id_t Mod_id) //,
//if(tx_request_pdu_list[dl_config_pdu_tmp->dlsch_pdu.dlsch_pdu_rel8.pdu_index].segments[0].segment_data!= NULL && tx_request_pdu_list[dl_config_pdu_tmp->dlsch_pdu.dlsch_pdu_rel8.pdu_index].segments[0].segment_length >0){
*/
if(dl_config_pdu_tmp->dlsch_pdu.dlsch_pdu_rel8.pdu_index <= tx_req_num_elems -1){
// to avoid unexpected error , add check pdu_index is more than 0.
if((dl_config_pdu_tmp->dlsch_pdu.dlsch_pdu_rel8.pdu_index >= 0) &&(dl_config_pdu_tmp->dlsch_pdu.dlsch_pdu_rel8.pdu_index <= tx_req_num_elems -1)){
//if(tx_request_pdu_list + dl_config_pdu_tmp->dlsch_pdu.dlsch_pdu_rel8.pdu_index!= NULL){
LOG_E(MAC, "dl_config_req_UE_MAC 2 Received data: sfn/sf:%d PDU[%d] size:%d, TX_PDU index: %d, tx_req_num_elems: %d \n", NFAPI_SFNSF2DEC(req->sfn_sf), i, dl_config_pdu_list[i].pdu_size, dl_config_pdu_tmp->dlsch_pdu.dlsch_pdu_rel8.pdu_index, tx_req_num_elems);
+12 -8
View File
@@ -17,19 +17,23 @@
//#include "openair1/PHY/defs.h"
//#include "openair1/PHY/LTE_TRANSPORT/defs.h"
UL_IND_t *UL_INFO;
nfapi_tx_request_pdu_t* tx_request_pdu_list;
// this mutex is used to set multiple UE's UL value in L2 FAPI simulator.
FILL_UL_INFO_MUTEX_t fill_ul_mutex;
//below 2 difinitions move to phy_stub_UE.c to add initialization when difinition.
extern UL_IND_t *UL_INFO;
extern nfapi_tx_request_pdu_t* tx_request_pdu_list;
// New
/// Pointers to config_request types. Used from nfapi callback functions.
nfapi_dl_config_request_t* dl_config_req;
nfapi_ul_config_request_t* ul_config_req;
nfapi_hi_dci0_request_t* hi_dci0_req;
//below 3 difinitions move to phy_stub_UE.c to add initialization when difinition.
extern nfapi_dl_config_request_t* dl_config_req;
extern nfapi_ul_config_request_t* ul_config_req;
extern nfapi_hi_dci0_request_t* hi_dci0_req;
int tx_req_num_elems;
int next_ra_frame;
module_id_t next_Mod_id;
//below 2 difinitions move to lte-ue.c to add initialization when difinition.
//int next_ra_frame;
//module_id_t next_Mod_id;
eth_params_t stub_eth_params;
File diff suppressed because it is too large Load Diff
+2809 -3332
View File
File diff suppressed because it is too large Load Diff
-35
View File
@@ -6816,37 +6816,6 @@ rrc_eNB_decode_ccch(
0,
0);
/*
#if defined(ENABLE_ITTI)
# if defined(DISABLE_ITTI_XER_PRINT)
{
MessageDef *message_p;
message_p = itti_alloc_new_message(TASK_RRC_ENB, RRC_UL_CCCH_MESSAGE);
memcpy(&message_p->ittiMsg, (void *)ul_ccch_msg, sizeof(RrcUlCcchMessage));
itti_send_msg_to_task(TASK_UNKNOWN, ctxt_pP->instance, message_p);
}
# else
{
char message_string[10000];
size_t message_string_size;
if ((message_string_size =
xer_sprint(message_string, sizeof(message_string), &asn_DEF_LTE_UL_CCCH_Message, (void *)ul_ccch_msg)) > 0) {
MessageDef *msg_p;
msg_p = itti_alloc_new_message_sized(TASK_RRC_ENB, RRC_UL_CCCH, message_string_size + sizeof(IttiMsgText));
msg_p->ittiMsg.rrc_ul_ccch.size = message_string_size;
memcpy(&msg_p->ittiMsg.rrc_ul_ccch.text, message_string, message_string_size);
itti_send_msg_to_task(TASK_UNKNOWN, ctxt_pP->instance, msg_p);
}
}
# endif
#endif
*/
for (i = 0; i < 8; i++) {
LOG_T(RRC, "%x.", ((uint8_t *) & ul_ccch_msg)[i]);
}
@@ -7334,12 +7303,8 @@ rrc_eNB_decode_dcch(
LTE_UL_DCCH_Message_t *ul_dcch_msg = NULL; //&uldcchmsg;
int i;
struct rrc_eNB_ue_context_s *ue_context_p = NULL;
#if defined(ENABLE_ITTI)
# if defined(ENABLE_USE_MME)
MessageDef *msg_delete_tunnels_p = NULL;
uint8_t xid;
#endif
#endif
int dedicated_DRB=0;
T(T_ENB_RRC_UL_DCCH_DATA_IN, T_INT(ctxt_pP->module_id), T_INT(ctxt_pP->frame),
T_INT(ctxt_pP->subframe), T_INT(ctxt_pP->rnti));
+1 -1
View File
@@ -51,7 +51,7 @@ extern LTE_LogicalChannelConfig_t SRB2_logicalChannelConfig_defaultValue;
extern unsigned char NB_INST;
#endif
extern unsigned char NB_eNB_INST;
extern unsigned char NB_UE_INST;
extern uint16_t NB_UE_INST;
extern unsigned short NODE_ID[1];
#endif
+1 -1
View File
@@ -38,7 +38,7 @@
UE_PF_PO_t UE_PF_PO[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB];
pthread_mutex_t ue_pf_po_mutex;
UE_RRC_INST *UE_rrc_inst;
UE_RRC_INST *UE_rrc_inst = NULL;
#include "LAYER2/MAC/mac_extern.h"
#define MAX_U32 0xFFFFFFFF
+43 -22
View File
@@ -33,26 +33,23 @@ This header file must be included */
#define OPT_H_
#ifndef sys_include
#define sys_include
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <time.h>
#define sys_include
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <time.h>
#endif
#ifndef project_include
#define project_include
#include "common/utils/LOG/log_if.h"
// #include "UTIL/LOG/log_extern.h"
//#include "PHY/defs.h"
//#include "PHY/extern.h"
#include "PHY/impl_defs_lte.h"
#define project_include
#include "common/utils/LOG/log_if.h"
#include "PHY/impl_defs_lte.h"
#endif
#define PACKET_MAC_LTE_DEFAULT_UDP_PORT (9999)
@@ -65,6 +62,32 @@ typedef guint8 gboolean;
#include "packet-mac-lte.h"
#include "mac_pcap.h"
/* OPT parameters definitions */
#define OPT_CONFIGPREFIX "opt"
#define CONFIG_HLP_TYPEMON "Type of L2 monitoring messages: none,pcap,wireshark \n"
#define CONFIG_HLP_L2MONIP "ip address for wireshark messages \n"
#define CONFIG_HLP_L2MONPATH "file path for pcap messages on localhost \n"
/*-----------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
/* command line parameters for LOG utility */
/* optname helpstr paramflags XXXptr defXXXval type numelt */
/*-----------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
#define OPT_PARAMS_DESC { \
{"type" , CONFIG_HLP_TYPEMON, 0, strptr:&in_type, defstrval:"none", TYPE_STRING, 0}, \
{"ip" , CONFIG_HLP_L2MONIP, 0, strptr:&in_ip, defstrval:"127.0.0.1", TYPE_STRING, 0}, \
{"path" , CONFIG_HLP_L2MONPATH, 0, strptr:&in_path, defstrval:"/tmp/oai_opt.pcap", TYPE_STRING, 0}, \
}
#define OPTTYPE_IDX 0
/* check function for opt parameters */
#define OPTTYPE_OKSTRINGS {"none","pcap","wireshark"}
#define OPTTYPE_VALUES {OPT_NONE,OPT_PCAP,OPT_WIRESHARK}
#define OPTPARAMS_CHECK_DESC { \
{ .s3a= { config_checkstr_assign_integer, OPTTYPE_OKSTRINGS,OPTTYPE_VALUES ,3}} ,\
{ .s5= {NULL }} , \
{ .s5= {NULL }} , \
}
#ifdef OCP_FRAMEWORK
#include <enums.h>
#else
@@ -82,9 +105,7 @@ typedef enum radio_type_e {
RADIO_TYPE_MAX
} radio_type_t;
extern trace_mode_t opt_type;
extern char in_ip[40];
extern char in_path[FILENAME_MAX];
/**
* function def
@@ -94,7 +115,7 @@ void trace_pdu(int direction, uint8_t *pdu_buffer, unsigned int pdu_buffer_size,
int ueid, int rntiType, int rnti, uint16_t sysFrame, uint8_t subframe,
int oob_event, int oob_event_value);
int init_opt(char *path, char *ip);
int init_opt(void);
void terminate_opt(void);
+143 -159
View File
@@ -90,7 +90,7 @@ what about the implementation
#include <pthread.h>
#include <stdint.h>
#include "common/config/config_userapi.h"
#include "opt.h"
int opt_enabled=0;
@@ -98,8 +98,8 @@ int opt_enabled=0;
//static unsigned char g_PDUBuffer[1600];
//static unsigned int g_PDUOffset;
char in_ip[40];
char in_path[FILENAME_MAX];
static char *in_ip;
static char *in_path;
FILE *file_fd = NULL;
pcap_hdr_t file_header = {
0xa1b2c3d4, /* magic number */
@@ -133,17 +133,15 @@ static void SendFrame(guint8 radioType, guint8 direction, guint8 rntiType,
static int MAC_LTE_PCAP_WritePDU(MAC_Context_Info_t *context,
const unsigned char *PDU, unsigned int length);
static void *opt_listener_thread(void *arg)
{
static void *opt_listener_thread(void *arg) {
ssize_t ret;
struct sockaddr_in from_address;
socklen_t socklen = sizeof(from_address);
memset(&from_address, 0, sizeof(from_address));
while(1) {
/* Simply drop packets */
ret = recvfrom(opt_listener.sd, NULL, 0, 0, (struct sockaddr*)&from_address,
ret = recvfrom(opt_listener.sd, NULL, 0, 0, (struct sockaddr *)&from_address,
&socklen);
if (ret == 0) {
@@ -165,17 +163,13 @@ static void *opt_listener_thread(void *arg)
}
static
int opt_create_listener_socket(char *ip_address, uint16_t port)
{
int opt_create_listener_socket(char *ip_address, uint16_t port) {
/* Create an UDP socket and listen on it.
* Silently discard PDU received.
*/
int sd = -1;
int ret = -1;
memset(&opt_listener, 0, sizeof(opt_listener_t));
sd = socket(AF_INET, SOCK_DGRAM, 0);
if (sd < 0) {
@@ -190,8 +184,7 @@ int opt_create_listener_socket(char *ip_address, uint16_t port)
/* Listening only on provided IP address */
opt_listener.address.sin_addr.s_addr = inet_addr(ip_address);
opt_listener.address.sin_port = htons(port);
ret = bind(opt_listener.sd, (struct sockaddr*) &opt_listener.address, sizeof(opt_listener.address));
ret = bind(opt_listener.sd, (struct sockaddr *) &opt_listener.address, sizeof(opt_listener.address));
if (ret != 0) {
LOG_E(OPT, "Failed to bind socket to (%s:%u): %s\n",
@@ -231,49 +224,39 @@ static void SendFrame(guint8 radioType, guint8 direction, guint8 rntiType,
guint16 rnti, guint16 ueid, guint16 sfnSf,
guint8 isPredefinedData, guint8 retx, guint8 crcStatus,
guint8 oob_event, guint8 oob_event_value,
uint8_t *pdu_buffer, unsigned int pdu_buffer_size)
{
uint8_t *pdu_buffer, unsigned int pdu_buffer_size) {
unsigned char frameBuffer[9000];
unsigned int frameOffset;
ssize_t bytesSent;
frameOffset = 0;
uint16_t tmp16;
memcpy(frameBuffer+frameOffset, MAC_LTE_START_STRING,
strlen(MAC_LTE_START_STRING));
frameOffset += strlen(MAC_LTE_START_STRING);
/******************************************************************************/
/* Now write out fixed fields (the mandatory elements of struct mac_lte_info) */
frameBuffer[frameOffset++] = radioType;
frameBuffer[frameOffset++] = direction;
frameBuffer[frameOffset++] = rntiType;
/*************************************/
/* Now optional fields */
/* RNTI */
frameBuffer[frameOffset++] = MAC_LTE_RNTI_TAG;
tmp16 = htons(rnti);
memcpy(frameBuffer+frameOffset, &tmp16, 2);
frameOffset += 2;
/* UEId */
frameBuffer[frameOffset++] = MAC_LTE_UEID_TAG;
tmp16 = htons(ueid);
memcpy(frameBuffer+frameOffset, &tmp16, 2);
frameOffset += 2;
/* Subframe number */
frameBuffer[frameOffset++] = MAC_LTE_FRAME_SUBFRAME_TAG;
tmp16 = htons(sfnSf); // frame counter : this will give an expert info as wireshark expects SF and not F
memcpy(frameBuffer+frameOffset, &tmp16, 2);
frameOffset += 2;
frameBuffer[frameOffset++] = MAC_LTE_CRC_STATUS_TAG;
frameBuffer[frameOffset++] = crcStatus;
#ifdef WIRESHARK_DEV
frameOffset += 2;
tmp16 = htons(sfnSf); // subframe
@@ -293,55 +276,55 @@ static void SendFrame(guint8 radioType, guint8 direction, guint8 rntiType,
frameBuffer[frameOffset++] = retx;
}
//#ifdef WIRESHARK_DEV
//#ifdef WIRESHARK_DEV
/* Relating to out-of-band events */
/* N.B. dissector will only look to these fields if length is 0... */
if (pdu_buffer_size==0) {
switch (oob_event) {
case ltemac_send_preamble :
LOG_D(OPT,"ltemac_send_preamble event %02x."
//"%02x."
"%02x.%02x\n",
MAC_LTE_SEND_PREAMBLE_TAG,
//ltemac_send_preamble,
rnti,
oob_event_value);
//frameBuffer[frameOffset++]=0;
//frameBuffer[frameOffset++]=0;
//frameBuffer[frameOffset++]=0;
frameBuffer[frameOffset++] = MAC_LTE_SEND_PREAMBLE_TAG;
//frameBuffer[frameOffset++]=ltemac_send_preamble;
frameBuffer[frameOffset++]=rnti; // is the preamble
frameBuffer[frameOffset++]=oob_event_value;
break;
case ltemac_send_preamble :
LOG_D(OPT,"ltemac_send_preamble event %02x."
//"%02x."
"%02x.%02x\n",
MAC_LTE_SEND_PREAMBLE_TAG,
//ltemac_send_preamble,
rnti,
oob_event_value);
//frameBuffer[frameOffset++]=0;
//frameBuffer[frameOffset++]=0;
//frameBuffer[frameOffset++]=0;
frameBuffer[frameOffset++] = MAC_LTE_SEND_PREAMBLE_TAG;
//frameBuffer[frameOffset++]=ltemac_send_preamble;
frameBuffer[frameOffset++]=rnti; // is the preamble
frameBuffer[frameOffset++]=oob_event_value;
break;
case ltemac_send_sr:
frameBuffer[frameOffset++]=MAC_LTE_SR_TAG ;
frameOffset+=2;
frameBuffer[frameOffset++]=rnti;
frameOffset++;
frameBuffer[frameOffset++]=oob_event_value;
frameOffset++;
break;
case ltemac_send_sr:
frameBuffer[frameOffset++]=MAC_LTE_SR_TAG ;
frameOffset+=2;
frameBuffer[frameOffset++]=rnti;
frameOffset++;
frameBuffer[frameOffset++]=oob_event_value;
frameOffset++;
break;
case ltemac_sr_failure:
default:
LOG_W(OPT,"not implemeneted yet\n");
break;
case ltemac_sr_failure:
default:
LOG_W(OPT,"not implemeneted yet\n");
break;
}
}
//#endif
//#endif
/***************************************/
/* Now write the MAC PDU */
frameBuffer[frameOffset++] = MAC_LTE_PAYLOAD_TAG;
/* Append actual PDU */
//memcpy(frameBuffer+frameOffset, g_PDUBuffer, g_PDUOffset);
//frameOffset += g_PDUOffset;
if (pdu_buffer != NULL) {
memcpy(frameBuffer+frameOffset, (void*)pdu_buffer, pdu_buffer_size);
memcpy(frameBuffer+frameOffset, (void *)pdu_buffer, pdu_buffer_size);
frameOffset += pdu_buffer_size;
}
@@ -358,44 +341,36 @@ static void SendFrame(guint8 radioType, guint8 direction, guint8 rntiType,
/* Write an individual PDU (PCAP packet header + mac-context + mac-pdu) */
static int MAC_LTE_PCAP_WritePDU(MAC_Context_Info_t *context,
const uint8_t *PDU, unsigned int length)
{
const uint8_t *PDU, unsigned int length) {
pcaprec_hdr_t packet_header;
uint8_t context_header[256];
int offset = 0;
unsigned short tmp16;
/*****************************************************************/
/* Context information (same as written by UDP heuristic clients */
context_header[offset++] = context->radioType;
context_header[offset++] = context->direction;
context_header[offset++] = context->rntiType;
/* RNTI */
context_header[offset++] = MAC_LTE_RNTI_TAG;
tmp16 = htons(context->rnti);
memcpy(context_header+offset, &tmp16, 2);
offset += 2;
/* UEId */
context_header[offset++] = MAC_LTE_UEID_TAG;
tmp16 = htons(context->ueid);
memcpy(context_header+offset, &tmp16, 2);
offset += 2;
/* Subframe number */
context_header[offset++] = MAC_LTE_FRAME_SUBFRAME_TAG;
tmp16 = htons(context->subFrameNumber);
memcpy(context_header+offset, &tmp16, 2);
offset += 2;
/* CRC Status */
context_header[offset++] = MAC_LTE_CRC_STATUS_TAG;
context_header[offset++] = context->crcStatusOK;
/* Data tag immediately preceding PDU */
context_header[offset++] = MAC_LTE_PAYLOAD_TAG;
/****************************************************************/
/* PCAP Header */
/* TODO: Timestamp might want to be relative to a more sensible
@@ -404,13 +379,11 @@ static int MAC_LTE_PCAP_WritePDU(MAC_Context_Info_t *context,
packet_header.ts_usec = (context->subframesSinceCaptureStart % 1000) * 1000;
packet_header.incl_len = offset + length;
packet_header.orig_len = offset + length;
/***************************************************************/
/* Now write everything to the file */
fwrite(&packet_header, sizeof(pcaprec_hdr_t), 1, file_fd);
fwrite(context_header, 1, offset, file_fd);
fwrite(PDU, 1, length, file_fd);
return 1;
}
#include <common/ran_context.h>
@@ -419,117 +392,129 @@ extern RAN_CONTEXT_t RC;
/* Remote serveraddress (where Wireshark is running) */
void trace_pdu(int direction, uint8_t *pdu_buffer, unsigned int pdu_buffer_size,
int ueid, int rntiType, int rnti, uint16_t sysFrameNumber, uint8_t subFrameNumber, int oob_event,
int oob_event_value)
{
int oob_event_value) {
MAC_Context_Info_t pdu_context;
int radioType=FDD_RADIO;
if (RC.eNB[0][0]!=NULL)
radioType=RC.eNB[0][0]->frame_parms.frame_type== FDD ? FDD_RADIO:TDD_RADIO;
if (PHY_vars_UE_g[0][0] != NULL)
radioType=PHY_vars_UE_g[0][0]->frame_parms.frame_type== FDD ? FDD_RADIO:TDD_RADIO;
switch (opt_type) {
case OPT_WIRESHARK :
if (g_socksd == -1) {
return;
}
case OPT_WIRESHARK :
if (g_socksd == -1) {
return;
}
SendFrame( radioType,
(direction == DIRECTION_DOWNLINK) ? DIRECTION_DOWNLINK : DIRECTION_UPLINK,
rntiType, rnti, ueid, (sysFrameNumber<<4) + subFrameNumber,
1, 0, 1, //guint8 isPredefinedData, guint8 retx, guint8 crcStatus
oob_event,oob_event_value,
pdu_buffer, pdu_buffer_size);
break;
SendFrame( radioType,
(direction == DIRECTION_DOWNLINK) ? DIRECTION_DOWNLINK : DIRECTION_UPLINK,
rntiType, rnti, ueid, (sysFrameNumber<<4) + subFrameNumber,
1, 0, 1, //guint8 isPredefinedData, guint8 retx, guint8 crcStatus
oob_event,oob_event_value,
pdu_buffer, pdu_buffer_size);
break;
case OPT_PCAP:
if (file_fd == NULL) {
return;
}
case OPT_PCAP:
if (file_fd == NULL) {
return;
}
pdu_context.radioType = radioType;
pdu_context.direction = (direction == DIRECTION_DOWNLINK) ? DIRECTION_DOWNLINK
: DIRECTION_UPLINK;
pdu_context.rntiType = rntiType;
pdu_context.rnti = rnti;
pdu_context.ueid = ueid;
pdu_context.isRetx = 0;
pdu_context.crcStatusOK =1;
pdu_context.sysFrameNumber = sysFrameNumber;
pdu_context.subFrameNumber = subFrameNumber;
pdu_context.subframesSinceCaptureStart = subframesSinceCaptureStart++;
MAC_LTE_PCAP_WritePDU( &pdu_context, pdu_buffer, pdu_buffer_size);
break;
pdu_context.radioType = radioType;
pdu_context.direction = (direction == DIRECTION_DOWNLINK) ? DIRECTION_DOWNLINK
: DIRECTION_UPLINK;
pdu_context.rntiType = rntiType;
pdu_context.rnti = rnti;
pdu_context.ueid = ueid;
pdu_context.isRetx = 0;
pdu_context.crcStatusOK =1;
pdu_context.sysFrameNumber = sysFrameNumber;
pdu_context.subFrameNumber = subFrameNumber;
pdu_context.subframesSinceCaptureStart = subframesSinceCaptureStart++;
MAC_LTE_PCAP_WritePDU( &pdu_context, pdu_buffer, pdu_buffer_size);
break;
case OPT_TSHARK:
default:
break;
case OPT_TSHARK:
default:
break;
}
}
/*---------------------------------------------------*/
int init_opt(char *path, char *ip)
{
int init_opt(void) {
char *in_type=NULL;
paramdef_t opt_params[] = OPT_PARAMS_DESC ;
checkedparam_t opt_checkParams[] = OPTPARAMS_CHECK_DESC;
uint16_t in_port;
config_set_checkfunctions(opt_params, opt_checkParams,
sizeof(opt_params)/sizeof(paramdef_t));
config_get( opt_params,sizeof(opt_params)/sizeof(paramdef_t),OPT_CONFIGPREFIX);
subframesSinceCaptureStart = 0;
int tmptype = config_get_processedint( &(opt_params[OPTTYPE_IDX]));
if (path != NULL) {
strncpy( in_path, path, sizeof(in_path) );
in_path[sizeof(in_path) - 1] = 0; // terminate string
if (tmptype == OPT_NONE) {
opt_enabled=0;
LOG_I(OPT,"OPT disabled\n");
return 0;
} else if (tmptype == OPT_PCAP && strlen(in_path) > 0) {
opt_type = OPT_PCAP;
opt_enabled=1;
LOG_I(OPT,"Enabling OPT for PCAP with the following file %s \n",in_path);
} else if (tmptype == OPT_WIRESHARK && strlen(in_ip) > 0) {
opt_enabled=1;
opt_type = OPT_WIRESHARK;
LOG_I(OPT,"Enabling OPT for wireshark for local interface %s\n",in_ip);
} else {
strcpy( in_path, "/tmp/opt.pcap" );
}
if (ip != NULL) {
strncpy( in_ip, ip, sizeof(in_ip) );
in_ip[sizeof(in_ip) - 1] = 0; // terminate string
} else {
strcpy( in_ip, "127.0.0.1" );
LOG_E(OPT,"Invalid OPT configuration\n");
config_printhelp(opt_params,sizeof(opt_params)/sizeof(paramdef_t),OPT_CONFIGPREFIX);
}
in_port = PACKET_MAC_LTE_DEFAULT_UDP_PORT;
// trace_mode
switch (opt_type) {
case OPT_WIRESHARK:
case OPT_WIRESHARK:
/* Create local server socket only if using localhost address */
if (strcmp(in_ip, "127.0.0.1") == 0) {
opt_create_listener_socket(in_ip, in_port);
}
/* Create local server socket only if using localhost address */
if (strcmp(in_ip, "127.0.0.1") == 0) {
opt_create_listener_socket(in_ip, in_port);
}
g_socksd = socket(AF_INET, SOCK_DGRAM, 0);
g_socksd = socket(AF_INET, SOCK_DGRAM, 0);
if (g_socksd == -1) {
LOG_E(OPT, "Error trying to create socket (errno=%d)\n", errno);
LOG_E(OPT, "CREATING SOCKET FAILED\n");
return (-1);
}
if (g_socksd == -1) {
LOG_E(OPT, "Error trying to create socket (errno=%d)\n", errno);
LOG_E(OPT, "CREATING SOCKET FAILED\n");
return (-1);
}
/* Get remote IP address from the function argument */
g_serv_addr.sin_family = AF_INET;
g_serv_addr.sin_port = htons(in_port);
g_serv_addr.sin_addr.s_addr = inet_addr(in_ip);
break;
/* Get remote IP address from the function argument */
g_serv_addr.sin_family = AF_INET;
g_serv_addr.sin_port = htons(in_port);
g_serv_addr.sin_addr.s_addr = inet_addr(in_ip);
break;
case OPT_PCAP:
file_fd = fopen(in_path, "w");
case OPT_PCAP:
file_fd = fopen(in_path, "w");
if (file_fd == NULL) {
LOG_D(OPT, "Failed to open file \"%s\" for writing\n", in_path);
return (-1);
}
/* Write the file header */
fwrite(&file_header, sizeof(pcap_hdr_t), 1, file_fd);
break;
if (file_fd == NULL) {
LOG_D(OPT, "Failed to open file \"%s\" for writing\n", in_path);
return (-1);
}
case OPT_TSHARK:
LOG_W(OPT, "Tshark is currently not supported\n");
opt_type = OPT_NONE;
break;
/* Write the file header */
fwrite(&file_header, sizeof(pcap_hdr_t), 1, file_fd);
break;
default:
opt_type = OPT_NONE;
LOG_W(OPT, "supported Option\n");
break;
case OPT_TSHARK:
LOG_W(OPT, "Tshark is currently not supported\n");
opt_type = OPT_NONE;
break;
default:
opt_type = OPT_NONE;
LOG_W(OPT, "supported Option\n");
break;
}
if ( opt_type == OPT_WIRESHARK )
@@ -543,8 +528,7 @@ int init_opt(char *path, char *ip)
// memset(mac_info, 0, sizeof(mac_lte_info)+pdu_buffer_size + 8);
return (1);
}
void terminate_opt(void)
{
void terminate_opt(void) {
/* Close local socket */
// free(mac_info);
if (opt_type != OPT_NONE) {
@@ -552,18 +536,18 @@ void terminate_opt(void)
}
switch (opt_type) {
case OPT_WIRESHARK:
close(g_socksd);
g_socksd = -1;
break;
case OPT_WIRESHARK:
close(g_socksd);
g_socksd = -1;
break;
case OPT_PCAP:
fclose (file_fd);
file_fd = NULL;
break;
case OPT_PCAP:
fclose (file_fd);
file_fd = NULL;
break;
default:
break;
default:
break;
}
}
+91 -147
View File
@@ -81,30 +81,21 @@ void x2ap_eNB_handle_handover_req_ack(instance_t instance,
static
void x2ap_eNB_handle_sctp_data_ind(instance_t instance, sctp_data_ind_t *sctp_data_ind) {
int result;
DevAssert(sctp_data_ind != NULL);
x2ap_eNB_handle_message(instance, sctp_data_ind->assoc_id, sctp_data_ind->stream,
sctp_data_ind->buffer, sctp_data_ind->buffer_length);
result = itti_free(TASK_UNKNOWN, sctp_data_ind->buffer);
AssertFatal (result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result);
}
static
void x2ap_eNB_handle_sctp_association_resp(instance_t instance, sctp_new_association_resp_t *sctp_new_association_resp)
{
void x2ap_eNB_handle_sctp_association_resp(instance_t instance, sctp_new_association_resp_t *sctp_new_association_resp) {
x2ap_eNB_instance_t *instance_p;
x2ap_eNB_data_t *x2ap_enb_data_p;
DevAssert(sctp_new_association_resp != NULL);
printf("x2ap_eNB_handle_sctp_association_resp at 1\n");
dump_trees();
printf("x2ap_eNB_handle_sctp_association_resp at 1\n");
dump_trees();
instance_p = x2ap_eNB_get_instance(instance);
DevAssert(instance_p != NULL);
@@ -113,13 +104,15 @@ dump_trees();
*/
if (sctp_new_association_resp->assoc_id != -1) {
x2ap_enb_data_p = x2ap_get_eNB(instance_p, sctp_new_association_resp->assoc_id,
sctp_new_association_resp->ulp_cnx_id);
sctp_new_association_resp->ulp_cnx_id);
if (x2ap_enb_data_p != NULL) {
/* some sanity check - to be refined at some point */
if (sctp_new_association_resp->sctp_state != SCTP_STATE_ESTABLISHED) {
X2AP_ERROR("x2ap_enb_data_p not NULL and sctp state not SCTP_STATE_ESTABLISHED, what to do?\n");
abort();
}
x2ap_enb_data_p->in_streams = sctp_new_association_resp->in_streams;
x2ap_enb_data_p->out_streams = sctp_new_association_resp->out_streams;
return;
@@ -127,70 +120,60 @@ dump_trees();
}
x2ap_enb_data_p = x2ap_get_eNB(instance_p, -1,
sctp_new_association_resp->ulp_cnx_id);
sctp_new_association_resp->ulp_cnx_id);
DevAssert(x2ap_enb_data_p != NULL);
printf("x2ap_eNB_handle_sctp_association_resp at 2\n");
dump_trees();
printf("x2ap_eNB_handle_sctp_association_resp at 2\n");
dump_trees();
if (sctp_new_association_resp->sctp_state != SCTP_STATE_ESTABLISHED) {
X2AP_WARN("Received unsuccessful result for SCTP association (%u), instance %d, cnx_id %u\n",
sctp_new_association_resp->sctp_state,
instance,
sctp_new_association_resp->ulp_cnx_id);
x2ap_handle_x2_setup_message(x2ap_enb_data_p,
sctp_new_association_resp->sctp_state == SCTP_STATE_SHUTDOWN);
sctp_new_association_resp->sctp_state == SCTP_STATE_SHUTDOWN);
return;
}
printf("x2ap_eNB_handle_sctp_association_resp at 3\n");
dump_trees();
printf("x2ap_eNB_handle_sctp_association_resp at 3\n");
dump_trees();
/* Update parameters */
x2ap_enb_data_p->assoc_id = sctp_new_association_resp->assoc_id;
x2ap_enb_data_p->in_streams = sctp_new_association_resp->in_streams;
x2ap_enb_data_p->out_streams = sctp_new_association_resp->out_streams;
printf("x2ap_eNB_handle_sctp_association_resp at 4\n");
dump_trees();
printf("x2ap_eNB_handle_sctp_association_resp at 4\n");
dump_trees();
/* Prepare new x2 Setup Request */
x2ap_eNB_generate_x2_setup_request(instance_p, x2ap_enb_data_p);
}
static
void x2ap_eNB_handle_sctp_association_ind(instance_t instance, sctp_new_association_ind_t *sctp_new_association_ind)
{
void x2ap_eNB_handle_sctp_association_ind(instance_t instance, sctp_new_association_ind_t *sctp_new_association_ind) {
x2ap_eNB_instance_t *instance_p;
x2ap_eNB_data_t *x2ap_enb_data_p;
printf("x2ap_eNB_handle_sctp_association_ind at 1 (called for instance %d)\n", instance);
dump_trees();
printf("x2ap_eNB_handle_sctp_association_ind at 1 (called for instance %d)\n", instance);
dump_trees();
DevAssert(sctp_new_association_ind != NULL);
instance_p = x2ap_eNB_get_instance(instance);
DevAssert(instance_p != NULL);
x2ap_enb_data_p = x2ap_get_eNB(instance_p, sctp_new_association_ind->assoc_id, -1);
if (x2ap_enb_data_p != NULL) abort();
// DevAssert(x2ap_enb_data_p != NULL);
// DevAssert(x2ap_enb_data_p != NULL);
if (x2ap_enb_data_p == NULL) {
/* Create new eNB descriptor */
x2ap_enb_data_p = calloc(1, sizeof(*x2ap_enb_data_p));
DevAssert(x2ap_enb_data_p != NULL);
x2ap_enb_data_p->cnx_id = x2ap_eNB_fetch_add_global_cnx_id();
x2ap_enb_data_p->x2ap_eNB_instance = instance_p;
/* Insert the new descriptor in list of known eNB
* but not yet associated.
*/
RB_INSERT(x2ap_enb_map, &instance_p->x2ap_enb_head, x2ap_enb_data_p);
x2ap_enb_data_p->state = X2AP_ENB_STATE_CONNECTED;
instance_p->x2_target_enb_nb++;
if (instance_p->x2_target_enb_pending_nb > 0) {
instance_p->x2_target_enb_pending_nb--;
}
@@ -198,37 +181,31 @@ dump_trees();
X2AP_WARN("x2ap_enb_data_p already exists\n");
}
printf("x2ap_eNB_handle_sctp_association_ind at 2\n");
dump_trees();
printf("x2ap_eNB_handle_sctp_association_ind at 2\n");
dump_trees();
/* Update parameters */
x2ap_enb_data_p->assoc_id = sctp_new_association_ind->assoc_id;
x2ap_enb_data_p->in_streams = sctp_new_association_ind->in_streams;
x2ap_enb_data_p->out_streams = sctp_new_association_ind->out_streams;
printf("x2ap_eNB_handle_sctp_association_ind at 3\n");
dump_trees();
printf("x2ap_eNB_handle_sctp_association_ind at 3\n");
dump_trees();
}
int x2ap_eNB_init_sctp (x2ap_eNB_instance_t *instance_p,
net_ip_address_t *local_ip_addr,
uint32_t enb_port_for_X2C)
{
net_ip_address_t *local_ip_addr,
uint32_t enb_port_for_X2C) {
// Create and alloc new message
MessageDef *message;
sctp_init_t *sctp_init = NULL;
DevAssert(instance_p != NULL);
DevAssert(local_ip_addr != NULL);
message = itti_alloc_new_message (TASK_X2AP, SCTP_INIT_MSG_MULTI_REQ);
sctp_init = &message->ittiMsg.sctp_init_multi;
sctp_init->port = enb_port_for_X2C;
sctp_init->ppid = X2AP_SCTP_PPID;
sctp_init->ipv4 = 1;
sctp_init->ipv6 = 0;
sctp_init->nb_ipv4_addr = 1;
#if 0
memcpy(&sctp_init->ipv4_address,
local_ip_addr,
@@ -241,9 +218,7 @@ int x2ap_eNB_init_sctp (x2ap_eNB_instance_t *instance_p,
*/
sctp_init->nb_ipv6_addr = 0;
sctp_init->ipv6_address[0] = "0:0:0:0:0:0:0:1";
return itti_send_msg_to_task (TASK_SCTP, instance_p->instance, message);
}
static void x2ap_eNB_register_eNB(x2ap_eNB_instance_t *instance_p,
@@ -251,47 +226,33 @@ static void x2ap_eNB_register_eNB(x2ap_eNB_instance_t *instance_p,
net_ip_address_t *local_ip_addr,
uint16_t in_streams,
uint16_t out_streams,
uint32_t enb_port_for_X2C,
int multi_sd)
{
uint32_t enb_port_for_X2C,
int multi_sd) {
MessageDef *message = NULL;
sctp_new_association_req_multi_t *sctp_new_association_req = NULL;
x2ap_eNB_data_t *x2ap_enb_data = NULL;
DevAssert(instance_p != NULL);
DevAssert(target_eNB_ip_address != NULL);
message = itti_alloc_new_message(TASK_X2AP, SCTP_NEW_ASSOCIATION_REQ_MULTI);
sctp_new_association_req = &message->ittiMsg.sctp_new_association_req_multi;
sctp_new_association_req->port = enb_port_for_X2C;
sctp_new_association_req->ppid = X2AP_SCTP_PPID;
sctp_new_association_req->in_streams = in_streams;
sctp_new_association_req->out_streams = out_streams;
sctp_new_association_req->multi_sd = multi_sd;
memcpy(&sctp_new_association_req->remote_address,
target_eNB_ip_address,
sizeof(*target_eNB_ip_address));
memcpy(&sctp_new_association_req->local_address,
local_ip_addr,
sizeof(*local_ip_addr));
/* Create new eNB descriptor */
x2ap_enb_data = calloc(1, sizeof(*x2ap_enb_data));
DevAssert(x2ap_enb_data != NULL);
x2ap_enb_data->cnx_id = x2ap_eNB_fetch_add_global_cnx_id();
sctp_new_association_req->ulp_cnx_id = x2ap_enb_data->cnx_id;
x2ap_enb_data->assoc_id = -1;
x2ap_enb_data->x2ap_eNB_instance = instance_p;
/* Insert the new descriptor in list of known eNB
* but not yet associated.
*/
@@ -299,18 +260,14 @@ static void x2ap_eNB_register_eNB(x2ap_eNB_instance_t *instance_p,
x2ap_enb_data->state = X2AP_ENB_STATE_WAITING;
instance_p->x2_target_enb_nb ++;
instance_p->x2_target_enb_pending_nb ++;
itti_send_msg_to_task(TASK_SCTP, instance_p->instance, message);
}
static
void x2ap_eNB_handle_register_eNB(instance_t instance,
x2ap_register_enb_req_t *x2ap_register_eNB)
{
x2ap_register_enb_req_t *x2ap_register_eNB) {
x2ap_eNB_instance_t *new_instance;
DevAssert(x2ap_register_eNB != NULL);
/* Look if the provided instance already exists */
new_instance = x2ap_eNB_get_instance(instance);
@@ -322,13 +279,10 @@ void x2ap_eNB_handle_register_eNB(instance_t instance,
DevCheck(new_instance->mcc == x2ap_register_eNB->mcc, new_instance->mcc, x2ap_register_eNB->mcc, 0);
DevCheck(new_instance->mnc == x2ap_register_eNB->mnc, new_instance->mnc, x2ap_register_eNB->mnc, 0);
X2AP_WARN("eNB[%d] already registered\n", instance);
}
else {
} else {
new_instance = calloc(1, sizeof(x2ap_eNB_instance_t));
DevAssert(new_instance != NULL);
RB_INIT(&new_instance->x2ap_enb_head);
/* Copy usefull parameters */
new_instance->instance = instance;
new_instance->eNB_name = x2ap_register_eNB->eNB_name;
@@ -338,10 +292,9 @@ void x2ap_eNB_handle_register_eNB(instance_t instance,
new_instance->mcc = x2ap_register_eNB->mcc;
new_instance->mnc = x2ap_register_eNB->mnc;
new_instance->mnc_digit_length = x2ap_register_eNB->mnc_digit_length;
new_instance->num_cc = x2ap_register_eNB->num_cc;
for (int i = 0; i< x2ap_register_eNB->num_cc; i++){
for (int i = 0; i< x2ap_register_eNB->num_cc; i++) {
new_instance->eutra_band[i] = x2ap_register_eNB->eutra_band[i];
new_instance->downlink_frequency[i] = x2ap_register_eNB->downlink_frequency[i];
new_instance->uplink_frequency_offset[i] = x2ap_register_eNB->uplink_frequency_offset[i];
@@ -357,44 +310,40 @@ void x2ap_eNB_handle_register_eNB(instance_t instance,
memcpy(new_instance->target_enb_x2_ip_address,
x2ap_register_eNB->target_enb_x2_ip_address,
x2ap_register_eNB->nb_x2 * sizeof(net_ip_address_t));
new_instance->nb_x2 = x2ap_register_eNB->nb_x2;
new_instance->enb_x2_ip_address = x2ap_register_eNB->enb_x2_ip_address;
new_instance->sctp_in_streams = x2ap_register_eNB->sctp_in_streams;
new_instance->sctp_out_streams = x2ap_register_eNB->sctp_out_streams;
new_instance->enb_port_for_X2C = x2ap_register_eNB->enb_port_for_X2C;
/* Add the new instance to the list of eNB (meaningfull in virtual mode) */
x2ap_eNB_insert_new_instance(new_instance);
X2AP_INFO("Registered new eNB[%d] and %s eNB id %u\n",
instance,
x2ap_register_eNB->cell_type == CELL_MACRO_ENB ? "macro" : "home",
x2ap_register_eNB->eNB_id);
instance,
x2ap_register_eNB->cell_type == CELL_MACRO_ENB ? "macro" : "home",
x2ap_register_eNB->eNB_id);
/* initiate the SCTP listener */
if (x2ap_eNB_init_sctp(new_instance,&x2ap_register_eNB->enb_x2_ip_address,x2ap_register_eNB->enb_port_for_X2C) < 0 ) {
X2AP_ERROR ("Error while sending SCTP_INIT_MSG to SCTP \n");
return;
X2AP_ERROR ("Error while sending SCTP_INIT_MSG to SCTP \n");
return;
}
X2AP_INFO("eNB[%d] eNB id %u acting as a listner (server)\n",
instance, x2ap_register_eNB->eNB_id);
X2AP_INFO("eNB[%d] eNB id %u acting as a listner (server)\n",
instance, x2ap_register_eNB->eNB_id);
}
}
static
void x2ap_eNB_handle_sctp_init_msg_multi_cnf(
instance_t instance_id,
sctp_init_msg_multi_cnf_t *m)
{
instance_t instance_id,
sctp_init_msg_multi_cnf_t *m) {
x2ap_eNB_instance_t *instance;
int index;
DevAssert(m != NULL);
instance = x2ap_eNB_get_instance(instance_id);
DevAssert(instance != NULL);
instance->multi_sd = m->multi_sd;
/* Exit if CNF message reports failure.
* Failure means multi_sd < 0.
*/
@@ -406,16 +355,15 @@ void x2ap_eNB_handle_sctp_init_msg_multi_cnf(
/* Trying to connect to the provided list of eNB ip address */
for (index = 0; index < instance->nb_x2; index++) {
X2AP_INFO("eNB[%d] eNB id %u acting as an initiator (client)\n",
instance_id, instance->eNB_id);
x2ap_eNB_register_eNB(instance,
&instance->target_enb_x2_ip_address[index],
&instance->enb_x2_ip_address,
instance->sctp_in_streams,
instance->sctp_out_streams,
instance->enb_port_for_X2C,
instance->multi_sd);
X2AP_INFO("eNB[%d] eNB id %u acting as an initiator (client)\n",
instance_id, instance->eNB_id);
x2ap_eNB_register_eNB(instance,
&instance->target_enb_x2_ip_address[index],
&instance->enb_x2_ip_address,
instance->sctp_in_streams,
instance->sctp_out_streams,
instance->enb_port_for_X2C,
instance->multi_sd);
}
}
@@ -475,69 +423,65 @@ void x2ap_eNB_handle_handover_req_ack(instance_t instance,
//x2ap_handover_req_ack->rrc_buffer, x2ap_handover_req_ack->rrc_buffer_size);
}
void *x2ap_task(void *arg)
{
void *x2ap_task(void *arg) {
MessageDef *received_msg = NULL;
int result;
X2AP_DEBUG("Starting X2AP layer\n");
x2ap_eNB_prepare_internal_data();
itti_mark_task_ready(TASK_X2AP);
while (1) {
itti_receive_msg(TASK_X2AP, &received_msg);
switch (ITTI_MSG_ID(received_msg)) {
case TERMINATE_MESSAGE:
X2AP_WARN(" *** Exiting X2AP thread\n");
itti_exit_task();
break;
case TERMINATE_MESSAGE:
X2AP_WARN(" *** Exiting X2AP thread\n");
itti_exit_task();
break;
case X2AP_REGISTER_ENB_REQ:
x2ap_eNB_handle_register_eNB(ITTI_MESSAGE_GET_INSTANCE(received_msg),
&X2AP_REGISTER_ENB_REQ(received_msg));
break;
case X2AP_REGISTER_ENB_REQ:
x2ap_eNB_handle_register_eNB(ITTI_MESSAGE_GET_INSTANCE(received_msg),
&X2AP_REGISTER_ENB_REQ(received_msg));
break;
case X2AP_HANDOVER_REQ:
x2ap_eNB_handle_handover_req(ITTI_MESSAGE_GET_INSTANCE(received_msg),
&X2AP_HANDOVER_REQ(received_msg));
break;
case X2AP_HANDOVER_REQ:
x2ap_eNB_handle_handover_req(ITTI_MESSAGE_GET_INSTANCE(received_msg),
&X2AP_HANDOVER_REQ(received_msg));
break;
case X2AP_HANDOVER_REQ_ACK:
x2ap_eNB_handle_handover_req_ack(ITTI_MESSAGE_GET_INSTANCE(received_msg),
&X2AP_HANDOVER_REQ_ACK(received_msg));
break;
case X2AP_HANDOVER_REQ_ACK:
x2ap_eNB_handle_handover_req_ack(ITTI_MESSAGE_GET_INSTANCE(received_msg),
&X2AP_HANDOVER_REQ_ACK(received_msg));
break;
case SCTP_INIT_MSG_MULTI_CNF:
x2ap_eNB_handle_sctp_init_msg_multi_cnf(ITTI_MESSAGE_GET_INSTANCE(received_msg),
&received_msg->ittiMsg.sctp_init_msg_multi_cnf);
break;
case SCTP_INIT_MSG_MULTI_CNF:
x2ap_eNB_handle_sctp_init_msg_multi_cnf(ITTI_MESSAGE_GET_INSTANCE(received_msg),
&received_msg->ittiMsg.sctp_init_msg_multi_cnf);
break;
case SCTP_NEW_ASSOCIATION_RESP:
x2ap_eNB_handle_sctp_association_resp(ITTI_MESSAGE_GET_INSTANCE(received_msg),
&received_msg->ittiMsg.sctp_new_association_resp);
break;
case SCTP_NEW_ASSOCIATION_RESP:
x2ap_eNB_handle_sctp_association_resp(ITTI_MESSAGE_GET_INSTANCE(received_msg),
&received_msg->ittiMsg.sctp_new_association_resp);
break;
case SCTP_NEW_ASSOCIATION_IND:
x2ap_eNB_handle_sctp_association_ind(ITTI_MESSAGE_GET_INSTANCE(received_msg),
&received_msg->ittiMsg.sctp_new_association_ind);
break;
case SCTP_NEW_ASSOCIATION_IND:
x2ap_eNB_handle_sctp_association_ind(ITTI_MESSAGE_GET_INSTANCE(received_msg),
&received_msg->ittiMsg.sctp_new_association_ind);
break;
case SCTP_DATA_IND:
x2ap_eNB_handle_sctp_data_ind(ITTI_MESSAGE_GET_INSTANCE(received_msg),
&received_msg->ittiMsg.sctp_data_ind);
break;
case SCTP_DATA_IND:
x2ap_eNB_handle_sctp_data_ind(ITTI_MESSAGE_GET_INSTANCE(received_msg),
&received_msg->ittiMsg.sctp_data_ind);
break;
default:
X2AP_ERROR("Received unhandled message: %d:%s\n",
ITTI_MSG_ID(received_msg), ITTI_MSG_NAME(received_msg));
break;
default:
X2AP_ERROR("Received unhandled message: %d:%s\n",
ITTI_MSG_ID(received_msg), ITTI_MSG_NAME(received_msg));
break;
}
result = itti_free (ITTI_MSG_ORIGIN_ID(received_msg), received_msg);
AssertFatal (result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result);
received_msg = NULL;
}
+41 -3
View File
@@ -57,7 +57,13 @@ Description Defines functions used to handle EPS bearer contexts.
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#ifdef PDCP_USE_NETLINK
#ifdef UESIM_EXPANSION
#include "openairinterface5g_limits.h"
extern uint16_t inst_pdcp_list[NUMBER_OF_UE_MAX];
#endif
#endif
extern uint8_t nfapi_mode;
/****************************************************************************/
/**************** E X T E R N A L D E F I N I T I O N S ****************/
@@ -208,7 +214,7 @@ int esm_ebr_context_create(
char broadcast[INET_ADDRSTRLEN];
struct in_addr in_addr;
char command_line[500];
int res;
int res = -1;
switch (pdn->type) {
case NET_PDN_TYPE_IPV4V6:
@@ -272,7 +278,38 @@ int esm_ebr_context_create(
strcpy(broadcast, ipv4_addr);
}
res = sprintf(command_line,
if(nfapi_mode ==3){
// this is for L2 FAPI simulator.
// change for multiple UE's like 256UEs.
// if it's made too many tables , OS may crush so we use one table.
#ifdef PDCP_USE_NETLINK
#ifdef UESIM_EXPANSION
uint16_t inst_nic = (pdn->ip_addr[3] & 0x000000FF) - 2;
res = sprintf(command_line,
"ifconfig oip%d %s netmask %s broadcast %s up && "
"ip rule add from %s/24 table %d && "
"ip rule add to %s/24 table %d && "
"ip route add default dev oip%d table %d",
inst_nic + 1, ipv4_addr, netmask, broadcast,
ipv4_addr, 201,
ipv4_addr, 201,
inst_nic + 1, 201);
inst_pdcp_list[inst_nic] = ueid;
#else
res = sprintf(command_line,
"ifconfig oip%d %s netmask %s broadcast %s up && "
"ip rule add from %s/32 table %d && "
"ip rule add to %s/32 table %d && "
"ip route add default dev oip%d table %d",
ueid + 1, ipv4_addr, netmask, broadcast,
ipv4_addr, ueid + 201,
ipv4_addr, ueid + 201,
ueid + 1, ueid + 201);
#endif
#endif
} else {
res = sprintf(command_line,
"ifconfig oip%d %s netmask %s broadcast %s up && "
"ip rule add from %s/32 table %d && "
"ip rule add to %s/32 table %d && "
@@ -281,6 +318,7 @@ int esm_ebr_context_create(
ipv4_addr, ueid + 201,
ipv4_addr, ueid + 201,
ueid + 1, ueid + 201);
}
if ( res<0 ) {
LOG_TRACE(WARNING, "ESM-PROC - Failed to system command string");
}
+47 -151
View File
@@ -85,94 +85,13 @@ static const uint8_t esm_message_ids[] = {
ESM_STATUS,
};
static int _nas_find_message_index(const uint8_t message_id, const uint8_t *message_ids, const int ids_number)
{
int i;
for(i = 0; i < ids_number; i ++) {
if (message_id == message_ids[i]) {
return (2 + i);
}
}
return (1);
int nas_itti_plain_msg(const char *buffer, const nas_message_t *msg, const int length, const int down_link) {
return 0;
}
int nas_itti_plain_msg(const char *buffer, const nas_message_t *msg, const int length, const int down_link)
{
MessageDef *message_p;
int data_length = length < NAS_DATA_LENGHT_MAX ? length : NAS_DATA_LENGHT_MAX;
int message_type = -1;
MessagesIds messageId_raw = -1;
MessagesIds messageId_plain = -1;
/* Define message ids */
if (msg->header.protocol_discriminator == EPS_MOBILITY_MANAGEMENT_MESSAGE) {
message_type = 0;
messageId_raw = down_link ? NAS_DL_EMM_RAW_MSG : NAS_UL_EMM_RAW_MSG;
messageId_plain = down_link ? NAS_DL_EMM_PLAIN_MSG : NAS_UL_EMM_PLAIN_MSG;
} else {
if (msg->header.protocol_discriminator == EPS_SESSION_MANAGEMENT_MESSAGE) {
message_type = 1;
messageId_raw = down_link ? NAS_DL_ESM_RAW_MSG : NAS_UL_ESM_RAW_MSG;
messageId_plain = down_link ? NAS_DL_ESM_PLAIN_MSG : NAS_UL_ESM_PLAIN_MSG;
}
}
if (message_type >= 0) {
/* Create and send the RAW message */
message_p = itti_alloc_new_message(TASK_ORIGIN, messageId_raw);
NAS_DL_EMM_RAW_MSG(message_p).lenght = length;
memset ((void *) &(NAS_DL_EMM_RAW_MSG(message_p).data), 0, NAS_DATA_LENGHT_MAX);
memcpy ((void *) &(NAS_DL_EMM_RAW_MSG(message_p).data), buffer, data_length);
itti_send_msg_to_task(TASK_UNKNOWN, INSTANCE_DEFAULT, message_p);
/* Create and send the plain message */
if (message_type == 0) {
message_p = itti_alloc_new_message(TASK_ORIGIN, messageId_plain);
NAS_DL_EMM_PLAIN_MSG(message_p).present = _nas_find_message_index(msg->plain.emm.header.message_type, emm_message_ids, sizeof(emm_message_ids) / sizeof(emm_message_ids[0]));
memcpy ((void *) &(NAS_DL_EMM_PLAIN_MSG(message_p).choice), &msg->plain.emm, sizeof (EMM_msg));
} else {
message_p = itti_alloc_new_message(TASK_ORIGIN, messageId_plain);
NAS_DL_ESM_PLAIN_MSG(message_p).present = _nas_find_message_index(msg->plain.esm.header.message_type, esm_message_ids, sizeof(esm_message_ids) / sizeof(esm_message_ids[0]));
memcpy ((void *) &(NAS_DL_ESM_PLAIN_MSG(message_p).choice), &msg->plain.esm, sizeof (ESM_msg));
}
return itti_send_msg_to_task(TASK_UNKNOWN, INSTANCE_DEFAULT, message_p);
}
return EXIT_FAILURE;
}
int nas_itti_protected_msg(const char *buffer, const nas_message_t *msg, const int length, const int down_link)
{
MessageDef *message_p = NULL;
if (msg->header.protocol_discriminator == EPS_MOBILITY_MANAGEMENT_MESSAGE) {
message_p = itti_alloc_new_message(TASK_ORIGIN, down_link ? NAS_DL_EMM_PROTECTED_MSG : NAS_UL_EMM_PROTECTED_MSG);
memcpy ((void *) &(NAS_DL_EMM_PROTECTED_MSG(message_p).header), &msg->header, sizeof (nas_message_security_header_t));
NAS_DL_EMM_PROTECTED_MSG(message_p).present = _nas_find_message_index(msg->security_protected.plain.emm.header.message_type, emm_message_ids, sizeof(emm_message_ids) / sizeof(emm_message_ids[0]));
memcpy ((void *) &(NAS_DL_EMM_PROTECTED_MSG(message_p).choice), &msg->security_protected.plain.emm, sizeof (EMM_msg));
} else {
if (msg->header.protocol_discriminator == EPS_SESSION_MANAGEMENT_MESSAGE) {
message_p = itti_alloc_new_message(TASK_ORIGIN, down_link ? NAS_DL_ESM_PROTECTED_MSG : NAS_UL_ESM_PROTECTED_MSG);
memcpy ((void *) &(NAS_DL_ESM_PROTECTED_MSG(message_p).header), &msg->header, sizeof (nas_message_security_header_t));
NAS_DL_ESM_PROTECTED_MSG(message_p).present = _nas_find_message_index(msg->security_protected.plain.esm.header.message_type, esm_message_ids, sizeof(esm_message_ids) / sizeof(esm_message_ids[0]));
memcpy ((void *) &(NAS_DL_ESM_PROTECTED_MSG(message_p).choice), &msg->security_protected.plain.esm, sizeof (ESM_msg));
}
}
if (message_p != NULL) {
return itti_send_msg_to_task(TASK_UNKNOWN, INSTANCE_DEFAULT, message_p);
}
return EXIT_FAILURE;
int nas_itti_protected_msg(const char *buffer, const nas_message_t *msg, const int length, const int down_link) {
return 0;
}
#endif
@@ -180,112 +99,89 @@ int nas_itti_protected_msg(const char *buffer, const nas_message_t *msg, const i
extern unsigned char NB_eNB_INST;
int nas_itti_kenb_refresh_req(const Byte_t kenb[32])
{
int nas_itti_kenb_refresh_req(const Byte_t kenb[32]) {
MessageDef *message_p;
message_p = itti_alloc_new_message(TASK_NAS_UE, NAS_KENB_REFRESH_REQ);
memcpy(NAS_KENB_REFRESH_REQ(message_p).kenb, kenb, sizeof(NAS_KENB_REFRESH_REQ(message_p).kenb));
MSC_LOG_TX_MESSAGE(
MSC_NAS_UE,
MSC_RRC_UE,
NULL,0,
"0 NAS_KENB_REFRESH_REQ KeNB "
"%02x%02x%02x%02x"
"%02x%02x%02x%02x"
"%02x%02x%02x%02x"
"%02x%02x%02x%02x"
"%02x%02x%02x%02x"
"%02x%02x%02x%02x"
"%02x%02x%02x%02x"
"%02x%02x%02x%02x",
kenb[0], kenb[1], kenb[2], kenb[3],
kenb[4], kenb[5], kenb[6], kenb[7],
kenb[8], kenb[9], kenb[10], kenb[11],
kenb[12], kenb[13], kenb[14], kenb[15],
kenb[16], kenb[17], kenb[18], kenb[19],
kenb[20], kenb[21], kenb[22], kenb[23],
kenb[24], kenb[25], kenb[26], kenb[27],
kenb[28], kenb[29], kenb[30], kenb[31]);
MSC_NAS_UE,
MSC_RRC_UE,
NULL,0,
"0 NAS_KENB_REFRESH_REQ KeNB "
"%02x%02x%02x%02x"
"%02x%02x%02x%02x"
"%02x%02x%02x%02x"
"%02x%02x%02x%02x"
"%02x%02x%02x%02x"
"%02x%02x%02x%02x"
"%02x%02x%02x%02x"
"%02x%02x%02x%02x",
kenb[0], kenb[1], kenb[2], kenb[3],
kenb[4], kenb[5], kenb[6], kenb[7],
kenb[8], kenb[9], kenb[10], kenb[11],
kenb[12], kenb[13], kenb[14], kenb[15],
kenb[16], kenb[17], kenb[18], kenb[19],
kenb[20], kenb[21], kenb[22], kenb[23],
kenb[24], kenb[25], kenb[26], kenb[27],
kenb[28], kenb[29], kenb[30], kenb[31]);
return itti_send_msg_to_task(TASK_RRC_UE, NB_eNB_INST + 0 /* TODO to be virtualized */, message_p);
}
int nas_itti_cell_info_req(const plmn_t plmnID, const Byte_t rat, int user_id)
{
int nas_itti_cell_info_req(const plmn_t plmnID, const Byte_t rat, int user_id) {
MessageDef *message_p;
message_p = itti_alloc_new_message(TASK_NAS_UE, NAS_CELL_SELECTION_REQ);
NAS_CELL_SELECTION_REQ(message_p).plmnID = plmnID;
NAS_CELL_SELECTION_REQ(message_p).rat = rat;
MSC_LOG_TX_MESSAGE(
MSC_NAS_UE,
MSC_RRC_UE,
NULL,0,
"0 NAS_CELL_SELECTION_REQ PLMN %X%X%X.%X%X%X",
plmnID.MCCdigit1, plmnID.MCCdigit2, plmnID.MCCdigit3,
plmnID.MNCdigit1, plmnID.MNCdigit2, plmnID.MNCdigit3);
MSC_NAS_UE,
MSC_RRC_UE,
NULL,0,
"0 NAS_CELL_SELECTION_REQ PLMN %X%X%X.%X%X%X",
plmnID.MCCdigit1, plmnID.MCCdigit2, plmnID.MCCdigit3,
plmnID.MNCdigit1, plmnID.MNCdigit2, plmnID.MNCdigit3);
return itti_send_msg_to_task(TASK_RRC_UE, NB_eNB_INST + user_id, message_p);
}
int nas_itti_nas_establish_req(as_cause_t cause, as_call_type_t type, as_stmsi_t s_tmsi, plmn_t plmnID, Byte_t *data, uint32_t length, int user_id)
{
int nas_itti_nas_establish_req(as_cause_t cause, as_call_type_t type, as_stmsi_t s_tmsi, plmn_t plmnID, Byte_t *data, uint32_t length, int user_id) {
MessageDef *message_p;
message_p = itti_alloc_new_message(TASK_NAS_UE, NAS_CONN_ESTABLI_REQ);
NAS_CONN_ESTABLI_REQ(message_p).cause = cause;
NAS_CONN_ESTABLI_REQ(message_p).type = type;
NAS_CONN_ESTABLI_REQ(message_p).s_tmsi = s_tmsi;
NAS_CONN_ESTABLI_REQ(message_p).plmnID = plmnID;
NAS_CONN_ESTABLI_REQ(message_p).initialNasMsg.data = data;
NAS_CONN_ESTABLI_REQ(message_p).initialNasMsg.length = length;
MSC_LOG_TX_MESSAGE(
MSC_NAS_UE,
MSC_RRC_UE,
NULL,0,
"0 NAS_CONN_ESTABLI_REQ MME code %u m-TMSI %u PLMN %X%X%X.%X%X%X",
s_tmsi.MMEcode, s_tmsi.m_tmsi,
plmnID.MCCdigit1, plmnID.MCCdigit2, plmnID.MCCdigit3,
plmnID.MNCdigit1, plmnID.MNCdigit2, plmnID.MNCdigit3);
MSC_NAS_UE,
MSC_RRC_UE,
NULL,0,
"0 NAS_CONN_ESTABLI_REQ MME code %u m-TMSI %u PLMN %X%X%X.%X%X%X",
s_tmsi.MMEcode, s_tmsi.m_tmsi,
plmnID.MCCdigit1, plmnID.MCCdigit2, plmnID.MCCdigit3,
plmnID.MNCdigit1, plmnID.MNCdigit2, plmnID.MNCdigit3);
return itti_send_msg_to_task(TASK_RRC_UE, NB_eNB_INST + user_id, message_p);
}
int nas_itti_ul_data_req(const uint32_t ue_id, void *const data, const uint32_t length, int user_id)
{
int nas_itti_ul_data_req(const uint32_t ue_id, void *const data, const uint32_t length, int user_id) {
MessageDef *message_p;
message_p = itti_alloc_new_message(TASK_NAS_UE, NAS_UPLINK_DATA_REQ);
NAS_UPLINK_DATA_REQ(message_p).UEid = ue_id;
NAS_UPLINK_DATA_REQ(message_p).nasMsg.data = data;
NAS_UPLINK_DATA_REQ(message_p).nasMsg.length = length;
return itti_send_msg_to_task(TASK_RRC_UE, NB_eNB_INST + user_id, message_p);
}
int nas_itti_rab_establish_rsp(const as_stmsi_t s_tmsi, const as_rab_id_t rabID, const nas_error_code_t errCode, int user_id)
{
int nas_itti_rab_establish_rsp(const as_stmsi_t s_tmsi, const as_rab_id_t rabID, const nas_error_code_t errCode, int user_id) {
MessageDef *message_p;
message_p = itti_alloc_new_message(TASK_NAS_UE, NAS_RAB_ESTABLI_RSP);
NAS_RAB_ESTABLI_RSP(message_p).s_tmsi = s_tmsi;
NAS_RAB_ESTABLI_RSP(message_p).rabID = rabID;
NAS_RAB_ESTABLI_RSP(message_p).errCode = errCode;
MSC_LOG_TX_MESSAGE(
MSC_NAS_UE,
MSC_RRC_UE,
NULL,0,
"0 NAS_RAB_ESTABLI_RSP MME code %u m-TMSI %u rb id %u status %u",
s_tmsi.MMEcode, s_tmsi.m_tmsi,rabID, errCode );
MSC_NAS_UE,
MSC_RRC_UE,
NULL,0,
"0 NAS_RAB_ESTABLI_RSP MME code %u m-TMSI %u rb id %u status %u",
s_tmsi.MMEcode, s_tmsi.m_tmsi,rabID, errCode );
return itti_send_msg_to_task(TASK_RRC_UE, NB_eNB_INST + user_id, message_p);
}
+1 -1
View File
@@ -40,7 +40,7 @@
// FIXME review these externs
extern unsigned char NB_eNB_INST;
extern unsigned char NB_UE_INST;
extern uint16_t NB_UE_INST;
char *make_port_str_from_ueid(const char *base_port_str, int ueid);
+4 -74
View File
@@ -36,103 +36,52 @@
#include "s1ap_common.h"
#include "s1ap_eNB_decoder.h"
static int s1ap_eNB_decode_initiating_message(S1AP_S1AP_PDU_t *pdu)
{
MessageDef *message_p;
MessagesIds message_id;
static int s1ap_eNB_decode_initiating_message(S1AP_S1AP_PDU_t *pdu) {
asn_encode_to_new_buffer_result_t res = { NULL, {0, NULL, NULL} };
DevAssert(pdu != NULL);
switch(pdu->choice.initiatingMessage.procedureCode) {
case S1AP_ProcedureCode_id_downlinkNASTransport:
res = asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_S1AP_S1AP_PDU, pdu);
message_id = S1AP_DOWNLINK_NAS_LOG;
message_p = itti_alloc_new_message_sized(TASK_S1AP, message_id,
res.result.encoded + sizeof (IttiMsgText));
message_p->ittiMsg.s1ap_downlink_nas_log.size = res.result.encoded;
memcpy(&message_p->ittiMsg.s1ap_downlink_nas_log.text, res.buffer, res.result.encoded);
itti_send_msg_to_task(TASK_UNKNOWN, INSTANCE_DEFAULT, message_p);
free(res.buffer);
break;
case S1AP_ProcedureCode_id_InitialContextSetup:
res = asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_S1AP_S1AP_PDU, pdu);
message_id = S1AP_INITIAL_CONTEXT_SETUP_LOG;
message_p = itti_alloc_new_message_sized(TASK_S1AP, message_id,
res.result.encoded + sizeof (IttiMsgText));
message_p->ittiMsg.s1ap_initial_context_setup_log.size = res.result.encoded;
memcpy(&message_p->ittiMsg.s1ap_initial_context_setup_log.text, res.buffer, res.result.encoded);
itti_send_msg_to_task(TASK_UNKNOWN, INSTANCE_DEFAULT, message_p);
free(res.buffer);
break;
case S1AP_ProcedureCode_id_UEContextRelease:
res = asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_S1AP_S1AP_PDU, pdu);
message_id = S1AP_UE_CONTEXT_RELEASE_COMMAND_LOG;
message_p = itti_alloc_new_message_sized(TASK_S1AP, message_id,
res.result.encoded + sizeof (IttiMsgText));
message_p->ittiMsg.s1ap_ue_context_release_command_log.size = res.result.encoded;
memcpy(&message_p->ittiMsg.s1ap_ue_context_release_command_log.text, res.buffer, res.result.encoded);
itti_send_msg_to_task(TASK_UNKNOWN, INSTANCE_DEFAULT, message_p);
free(res.buffer);
break;
case S1AP_ProcedureCode_id_Paging:
res = asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_S1AP_S1AP_PDU, pdu);
message_id = S1AP_PAGING_LOG;
message_p = itti_alloc_new_message_sized(TASK_S1AP, message_id,
res.result.encoded + sizeof (IttiMsgText));
message_p->ittiMsg.s1ap_paging_log.size = res.result.encoded;
memcpy(&message_p->ittiMsg.s1ap_paging_log.text, res.buffer, res.result.encoded);
itti_send_msg_to_task(TASK_UNKNOWN, INSTANCE_DEFAULT, message_p);
S1AP_INFO("Paging initiating message\n");
free(res.buffer);
break;
case S1AP_ProcedureCode_id_E_RABSetup:
res = asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_S1AP_S1AP_PDU, pdu);
message_id = S1AP_E_RAB_SETUP_REQUEST_LOG;
message_p = itti_alloc_new_message_sized(TASK_S1AP, message_id,
res.result.encoded + sizeof (IttiMsgText));
message_p->ittiMsg.s1ap_e_rab_setup_request_log.size = res.result.encoded;
memcpy(&message_p->ittiMsg.s1ap_e_rab_setup_request_log.text, res.buffer, res.result.encoded);
itti_send_msg_to_task(TASK_UNKNOWN, INSTANCE_DEFAULT, message_p);
free(res.buffer);
S1AP_INFO("E_RABSetup initiating message\n");
break;
case S1AP_ProcedureCode_id_E_RABModify:
res = asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_S1AP_S1AP_PDU, pdu);
message_id = S1AP_E_RAB_MODIFY_REQUEST_LOG;
message_p = itti_alloc_new_message_sized(TASK_S1AP, message_id,
res.result.encoded + sizeof (IttiMsgText));
message_p->ittiMsg.s1ap_e_rab_modify_request_log.size = res.result.encoded;
memcpy(&message_p->ittiMsg.s1ap_e_rab_modify_request_log.text, res.buffer, res.result.encoded);
itti_send_msg_to_task(TASK_UNKNOWN, INSTANCE_DEFAULT, message_p);
free(res.buffer);
S1AP_INFO("E_RABModify initiating message\n");
break;
case S1AP_ProcedureCode_id_E_RABRelease:
res = asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_S1AP_S1AP_PDU, pdu);
message_id = S1AP_E_RAB_RELEASE_REQUEST_LOG;
message_p = itti_alloc_new_message_sized(TASK_S1AP, message_id,
res.result.encoded + sizeof (IttiMsgText));
message_p->ittiMsg.s1ap_e_rab_release_request_log.size = res.result.encoded;
memcpy(&message_p->ittiMsg.s1ap_e_rab_release_request_log.text, res.buffer, res.result.encoded);
itti_send_msg_to_task(TASK_UNKNOWN, INSTANCE_DEFAULT, message_p);
free(res.buffer);
S1AP_INFO("TODO E_RABRelease initiating message\n");
break;
case S1AP_ProcedureCode_id_ErrorIndication:
res = asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_S1AP_S1AP_PDU, pdu);
message_id = S1AP_ERROR_INDICATION_LOG;
message_p = itti_alloc_new_message_sized(TASK_S1AP, message_id,
res.result.encoded + sizeof (IttiMsgText));
message_p->ittiMsg.s1ap_error_indication_log.size = res.result.encoded;
memcpy(&message_p->ittiMsg.s1ap_error_indication_log.text, res.buffer, res.result.encoded);
itti_send_msg_to_task(TASK_UNKNOWN, INSTANCE_DEFAULT, message_p);
free(res.buffer);
S1AP_INFO("TODO ErrorIndication initiating message\n");
break;
@@ -148,21 +97,13 @@ static int s1ap_eNB_decode_initiating_message(S1AP_S1AP_PDU_t *pdu)
return 0;
}
static int s1ap_eNB_decode_successful_outcome(S1AP_S1AP_PDU_t *pdu)
{
MessageDef *message_p;
MessagesIds message_id;
static int s1ap_eNB_decode_successful_outcome(S1AP_S1AP_PDU_t *pdu) {
asn_encode_to_new_buffer_result_t res = { NULL, {0, NULL, NULL} };
DevAssert(pdu != NULL);
switch(pdu->choice.successfulOutcome.procedureCode) {
case S1AP_ProcedureCode_id_S1Setup:
res = asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_S1AP_S1AP_PDU, pdu);
message_id = S1AP_S1_SETUP_LOG;
message_p = itti_alloc_new_message_sized(TASK_S1AP, message_id, res.result.encoded + sizeof (IttiMsgText));
message_p->ittiMsg.s1ap_s1_setup_log.size = res.result.encoded;
memcpy(&message_p->ittiMsg.s1ap_s1_setup_log.text, res.buffer, res.result.encoded);
itti_send_msg_to_task(TASK_UNKNOWN, INSTANCE_DEFAULT, message_p);
free(res.buffer);
break;
@@ -185,21 +126,13 @@ static int s1ap_eNB_decode_successful_outcome(S1AP_S1AP_PDU_t *pdu)
return 0;
}
static int s1ap_eNB_decode_unsuccessful_outcome(S1AP_S1AP_PDU_t *pdu)
{
MessageDef *message_p;
MessagesIds message_id;
static int s1ap_eNB_decode_unsuccessful_outcome(S1AP_S1AP_PDU_t *pdu) {
asn_encode_to_new_buffer_result_t res = { NULL, {0, NULL, NULL} };
DevAssert(pdu != NULL);
switch(pdu->choice.unsuccessfulOutcome.procedureCode) {
case S1AP_ProcedureCode_id_S1Setup:
res = asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_S1AP_S1AP_PDU, pdu);
message_id = S1AP_S1_SETUP_LOG;
message_p = itti_alloc_new_message_sized(TASK_S1AP, message_id, res.result.encoded + sizeof (IttiMsgText));
message_p->ittiMsg.s1ap_s1_setup_log.size = res.result.encoded;
memcpy(&message_p->ittiMsg.s1ap_s1_setup_log.text, res.buffer, res.result.encoded);
itti_send_msg_to_task(TASK_UNKNOWN, INSTANCE_DEFAULT, message_p);
free(res.buffer);
break;
case S1AP_ProcedureCode_id_PathSwitchRequest:
@@ -222,13 +155,10 @@ static int s1ap_eNB_decode_unsuccessful_outcome(S1AP_S1AP_PDU_t *pdu)
}
int s1ap_eNB_decode_pdu(S1AP_S1AP_PDU_t *pdu, const uint8_t *const buffer,
const uint32_t length)
{
const uint32_t length) {
asn_dec_rval_t dec_ret;
DevAssert(pdu != NULL);
DevAssert(buffer != NULL);
dec_ret = aper_decode(NULL,
&asn_DEF_S1AP_S1AP_PDU,
(void **)&pdu,
+4 -74
View File
@@ -47,8 +47,7 @@ static inline int s1ap_eNB_encode_successfull_outcome(S1AP_S1AP_PDU_t *pdu,
static inline int s1ap_eNB_encode_unsuccessfull_outcome(S1AP_S1AP_PDU_t *pdu,
uint8_t **buffer, uint32_t *len);
int s1ap_eNB_encode_pdu(S1AP_S1AP_PDU_t *pdu, uint8_t **buffer, uint32_t *len)
{
int s1ap_eNB_encode_pdu(S1AP_S1AP_PDU_t *pdu, uint8_t **buffer, uint32_t *len) {
int ret = -1;
DevAssert(pdu != NULL);
DevAssert(buffer != NULL);
@@ -79,71 +78,38 @@ int s1ap_eNB_encode_pdu(S1AP_S1AP_PDU_t *pdu, uint8_t **buffer, uint32_t *len)
static inline
int s1ap_eNB_encode_initiating(S1AP_S1AP_PDU_t *pdu,
uint8_t **buffer, uint32_t *len)
{
MessageDef *message_p;
MessagesIds message_id;
uint8_t **buffer, uint32_t *len) {
asn_encode_to_new_buffer_result_t res = { NULL, {0, NULL, NULL} };
DevAssert(pdu != NULL);
switch(pdu->choice.initiatingMessage.procedureCode) {
case S1AP_ProcedureCode_id_S1Setup:
res = asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_S1AP_S1AP_PDU, pdu);
message_id = S1AP_S1_SETUP_LOG;
message_p = itti_alloc_new_message_sized(TASK_S1AP, message_id, res.result.encoded + sizeof (IttiMsgText));
message_p->ittiMsg.s1ap_s1_setup_log.size = res.result.encoded;
memcpy(&message_p->ittiMsg.s1ap_s1_setup_log.text, res.buffer, res.result.encoded);
itti_send_msg_to_task(TASK_UNKNOWN, INSTANCE_DEFAULT, message_p);
free(res.buffer);
break;
case S1AP_ProcedureCode_id_uplinkNASTransport:
res = asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_S1AP_S1AP_PDU, pdu);
message_id = S1AP_UPLINK_NAS_LOG;
message_p = itti_alloc_new_message_sized(TASK_S1AP, message_id, res.result.encoded + sizeof (IttiMsgText));
message_p->ittiMsg.s1ap_uplink_nas_log.size = res.result.encoded;
memcpy(&message_p->ittiMsg.s1ap_uplink_nas_log.text, res.buffer, res.result.encoded);
itti_send_msg_to_task(TASK_UNKNOWN, INSTANCE_DEFAULT, message_p);
free(res.buffer);
break;
case S1AP_ProcedureCode_id_UECapabilityInfoIndication:
res = asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_S1AP_S1AP_PDU, pdu);
message_id = S1AP_UE_CAPABILITY_IND_LOG;
message_p = itti_alloc_new_message_sized(TASK_S1AP, message_id, res.result.encoded + sizeof (IttiMsgText));
message_p->ittiMsg.s1ap_ue_capability_ind_log.size = res.result.encoded;
memcpy(&message_p->ittiMsg.s1ap_ue_capability_ind_log.text, res.buffer, res.result.encoded);
itti_send_msg_to_task(TASK_UNKNOWN, INSTANCE_DEFAULT, message_p);
free(res.buffer);
break;
case S1AP_ProcedureCode_id_initialUEMessage:
res = asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_S1AP_S1AP_PDU, pdu);
message_id = S1AP_INITIAL_UE_MESSAGE_LOG;
message_p = itti_alloc_new_message_sized(TASK_S1AP, message_id, res.result.encoded + sizeof (IttiMsgText));
message_p->ittiMsg.s1ap_initial_ue_message_log.size = res.result.encoded;
memcpy(&message_p->ittiMsg.s1ap_initial_ue_message_log.text, res.buffer, res.result.encoded);
itti_send_msg_to_task(TASK_UNKNOWN, INSTANCE_DEFAULT, message_p);
free(res.buffer);
break;
case S1AP_ProcedureCode_id_NASNonDeliveryIndication:
res = asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_S1AP_S1AP_PDU, pdu);
message_id = S1AP_NAS_NON_DELIVERY_IND_LOG;
message_p = itti_alloc_new_message_sized(TASK_S1AP, message_id, res.result.encoded + sizeof (IttiMsgText));
message_p->ittiMsg.s1ap_nas_non_delivery_ind_log.size = res.result.encoded;
memcpy(&message_p->ittiMsg.s1ap_nas_non_delivery_ind_log.text, res.buffer, res.result.encoded);
itti_send_msg_to_task(TASK_UNKNOWN, INSTANCE_DEFAULT, message_p);
free(res.buffer);
break;
case S1AP_ProcedureCode_id_UEContextReleaseRequest:
res = asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_S1AP_S1AP_PDU, pdu);
message_id = S1AP_UE_CONTEXT_RELEASE_REQ_LOG;
message_p = itti_alloc_new_message_sized(TASK_S1AP, message_id, res.result.encoded + sizeof (IttiMsgText));
message_p->ittiMsg.s1ap_ue_context_release_req_log.size = res.result.encoded;
memcpy(&message_p->ittiMsg.s1ap_ue_context_release_req_log.text, res.buffer, res.result.encoded);
itti_send_msg_to_task(TASK_UNKNOWN, INSTANCE_DEFAULT, message_p);
free(res.buffer);
break;
@@ -176,63 +142,35 @@ int s1ap_eNB_encode_initiating(S1AP_S1AP_PDU_t *pdu,
static inline
int s1ap_eNB_encode_successfull_outcome(S1AP_S1AP_PDU_t *pdu,
uint8_t **buffer, uint32_t *len)
{
MessageDef *message_p;
MessagesIds message_id;
uint8_t **buffer, uint32_t *len) {
asn_encode_to_new_buffer_result_t res = { NULL, {0, NULL, NULL} };
DevAssert(pdu != NULL);
switch(pdu->choice.successfulOutcome.procedureCode) {
case S1AP_ProcedureCode_id_InitialContextSetup:
res = asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_S1AP_S1AP_PDU, pdu);
message_id = S1AP_INITIAL_CONTEXT_SETUP_LOG;
message_p = itti_alloc_new_message_sized(TASK_S1AP, message_id, res.result.encoded + sizeof (IttiMsgText));
message_p->ittiMsg.s1ap_initial_context_setup_log.size = res.result.encoded;
memcpy(&message_p->ittiMsg.s1ap_initial_context_setup_log.text, res.buffer, res.result.encoded);
itti_send_msg_to_task(TASK_UNKNOWN, INSTANCE_DEFAULT, message_p);
free(res.buffer);
break;
case S1AP_ProcedureCode_id_UEContextRelease:
res = asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_S1AP_S1AP_PDU, pdu);
message_id = S1AP_UE_CONTEXT_RELEASE_COMPLETE_LOG;
message_p = itti_alloc_new_message_sized(TASK_S1AP, message_id, res.result.encoded + sizeof (IttiMsgText));
message_p->ittiMsg.s1ap_ue_context_release_complete_log.size = res.result.encoded;
memcpy(&message_p->ittiMsg.s1ap_ue_context_release_complete_log.text, res.buffer, res.result.encoded);
itti_send_msg_to_task(TASK_UNKNOWN, INSTANCE_DEFAULT, message_p);
free(res.buffer);
break;
case S1AP_ProcedureCode_id_E_RABSetup:
res = asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_S1AP_S1AP_PDU, pdu);
message_id = S1AP_E_RAB_SETUP_RESPONSE_LOG;
message_p = itti_alloc_new_message_sized(TASK_S1AP, message_id, res.result.encoded + sizeof (IttiMsgText));
message_p->ittiMsg.s1ap_e_rab_setup_response_log.size = res.result.encoded;
memcpy(&message_p->ittiMsg.s1ap_e_rab_setup_response_log.text, res.buffer, res.result.encoded);
itti_send_msg_to_task(TASK_UNKNOWN, INSTANCE_DEFAULT, message_p);
free(res.buffer);
S1AP_INFO("E_RABSetup successful message\n");
break;
case S1AP_ProcedureCode_id_E_RABModify:
res = asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_S1AP_S1AP_PDU, pdu);
message_id = S1AP_E_RAB_MODIFY_RESPONSE_LOG;
message_p = itti_alloc_new_message_sized(TASK_S1AP, message_id, res.result.encoded + sizeof (IttiMsgText));
message_p->ittiMsg.s1ap_e_rab_modify_response_log.size = res.result.encoded;
memcpy(&message_p->ittiMsg.s1ap_e_rab_modify_response_log.text, res.buffer, res.result.encoded);
itti_send_msg_to_task(TASK_UNKNOWN, INSTANCE_DEFAULT, message_p);
free(res.buffer);
S1AP_INFO("E_RABModify successful message\n");
break;
case S1AP_ProcedureCode_id_E_RABRelease:
res = asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_S1AP_S1AP_PDU, pdu);
message_id = S1AP_E_RAB_RELEASE_RESPONSE_LOG;
message_p = itti_alloc_new_message_sized(TASK_S1AP, message_id, res.result.encoded + sizeof (IttiMsgText));
message_p->ittiMsg.s1ap_e_rab_release_response_log.size = res.result.encoded;
memcpy(&message_p->ittiMsg.s1ap_e_rab_release_response_log.text, res.buffer, res.result.encoded);
itti_send_msg_to_task(TASK_UNKNOWN, INSTANCE_DEFAULT, message_p);
free(res.buffer);
S1AP_INFO("E_RAB Release successful message\n");
break;
@@ -256,21 +194,13 @@ int s1ap_eNB_encode_successfull_outcome(S1AP_S1AP_PDU_t *pdu,
static inline
int s1ap_eNB_encode_unsuccessfull_outcome(S1AP_S1AP_PDU_t *pdu,
uint8_t **buffer, uint32_t *len)
{
MessageDef *message_p;
MessagesIds message_id;
uint8_t **buffer, uint32_t *len) {
asn_encode_to_new_buffer_result_t res = { NULL, {0, NULL, NULL} };
DevAssert(pdu != NULL);
switch(pdu->choice.unsuccessfulOutcome.procedureCode) {
case S1AP_ProcedureCode_id_InitialContextSetup:
res = asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_S1AP_S1AP_PDU, pdu);
message_id = S1AP_INITIAL_CONTEXT_SETUP_LOG;
message_p = itti_alloc_new_message_sized(TASK_S1AP, message_id, res.result.encoded + sizeof (IttiMsgText));
message_p->ittiMsg.s1ap_initial_context_setup_log.size = res.result.encoded;
memcpy(&message_p->ittiMsg.s1ap_initial_context_setup_log.text, res.buffer, res.result.encoded);
itti_send_msg_to_task(TASK_UNKNOWN, INSTANCE_DEFAULT, message_p);
free(res.buffer);
break;
+54 -58
View File
@@ -25,40 +25,34 @@
# include "common/utils/LOG/log.h"
# include "targets/RT/USER/lte-softmodem.h"
# ifdef OPENAIR2
# if defined(ENABLE_USE_MME)
# include "sctp_eNB_task.h"
# include "x2ap_eNB.h"
# include "s1ap_eNB.h"
# include "nas_ue_task.h"
# include "udp_eNB_task.h"
# include "gtpv1u_eNB_task.h"
/* temporary warning removale while implementing noS1 */
/* as config option */
# else
# ifdef EPC_MODE_ENABLED
# undef EPC_MODE_ENABLED
# endif
# define EPC_MODE_ENABLED 0
# endif
# if ENABLE_RAL
# include "lteRALue.h"
# include "lteRALenb.h"
# endif
# include "RRC/LTE/rrc_defs.h"
# endif
#ifdef OPENAIR2
#if defined(ENABLE_USE_MME)
#include "sctp_eNB_task.h"
#include "x2ap_eNB.h"
#include "s1ap_eNB.h"
#include "nas_ue_task.h"
#include "udp_eNB_task.h"
#include "gtpv1u_eNB_task.h"
/* temporary warning removale while implementing noS1 */
/* as config option */
#else
#ifdef EPC_MODE_ENABLED
#undef EPC_MODE_ENABLED
#endif
#define EPC_MODE_ENABLED 0
#endif
#if ENABLE_RAL
#include "lteRALue.h"
#include "lteRALenb.h"
#endif
#include "RRC/LTE/rrc_defs.h"
#endif
# include "enb_app.h"
int create_tasks(uint32_t enb_nb)
{
int create_tasks(uint32_t enb_nb) {
LOG_D(ENB_APP, "%s(enb_nb:%d\n", __FUNCTION__, enb_nb);
itti_wait_ready(1);
if (itti_create_task (TASK_L2L1, l2l1_task, NULL) < 0) {
LOG_E(PDCP, "Create task for L2L1 failed\n");
return -1;
}
if (enb_nb > 0) {
/* Last task to create, others task must be ready before its start */
@@ -67,50 +61,52 @@ int create_tasks(uint32_t enb_nb)
return -1;
}
}
# if defined(ENABLE_USE_MME)
if (EPC_MODE_ENABLED) {
if (enb_nb > 0) {
if (itti_create_task (TASK_X2AP, x2ap_task, NULL) < 0) {
LOG_E(X2AP, "Create task for X2AP failed\n");
return -1;
}
if (enb_nb > 0) {
if (itti_create_task (TASK_X2AP, x2ap_task, NULL) < 0) {
LOG_E(X2AP, "Create task for X2AP failed\n");
return -1;
}
if (itti_create_task (TASK_SCTP, sctp_eNB_task, NULL) < 0) {
LOG_E(SCTP, "Create task for SCTP failed\n");
return -1;
}
if (itti_create_task (TASK_SCTP, sctp_eNB_task, NULL) < 0) {
LOG_E(SCTP, "Create task for SCTP failed\n");
return -1;
}
if (itti_create_task (TASK_S1AP, s1ap_eNB_task, NULL) < 0) {
LOG_E(S1AP, "Create task for S1AP failed\n");
return -1;
}
if(!(get_softmodem_params()->emulate_rf)){
if (itti_create_task (TASK_UDP, udp_eNB_task, NULL) < 0) {
LOG_E(UDP_, "Create task for UDP failed\n");
return -1;
}
}
if (itti_create_task (TASK_S1AP, s1ap_eNB_task, NULL) < 0) {
LOG_E(S1AP, "Create task for S1AP failed\n");
return -1;
}
if (itti_create_task (TASK_GTPV1_U, &gtpv1u_eNB_task, NULL) < 0) {
LOG_E(GTPU, "Create task for GTPV1U failed\n");
if(!(get_softmodem_params()->emulate_rf)) {
if (itti_create_task (TASK_UDP, udp_eNB_task, NULL) < 0) {
LOG_E(UDP_, "Create task for UDP failed\n");
return -1;
}
}
} /* if (EPC_MODE_ENABLED) */
#endif
if (enb_nb > 0) {
LOG_I(RRC,"Creating RRC eNB Task\n");
if (itti_create_task (TASK_RRC_ENB, rrc_enb_task, NULL) < 0) {
LOG_E(RRC, "Create task for RRC eNB failed\n");
if (itti_create_task (TASK_GTPV1_U, &gtpv1u_eNB_task, NULL) < 0) {
LOG_E(GTPU, "Create task for GTPV1U failed\n");
return -1;
}
}
} /* if (EPC_MODE_ENABLED) */
#endif
if (enb_nb > 0) {
LOG_I(RRC,"Creating RRC eNB Task\n");
if (itti_create_task (TASK_RRC_ENB, rrc_enb_task, NULL) < 0) {
LOG_E(RRC, "Create task for RRC eNB failed\n");
return -1;
}
}
itti_wait_ready(0);
return 0;
}
#endif
+34 -39
View File
@@ -24,57 +24,52 @@
# include "create_tasks.h"
# include "common/utils/LOG/log.h"
# ifdef OPENAIR2
# if defined(ENABLE_USE_MME)
# include "sctp_eNB_task.h"
# include "s1ap_eNB.h"
# include "nas_ue_task.h"
# include "udp_eNB_task.h"
# include "gtpv1u_eNB_task.h"
# endif
# if ENABLE_RAL
# include "lteRALue.h"
# include "lteRALenb.h"
# endif
# include "RRC/LTE/rrc_defs.h"
# endif
#ifdef OPENAIR2
#if defined(ENABLE_USE_MME)
#include "sctp_eNB_task.h"
#include "s1ap_eNB.h"
#include "nas_ue_task.h"
#include "udp_eNB_task.h"
#include "gtpv1u_eNB_task.h"
#endif
#if ENABLE_RAL
#include "lteRALue.h"
#include "lteRALenb.h"
#endif
#include "RRC/LTE/rrc_defs.h"
#endif
# include "enb_app.h"
int create_tasks_ue(uint32_t ue_nb)
{
int create_tasks_ue(uint32_t ue_nb) {
LOG_D(ENB_APP, "%s(ue_nb:%d)\n", __FUNCTION__, ue_nb);
itti_wait_ready(1);
if (itti_create_task (TASK_L2L1, l2l1_task, NULL) < 0) {
LOG_E(PDCP, "Create task for L2L1 failed\n");
return -1;
}
# if defined(ENABLE_USE_MME)
# if defined(NAS_BUILT_IN_UE)
if (ue_nb > 0) {
nas_user_container_t *users = calloc(1, sizeof(*users));
if (users == NULL) abort();
users->count = ue_nb;
if (itti_create_task (TASK_NAS_UE, nas_ue_task, users) < 0) {
LOG_E(NAS, "Create task for NAS UE failed\n");
return -1;
}
}
# endif
# endif
if (ue_nb > 0) {
if (itti_create_task (TASK_RRC_UE, rrc_ue_task, NULL) < 0) {
LOG_E(RRC, "Create task for RRC UE failed\n");
return -1;
}
if (ue_nb > 0) {
nas_user_container_t *users = calloc(1, sizeof(*users));
if (users == NULL) abort();
users->count = ue_nb;
if (itti_create_task (TASK_NAS_UE, nas_ue_task, users) < 0) {
LOG_E(NAS, "Create task for NAS UE failed\n");
return -1;
}
}
# endif
# endif
if (ue_nb > 0) {
if (itti_create_task (TASK_RRC_UE, rrc_ue_task, NULL) < 0) {
LOG_E(RRC, "Create task for RRC UE failed\n");
return -1;
}
}
itti_wait_ready(0);
return 0;
}
#endif
+21 -1
View File
@@ -5,8 +5,18 @@
# define NUMBER_OF_eNB_MAX 1
# define NUMBER_OF_RU_MAX 2
# ifndef UE_EXPANSION
// TODO:L2 FAPI simulator.
// UESIM_EXPANSION is used to be same value of NUMBER_OF_UE_MAX
// in eNB and UE.
// now , if we use --mu option in UE, compiling error will occur.
// This problem will be fixed in the future.
# ifndef UESIM_EXPANSION
# define NUMBER_OF_UE_MAX 16
# define NUMBER_OF_CONNECTED_eNB_MAX 3
# else
# define NUMBER_OF_UE_MAX 256
# define NUMBER_OF_CONNECTED_eNB_MAX 1
# endif
# else
# define NUMBER_OF_UE_MAX 256
# define NUMBER_OF_CONNECTED_eNB_MAX 1
@@ -15,8 +25,18 @@
# define NUMBER_OF_eNB_MAX 7
# define NUMBER_OF_RU_MAX 32
# ifndef UE_EXPANSION
# define NUMBER_OF_UE_MAX 20
/* if the value of MAX_MOBILES_PER_ENB and NUMBER_OF_UE_MAX is different,
eNB process will exit because unexpected access happens.
Now some parts are using NUMBER_OF_UE_MAX
and the other are using MAX_MOBILES_PER_ENB in for-loop.
*/
# ifndef UESIM_EXPANSION
# define NUMBER_OF_UE_MAX 16
# define NUMBER_OF_CONNECTED_eNB_MAX 3
# else
# define NUMBER_OF_UE_MAX 256
# define NUMBER_OF_CONNECTED_eNB_MAX 1
# endif
# else
# define NUMBER_OF_UE_MAX 256
# define NUMBER_OF_CONNECTED_eNB_MAX 1
@@ -172,7 +172,7 @@ eNBs =
////////// MME parameters:
mme_ip_address = ( { ipv4 = "127.0.0.3";
mme_ip_address = ( { ipv4 = "192.168.12.26";
ipv6 = "192:168:30::17";
active = "yes";
preference = "ipv4";
@@ -181,14 +181,24 @@ eNBs =
NETWORK_INTERFACES :
{
ENB_INTERFACE_NAME_FOR_S1_MME = "lo";
ENB_IPV4_ADDRESS_FOR_S1_MME = "127.0.0.2/24";
ENB_INTERFACE_NAME_FOR_S1U = "lo";
ENB_IPV4_ADDRESS_FOR_S1U = "127.0.0.5/24";
ENB_PORT_FOR_S1U = 2152; # Spec 2152
#ENB_INTERFACE_NAME_FOR_S1_MME = "lo";
#ENB_IPV4_ADDRESS_FOR_S1_MME = "127.0.0.2/24";
#ENB_INTERFACE_NAME_FOR_S1U = "lo";
#ENB_IPV4_ADDRESS_FOR_S1U = "127.0.0.5/24";
#ENB_PORT_FOR_S1U = 2152; # Spec 2152
ENB_IPV4_ADDRESS_FOR_X2C = "127.0.0.2/24";
#ENB_IPV4_ADDRESS_FOR_X2C = "127.0.0.2/24";
#ENB_PORT_FOR_X2C = 36422; # Spec 36422
ENB_INTERFACE_NAME_FOR_S1_MME = "enp0s31f6";
ENB_IPV4_ADDRESS_FOR_S1_MME = "192.168.12.188/24";
ENB_INTERFACE_NAME_FOR_S1U = "enp0s31f6";
ENB_IPV4_ADDRESS_FOR_S1U = "192.168.12.188/24";
ENB_PORT_FOR_S1U = 2152; # Spec 2152
ENB_IPV4_ADDRESS_FOR_X2C = "192.168.12.188/24";
ENB_PORT_FOR_X2C = 36422; # Spec 36422
};
}
);
@@ -196,7 +206,7 @@ eNBs =
MACRLCs = (
{
num_cc = 1;
local_s_if_name = "lo";
local_s_if_name = "lo:";
remote_s_address = "127.0.0.1";
local_s_address = "127.0.0.2";
local_s_portc = 50001;
+44
View File
@@ -164,6 +164,10 @@ static inline int rxtx(PHY_VARS_eNB *eNB,L1_rxtx_proc_t *proc, char *thread_name
// *******************************************************************
#if defined(PRE_SCD_THREAD)
RU_t *ru = RC.ru[0];
#endif
if (nfapi_mode == 1) {
// I am a PNF and I need to let nFAPI know that we have a (sub)frame tick
uint16_t frame = proc->frame_rx;
@@ -218,6 +222,40 @@ static inline int rxtx(PHY_VARS_eNB *eNB,L1_rxtx_proc_t *proc, char *thread_name
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_ULSCH_SCHEDULER, 1 );
#if defined(PRE_SCD_THREAD)
if (nfapi_mode == 2){
new_dlsch_ue_select_tbl_in_use = dlsch_ue_select_tbl_in_use;
dlsch_ue_select_tbl_in_use = !dlsch_ue_select_tbl_in_use;
// L2-emulator can work only one eNB.
// memcpy(&pre_scd_eNB_UE_stats,&RC.mac[ru->eNB_list[0]->Mod_id]->UE_list.eNB_UE_stats, sizeof(eNB_UE_STATS)*MAX_NUM_CCs*NUMBER_OF_UE_MAX);
// memcpy(&pre_scd_activeUE, &RC.mac[ru->eNB_list[0]->Mod_id]->UE_list.active, sizeof(boolean_t)*NUMBER_OF_UE_MAX);
memcpy(&pre_scd_eNB_UE_stats,&RC.mac[0]->UE_list.eNB_UE_stats, sizeof(eNB_UE_STATS)*MAX_NUM_CCs*NUMBER_OF_UE_MAX);
memcpy(&pre_scd_activeUE, &RC.mac[0]->UE_list.active, sizeof(boolean_t)*NUMBER_OF_UE_MAX);
if (pthread_mutex_lock(&ru->proc.mutex_pre_scd)!= 0) {
LOG_E( PHY, "[eNB] error locking proc mutex for eNB pre scd\n");
exit_fun("error locking mutex_time");
}
ru->proc.instance_pre_scd++;
if (ru->proc.instance_pre_scd == 0) {
if (pthread_cond_signal(&ru->proc.cond_pre_scd) != 0) {
LOG_E( PHY, "[eNB] ERROR pthread_cond_signal for eNB pre scd\n" );
exit_fun( "ERROR pthread_cond_signal cond_pre_scd" );
}
}else{
LOG_E( PHY, "[eNB] frame %d subframe %d rxtx busy instance_pre_scd %d\n",
proc->frame_rx,proc->subframe_rx,ru->proc.instance_pre_scd );
}
if (pthread_mutex_unlock(&ru->proc.mutex_pre_scd)!= 0) {
LOG_E( PHY, "[eNB] error unlocking mutex_pre_scd mutex for eNB pre scd\n");
exit_fun("error unlocking mutex_pre_scd");
}
}
#endif
pthread_mutex_lock(&eNB->UL_INFO_mutex);
eNB->UL_INFO.frame = proc->frame_rx;
@@ -906,6 +944,12 @@ void init_eNB_proc(int inst) {
if ((get_thread_parallel_conf() == PARALLEL_RU_L1_SPLIT || get_thread_parallel_conf() == PARALLEL_RU_L1_TRX_SPLIT) && nfapi_mode!=2) {
pthread_create( &L1_proc->pthread, attr0, L1_thread, proc );
pthread_create( &L1_proc_tx->pthread, attr1, L1_thread_tx, proc);
} else if (nfapi_mode == 2) { // this is neccesary in VNF or L2 FAPI simulator.
// Original Code from Fujitsu w/ old structure/field name
//pthread_create( &proc_rxtx[0].pthread_rxtx, attr0, eNB_thread_rxtx, &proc_rxtx[0] );
//pthread_create( &proc_rxtx[1].pthread_rxtx, attr1, eNB_thread_rxtx, &proc_rxtx[1] );
pthread_create( &L1_proc->pthread, attr0, L1_thread, L1_proc );
pthread_create( &L1_proc_tx->pthread, attr1, L1_thread, L1_proc_tx);
}
pthread_create( &proc->pthread_prach, attr_prach, eNB_thread_prach, eNB );
+124 -2
View File
@@ -118,7 +118,11 @@ static int DEFENBS[] = {0};
#include "pdcp.h"
extern volatile int oai_exit;
extern int emulate_rf;
extern int numerology;
extern clock_source_t clock_source;
extern uint8_t dlsch_ue_select_tbl_in_use;
extern uint8_t nfapi_mode;
extern PARALLEL_CONF_t get_thread_parallel_conf(void);
extern WORKER_CONF_t get_thread_worker_conf(void);
@@ -141,6 +145,11 @@ int connect_rau(RU_t *ru);
extern uint16_t sf_ahead;
#if defined(PRE_SCD_THREAD)
void init_ru_vnf(void);
#endif
/*************************************************************/
/* Functions to attach and configure RRU */
@@ -1942,7 +1951,12 @@ void* pre_scd_thread( void* param ){
int CC_id;
int Mod_id;
RU_t *ru = (RU_t*)param;
Mod_id = ru->eNB_list[0]->Mod_id;
// L2-emulator can work only one eNB
if( nfapi_mode == 2)
Mod_id = 0;
else
Mod_id = ru->eNB_list[0]->Mod_id;
frame = 0;
subframe = 4;
@@ -2820,6 +2834,114 @@ void stop_RU(int nb_ru)
}
}
//Some of the member of ru pointer is used in pre_scd.
//This funtion is for initializing ru pointer for L2 FAPI simulator.
#if defined(PRE_SCD_THREAD)
void init_ru_vnf(void) {
int ru_id;
RU_t *ru;
RU_proc_t *proc;
// PHY_VARS_eNB *eNB0= (PHY_VARS_eNB *)NULL;
int i;
int CC_id;
dlsch_ue_select_tbl_in_use = 1;
// create status mask
RC.ru_mask = 0;
pthread_mutex_init(&RC.ru_mutex,NULL);
pthread_cond_init(&RC.ru_cond,NULL);
// read in configuration file)
printf("configuring RU from file\n");
RCconfig_RU();
LOG_I(PHY,"number of L1 instances %d, number of RU %d, number of CPU cores %d\n",RC.nb_L1_inst,RC.nb_RU,get_nprocs());
if (RC.nb_CC != 0)
for (i=0;i<RC.nb_L1_inst;i++)
for (CC_id=0;CC_id<RC.nb_CC[i];CC_id++) RC.eNB[i][CC_id]->num_RU=0;
LOG_D(PHY,"Process RUs RC.nb_RU:%d\n",RC.nb_RU);
for (ru_id=0;ru_id<RC.nb_RU;ru_id++) {
LOG_D(PHY,"Process RC.ru[%d]\n",ru_id);
ru = RC.ru[ru_id];
// ru->rf_config_file = rf_config_file;
ru->idx = ru_id;
ru->ts_offset = 0;
// use eNB_list[0] as a reference for RU frame parameters
// NOTE: multiple CC_id are not handled here yet!
if (ru->num_eNB > 0) {
// LOG_D(PHY, "%s() RC.ru[%d].num_eNB:%d ru->eNB_list[0]:%p RC.eNB[0][0]:%p rf_config_file:%s\n", __FUNCTION__, ru_id, ru->num_eNB, ru->eNB_list[0], RC.eNB[0][0], ru->rf_config_file);
if (ru->eNB_list[0] == 0)
{
LOG_E(PHY,"%s() DJP - ru->eNB_list ru->num_eNB are not initialized - so do it manually\n", __FUNCTION__);
ru->eNB_list[0] = RC.eNB[0][0];
ru->num_eNB=1;
//
// DJP - feptx_prec() / feptx_ofdm() parses the eNB_list (based on num_eNB) and copies the txdata_F to txdata in RU
//
}
else
{
LOG_E(PHY,"DJP - delete code above this %s:%d\n", __FILE__, __LINE__);
}
}
// frame_parms is not used in L2 FAPI simulator
/*
eNB0 = ru->eNB_list[0];
LOG_D(PHY, "RU FUnction:%d ru->if_south:%d\n", ru->function, ru->if_south);
LOG_D(PHY, "eNB0:%p\n", eNB0);
if (eNB0)
{
if ((ru->function != NGFI_RRU_IF5) && (ru->function != NGFI_RRU_IF4p5))
AssertFatal(eNB0!=NULL,"eNB0 is null!\n");
if (eNB0) {
LOG_I(PHY,"Copying frame parms from eNB %d to ru %d\n",eNB0->Mod_id,ru->idx);
memcpy((void*)&ru->frame_parms,(void*)&eNB0->frame_parms,sizeof(LTE_DL_FRAME_PARMS));
// attach all RU to all eNBs in its list/
LOG_D(PHY,"ru->num_eNB:%d eNB0->num_RU:%d\n", ru->num_eNB, eNB0->num_RU);
for (i=0;i<ru->num_eNB;i++) {
eNB0 = ru->eNB_list[i];
eNB0->RU_list[eNB0->num_RU++] = ru;
}
}
}
*/
LOG_I(PHY,"Initializing RRU descriptor %d : (%s,%s,%d)\n",ru_id,ru_if_types[ru->if_south],eNB_timing[ru->if_timing],ru->function);
// set_function_spec_param(ru);
LOG_I(PHY,"Starting ru_thread %d\n",ru_id);
// init_RU_proc(ru);
proc = &ru->proc;
memset((void*)proc,0,sizeof(RU_proc_t));
proc->instance_pre_scd = -1;
pthread_mutex_init( &proc->mutex_pre_scd, NULL);
pthread_cond_init( &proc->cond_pre_scd, NULL);
pthread_create(&proc->pthread_pre_scd, NULL, pre_scd_thread, (void*)ru);
pthread_setname_np(proc->pthread_pre_scd, "pre_scd_thread");
} // for ru_id
// sleep(1);
LOG_D(HW,"[lte-softmodem.c] RU threads created\n");
}
#endif
/* --------------------------------------------------------*/
/* from here function to use configuration module */
+33 -42
View File
@@ -39,67 +39,58 @@ char *parallel_config=NULL;
char *worker_config=NULL;
uint64_t get_softmodem_optmask(void) {
return softmodem_params.optmask;
return softmodem_params.optmask;
}
uint64_t set_softmodem_optmask(uint64_t bitmask) {
softmodem_params.optmask = softmodem_params.optmask | bitmask;
return softmodem_params.optmask;
softmodem_params.optmask = softmodem_params.optmask | bitmask;
return softmodem_params.optmask;
}
softmodem_params_t* get_softmodem_params(void) {
return &softmodem_params;
softmodem_params_t *get_softmodem_params(void) {
return &softmodem_params;
}
void get_common_options(void)
{
uint32_t online_log_messages;
uint32_t glog_level ;
uint32_t start_telnetsrv;
uint32_t noS1;
uint32_t nokrnmod;
uint32_t nonbiot;
paramdef_t cmdline_params[] =CMDLINE_PARAMS_DESC ;
paramdef_t cmdline_logparams[] =CMDLINE_LOGPARAMS_DESC ;
config_process_cmdline( cmdline_params,sizeof(cmdline_params)/sizeof(paramdef_t),NULL);
if (strlen(in_path) > 0) {
opt_type = OPT_PCAP;
opt_enabled=1;
printf("Enabling OPT for PCAP with the following file %s \n",in_path);
}
if (strlen(in_ip) > 0) {
opt_enabled=1;
opt_type = OPT_WIRESHARK;
printf("Enabling OPT for wireshark for local interface");
}
config_process_cmdline( cmdline_logparams,sizeof(cmdline_logparams)/sizeof(paramdef_t),NULL);
void get_common_options(void) {
uint32_t online_log_messages;
uint32_t glog_level ;
uint32_t start_telnetsrv;
uint32_t noS1;
uint32_t nokrnmod;
uint32_t nonbiot;
paramdef_t cmdline_params[] =CMDLINE_PARAMS_DESC ;
paramdef_t cmdline_logparams[] =CMDLINE_LOGPARAMS_DESC ;
checkedparam_t cmdline_log_CheckParams[] = CMDLINE_LOGPARAMS_CHECK_DESC;
config_get( cmdline_params,sizeof(cmdline_params)/sizeof(paramdef_t),NULL);
config_set_checkfunctions(cmdline_logparams, cmdline_log_CheckParams,
sizeof(cmdline_logparams)/sizeof(paramdef_t));
config_get( cmdline_logparams,sizeof(cmdline_logparams)/sizeof(paramdef_t),NULL);
if(config_isparamset(cmdline_logparams,CMDLINE_ONLINELOG_IDX)) {
set_glog_onlinelog(online_log_messages);
set_glog_onlinelog(online_log_messages);
}
if(config_isparamset(cmdline_logparams,CMDLINE_GLOGLEVEL_IDX)) {
set_glog(glog_level);
set_glog(glog_level);
}
if (start_telnetsrv) {
load_module_shlib("telnetsrv",NULL,0,NULL);
load_module_shlib("telnetsrv",NULL,0,NULL);
}
if (noS1) {
set_softmodem_optmask(SOFTMODEM_NOS1_BIT);
set_softmodem_optmask(SOFTMODEM_NOS1_BIT);
}
if (nokrnmod) {
set_softmodem_optmask(SOFTMODEM_NOKRNMOD_BIT);
}
set_softmodem_optmask(SOFTMODEM_NOKRNMOD_BIT);
}
if (nonbiot) {
set_softmodem_optmask(SOFTMODEM_NONBIOT_BIT);
}
set_softmodem_optmask(SOFTMODEM_NONBIOT_BIT);
}
if(parallel_config != NULL) set_parallel_conf(parallel_config);
if(worker_config != NULL) set_worker_conf(worker_config);
}
+20 -103
View File
@@ -127,10 +127,7 @@ int config_sync_var=-1;
uint16_t runtime_phy_rx[29][6]; // SISO [MCS 0-28][RBs 0-5 : 6, 15, 25, 50, 75, 100]
uint16_t runtime_phy_tx[29][6]; // SISO [MCS 0-28][RBs 0-5 : 6, 15, 25, 50, 75, 100]
#if defined(ENABLE_ITTI)
volatile int start_eNB = 0;
volatile int start_UE = 0;
#endif
volatile int oai_exit = 0;
uint32_t downlink_frequency[MAX_NUM_CCs][4];
@@ -305,9 +302,6 @@ void exit_function(const char *file, const char *function, const int line, const
}
sleep(1); //allow lte-softmodem threads to exit first
#if defined(ENABLE_ITTI)
itti_terminate_tasks (TASK_UNKNOWN);
#endif
exit(1);
}
@@ -382,61 +376,6 @@ static void *scope_thread(void *arg) {
#endif
#if defined(ENABLE_ITTI)
void *l2l1_task(void *arg) {
MessageDef *message_p = NULL;
int result;
itti_set_task_real_time(TASK_L2L1);
itti_mark_task_ready(TASK_L2L1);
/* Wait for the initialize message */
printf("Wait for the ITTI initialize message\n");
while (1) {
itti_receive_msg (TASK_L2L1, &message_p);
switch (ITTI_MSG_ID(message_p)) {
case INITIALIZE_MESSAGE:
/* Start eNB thread */
LOG_D(PHY, "L2L1 TASK received %s\n", ITTI_MSG_NAME(message_p));
start_eNB = 1;
break;
case TERMINATE_MESSAGE:
LOG_W(PHY, " *** Exiting L2L1 thread\n");
oai_exit=1;
start_eNB = 0;
itti_exit_task ();
break;
case ACTIVATE_MESSAGE:
start_UE = 1;
break;
case DEACTIVATE_MESSAGE:
start_UE = 0;
break;
case MESSAGE_TEST:
printf("Received %s\n", ITTI_MSG_NAME(message_p));
break;
default:
printf("Received unexpected message %s\n", ITTI_MSG_NAME(message_p));
break;
}
result = itti_free (ITTI_MSG_ORIGIN_ID(message_p), message_p);
AssertFatal (result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result);
message_p = NULL;
};
return NULL;
}
#endif
static void get_options(void) {
CONFIG_SETRTFLAG(CONFIG_NOEXITONHELP);
get_common_options();
@@ -449,7 +388,7 @@ static void get_options(void) {
NB_eNB_INST = RC.nb_inst;
printf("Configuration: nb_rrc_inst %d, nb_L1_inst %d, nb_ru %d\n",NB_eNB_INST,RC.nb_L1_inst,RC.nb_RU);
if (!SOFTMODEM_NONBIOT) {
if (!IS_SOFTMODEM_NONBIOT) {
load_NB_IoT();
printf(" nb_nbiot_rrc_inst %d, nb_nbiot_L1_inst %d, nb_nbiot_macrlc_inst %d\n",
RC.nb_nb_iot_rrc_inst, RC.nb_nb_iot_L1_inst, RC.nb_nb_iot_macrlc_inst);
@@ -505,7 +444,8 @@ void set_default_frame_parms(LTE_DL_FRAME_PARMS *frame_parms[MAX_NUM_CCs]) {
}
void wait_RUs(void) {
LOG_I(PHY,"Waiting for RUs to be configured ... RC.ru_mask:%02lx\n", RC.ru_mask);
/* do not modify the following LOG_UI message, which is used by CI */
LOG_UI(ENB_APP,"Waiting for RUs to be configured ... RC.ru_mask:%02lx\n", RC.ru_mask);
// wait for all RUs to be configured over fronthaul
pthread_mutex_lock(&RC.ru_mutex);
@@ -567,7 +507,6 @@ int stop_L1L2(module_id_t enb_id) {
/* these tasks need to pick up new configuration */
terminate_task(enb_id, TASK_ENB_APP, TASK_RRC_ENB);
terminate_task(enb_id, TASK_ENB_APP, TASK_L2L1);
oai_exit = 1;
LOG_I(ENB_APP, "calling kill_RU_proc() for instance %d\n", enb_id);
kill_RU_proc(RC.ru[enb_id]);
@@ -619,13 +558,6 @@ int restart_L1L2(module_id_t enb_id) {
LOG_I(RRC, "Re-created task for RRC eNB successfully\n");
}
if (itti_create_task (TASK_L2L1, l2l1_task, NULL) < 0) {
LOG_E(PDCP, "Create task for L2L1 failed\n");
return -1;
} else {
LOG_I(PDCP, "Re-created task for L2L1 successfully\n");
}
/* pass a reconfiguration request which will configure everything down to
* RC.eNB[i][j]->frame_parms, too */
msg_p = itti_alloc_new_message(TASK_ENB_APP, RRC_CONFIGURATION_REQ);
@@ -678,7 +610,6 @@ int main( int argc, char **argv ) {
set_latency_target();
logInit();
printf("Reading in command-line options\n");
CONFIG_SETRTFLAG(CONFIG_NOCHECKUNKOPT);
get_options ();
if (CONFIG_ISFLAGSET(CONFIG_ABORT) ) {
@@ -689,14 +620,6 @@ int main( int argc, char **argv ) {
#if T_TRACER
T_Config_Init();
#endif
ret=config_check_unknown_cmdlineopt(NULL);
if (ret != 0) {
LOG_E(ENB_APP, "%i unknown options in command line\n",ret);
exit_fun("");
}
CONFIG_CLEARRTFLAG(CONFIG_NOCHECKUNKOPT);
//randominit (0);
set_taus_seed (0);
printf("configuring for RAU/RRU\n");
@@ -717,12 +640,7 @@ int main( int argc, char **argv ) {
MSC_INIT(MSC_E_UTRAN, THREAD_MAX+TASK_MAX);
#endif
if (opt_type != OPT_NONE) {
if (init_opt(in_path, in_ip) == -1)
LOG_E(OPT,"failed to run OPT \n");
}
init_opt();
#ifdef PDCP_USE_NETLINK
printf("PDCP netlink\n");
netlink_init();
@@ -879,8 +797,14 @@ int main( int argc, char **argv ) {
printf("NFAPI MODE:%s\n", nfapi_mode_str);
if (nfapi_mode==2) // VNF
if (nfapi_mode==2) {// VNF
#if defined(PRE_SCD_THREAD)
init_ru_vnf(); // ru pointer is necessary for pre_scd.
#endif
wait_nfapi_init("main?");
}
printf("START MAIN THREADS\n");
// start the main threads
@@ -896,13 +820,16 @@ int main( int argc, char **argv ) {
printf("wait_eNBs()\n");
wait_eNBs();
printf("About to Init RU threads RC.nb_RU:%d\n", RC.nb_RU);
if (RC.nb_RU >0) {
// RU thread and some L1 procedure aren't necessary in VNF or L2 FAPI simulator.
// but RU thread deals with pre_scd and this is necessary in VNF and simulator.
// some initialization is necessary and init_ru_vnf do this.
if (RC.nb_RU >0 && nfapi_mode != 2) {
printf("Initializing RU threads\n");
init_RU(get_softmodem_params()->rf_config_file);
for (ru_id=0; ru_id<RC.nb_RU; ru_id++) {
for (ru_id=0;ru_id<RC.nb_RU;ru_id++) {
RC.ru[ru_id]->rf_map.card=0;
RC.ru[ru_id]->rf_map.chain=CC_id+(get_softmodem_params()->chain_offset);
}
@@ -938,13 +865,7 @@ int main( int argc, char **argv ) {
sync_var=0;
pthread_cond_broadcast(&sync_cond);
pthread_mutex_unlock(&sync_mutex);
ret=config_check_unknown_cmdlineopt(CONFIG_CHECKALLSECTIONS);
if (ret != 0) {
LOG_E(ENB_APP, "%i unknown options in command line (invalid section name)\n",ret);
exit_fun("");
}
config_check_unknown_cmdlineopt(CONFIG_CHECKALLSECTIONS);
// wait for end of program
printf("TYPE <CTRL-C> TO TERMINATE\n");
//getchar();
@@ -999,9 +920,7 @@ int main( int argc, char **argv ) {
}
free_lte_top();
printf("About to call end_configmodule() from %s() %s:%d\n", __FUNCTION__, __FILE__, __LINE__);
end_configmodule();
printf("Called end_configmodule() from %s() %s:%d\n", __FUNCTION__, __FILE__, __LINE__);
pthread_cond_destroy(&sync_cond);
pthread_mutex_destroy(&sync_mutex);
pthread_cond_destroy(&nfapi_sync_cond);
@@ -1020,9 +939,7 @@ int main( int argc, char **argv ) {
}
}
if (opt_enabled == 1)
terminate_opt();
terminate_opt();
logClean();
printf("Bye.\n");
return 0;
+114 -117
View File
@@ -35,12 +35,12 @@
#include "flexran_agent.h"
#if defined(ENABLE_ITTI)
#if defined(ENABLE_USE_MME)
#include "s1ap_eNB.h"
#ifdef PDCP_USE_NETLINK
#include "SIMULATION/ETH_TRANSPORT/proto.h"
#endif
#endif
#if defined(ENABLE_USE_MME)
#include "s1ap_eNB.h"
#ifdef PDCP_USE_NETLINK
#include "SIMULATION/ETH_TRANSPORT/proto.h"
#endif
#endif
#endif
/* help strings definition for command line options, used in CMDLINE_XXX_DESC macros and printed when -h option is used */
@@ -60,14 +60,14 @@
#define CONFIG_HLP_UENANTR "set UE number of rx antennas\n"
#define CONFIG_HLP_UENANTT "set UE number of tx antennas\n"
#define CONFIG_HLP_UESCAN "set UE to scan around carrier\n"
#define CONFIG_HLP_DUMPFRAME "dump UE received frame to rxsig_frame0.dat and exit\n"
#define CONFIG_HLP_DUMPFRAME "dump UE received frame to rxsig_frame0.dat and exit\n"
#define CONFIG_HLP_DLSHIFT "dynamic shift for LLR compuation for TM3/4 (default 0)\n"
#define CONFIG_HLP_UELOOP "get softmodem (UE) to loop through memory instead of acquiring from HW\n"
#define CONFIG_HLP_PHYTST "test UE phy layer, mac disabled\n"
#define CONFIG_HLP_DMAMAP "sets flag for improved EXMIMO UE performance\n"
#define CONFIG_HLP_DMAMAP "sets flag for improved EXMIMO UE performance\n"
#define CONFIG_HLP_CLK "tells hardware to use a clock reference (0:internal, 1:external, 2:gpsdo)\n"
#define CONFIG_HLP_USIM "use XOR autentication algo in case of test usim mode\n"
#define CONFIG_HLP_NOSNGLT "Disables single-thread mode in lte-softmodem\n"
#define CONFIG_HLP_USIM "use XOR autentication algo in case of test usim mode\n"
#define CONFIG_HLP_NOSNGLT "Disables single-thread mode in lte-softmodem\n"
#define CONFIG_HLP_TADV "Set timing_advance\n"
#define CONFIG_HLP_DLF "Set the downlink frequency for all component carriers\n"
#define CONFIG_HLP_CHOFF "Channel id offset\n"
@@ -76,16 +76,14 @@
#define CONFIG_HLP_ITTIL "Generate ITTI analyzser logs (similar to wireshark logs but with more details)\n"
#define CONFIG_HLP_DLMCS "Set the maximum downlink MCS\n"
#define CONFIG_HLP_STMON "Enable processing timing measurement of lte softmodem on per subframe basis \n"
#define CONFIG_HLP_PRB "Set the PRB, valid values: 6, 25, 50, 100 \n"
#define CONFIG_HLP_PRB "Set the PRB, valid values: 6, 25, 50, 100 \n"
#define CONFIG_HLP_EMULIFACE "Set the interface name for the multicast transport for emulation mode (e.g. eth0, lo, etc.) \n"
//#define CONFIG_HLP_NUMUES "Set the number of UEs for the emulation"
#define CONFIG_HLP_MSLOTS "Skip the missed slots/subframes \n"
//#define CONFIG_HLP_NUMUES "Set the number of UEs for the emulation"
#define CONFIG_HLP_MSLOTS "Skip the missed slots/subframes \n"
#define CONFIG_HLP_ULMCS "Set the maximum uplink MCS\n"
#define CONFIG_HLP_TDD "Set hardware to TDD mode (default: FDD). Used only with -U (otherwise set in config file).\n"
#define CONFIG_HLP_SNR "Set average SNR in dB (for --siml1 option)\n"
#define CONFIG_HLP_UE "Set the lte softmodem as a UE\n"
#define CONFIG_HLP_L2MONW "Enable L2 wireshark messages on localhost \n"
#define CONFIG_HLP_L2MONP "Enable L2 pcap messages on localhost \n"
#define CONFIG_HLP_TQFS "Apply three-quarter of sampling frequency, 23.04 Msps to reduce the data rate on USB/PCIe transfers (only valid for 20 MHz)\n"
#define CONFIG_HLP_TPORT "tracer port\n"
#define CONFIG_HLP_NOTWAIT "don't wait for tracer, start immediately\n"
@@ -103,7 +101,7 @@
#define CONFIG_HLP_USRP_CLK_SRC "USRP clock source: 'internal' or 'external'\n"
/***************************************************************************************************************************************/
/* command line options definitions, CMDLINE_XXXX_DESC macros are used to initialize paramdef_t arrays which are then used as argument
/* command line options definitions, CMDLINE_XXXX_DESC macros are used to initialize paramdef_t arrays which are then used as argument
when calling config_get or config_getlist functions */
@@ -112,15 +110,15 @@
/* optname helpstr paramflags XXXptr defXXXval type numelt */
/*------------------------------------------------------------------------------------------------------------------------------------------*/
#define CMDLINE_UEMODEPARAMS_DESC { \
{"calib-ue-rx", CONFIG_HLP_CALUER, 0, iptr:&rx_input_level_dBm, defintval:0, TYPE_INT, 0}, \
{"calib-ue-rx-med", CONFIG_HLP_CALUERM, 0, iptr:&rx_input_level_dBm, defintval:0, TYPE_INT, 0}, \
{"calib-ue-rx-byp", CONFIG_HLP_CALUERB, 0, iptr:&rx_input_level_dBm, defintval:0, TYPE_INT, 0}, \
{"debug-ue-prach", CONFIG_HLP_DBGUEPR, PARAMFLAG_BOOL, uptr:NULL, defuintval:1, TYPE_INT, 0}, \
{"no-L2-connect", CONFIG_HLP_NOL2CN, PARAMFLAG_BOOL, uptr:NULL, defuintval:1, TYPE_INT, 0}, \
{"calib-prach-tx", CONFIG_HLP_CALPRACH, PARAMFLAG_BOOL, uptr:NULL, defuintval:1, TYPE_INT, 0}, \
{"loop-memory", CONFIG_HLP_UELOOP, 0, strptr:&loopfile, defstrval:"iqs.in", TYPE_STRING,0}, \
{"ue-dump-frame", CONFIG_HLP_DUMPFRAME, PARAMFLAG_BOOL, iptr:&dumpframe, defintval:0, TYPE_INT, 0}, \
}
{"calib-ue-rx", CONFIG_HLP_CALUER, 0, iptr:&rx_input_level_dBm, defintval:0, TYPE_INT, 0}, \
{"calib-ue-rx-med", CONFIG_HLP_CALUERM, 0, iptr:&rx_input_level_dBm, defintval:0, TYPE_INT, 0}, \
{"calib-ue-rx-byp", CONFIG_HLP_CALUERB, 0, iptr:&rx_input_level_dBm, defintval:0, TYPE_INT, 0}, \
{"debug-ue-prach", CONFIG_HLP_DBGUEPR, PARAMFLAG_BOOL, uptr:NULL, defuintval:1, TYPE_INT, 0}, \
{"no-L2-connect", CONFIG_HLP_NOL2CN, PARAMFLAG_BOOL, uptr:NULL, defuintval:1, TYPE_INT, 0}, \
{"calib-prach-tx", CONFIG_HLP_CALPRACH, PARAMFLAG_BOOL, uptr:NULL, defuintval:1, TYPE_INT, 0}, \
{"loop-memory", CONFIG_HLP_UELOOP, 0, strptr:&loopfile, defstrval:"iqs.in", TYPE_STRING,0}, \
{"ue-dump-frame", CONFIG_HLP_DUMPFRAME, PARAMFLAG_BOOL, iptr:&dumpframe, defintval:0, TYPE_INT, 0}, \
}
#define CMDLINE_CALIBUERX_IDX 0
#define CMDLINE_CALIBUERXMED_IDX 1
#define CMDLINE_CALIBUERXBYP_IDX 2
@@ -138,41 +136,42 @@
/*-------------------------------------------------------------------------------------------------------------------------------------------------------*/
#define CMDLINE_UEPARAMS_DESC { \
{"siml1", CONFIG_HLP_SIML1, PARAMFLAG_BOOL, iptr:&simL1flag, defintval:0, TYPE_INT, 0}, \
{"U", CONFIG_HLP_NUMUE, 0, u8ptr:&NB_UE_INST, defuintval:1, TYPE_UINT, 0}, \
{"ue-rxgain", CONFIG_HLP_UERXG, 0, dblptr:&(rx_gain[0][0]), defdblval:130, 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:&nb_antenna_rx, defuintval:1, TYPE_UINT8, 0}, \
{"ue-nb-ant-tx", CONFIG_HLP_UENANTT, 0, u8ptr:&nb_antenna_tx, defuintval:1, TYPE_UINT8, 0}, \
{"ue-scan-carrier", CONFIG_HLP_UESCAN, PARAMFLAG_BOOL, iptr:&UE_scan_carrier, defintval:0, TYPE_INT, 0}, \
{"ue-max-power", NULL, 0, iptr:&(tx_max_power[0]), defintval:23, TYPE_INT, 0}, \
{"emul-iface", CONFIG_HLP_EMULIFACE, 0, strptr:&emul_iface, defstrval:"lo", TYPE_STRING, 100}, \
{"L2-emul", NULL, 0, u8ptr:&nfapi_mode, defuintval:3, TYPE_UINT8, 0}, \
{"num-ues", NULL, 0, u8ptr:&(NB_UE_INST), defuintval:1, TYPE_UINT8, 0}, \
{"r" , CONFIG_HLP_PRB, 0, u8ptr:&(frame_parms[0]->N_RB_DL), defintval:25, TYPE_UINT8, 0}, \
{"dlsch-demod-shift", CONFIG_HLP_DLSHIFT, 0, iptr:(int32_t *)&dlsch_demod_shift, defintval:0, TYPE_INT, 0}, \
{"usrp-args", CONFIG_HLP_USRP_ARGS, 0, strptr:(char **)&usrp_args, defstrval:"type=b200",TYPE_STRING, 0}, \
{"usrp-clksrc", CONFIG_HLP_USRP_CLK_SRC,0, strptr:(char **)&usrp_clksrc, defstrval:"internal", TYPE_STRING, 0}, \
{"mmapped-dma", CONFIG_HLP_DMAMAP, PARAMFLAG_BOOL, uptr:&mmapped_dma, defintval:0, TYPE_INT, 0}, \
{"clock", CONFIG_HLP_CLK, 0, uptr:&clock_source, defintval:0, TYPE_UINT, 0}, \
{"s" , CONFIG_HLP_SNR, 0, iptr:&snr_dB, defintval:25, TYPE_INT, 0}, \
{"T" , CONFIG_HLP_TDD, PARAMFLAG_BOOL, iptr:&tddflag, defintval:0, TYPE_INT, 0}, \
{"A", CONFIG_HLP_TADV, 0, iptr:&(timingadv), defintval:0, TYPE_INT, 0} \
}
{"siml1", CONFIG_HLP_SIML1, PARAMFLAG_BOOL, iptr:&simL1flag, defintval:0, TYPE_INT, 0}, \
{"U", CONFIG_HLP_NUMUE, 0, u16ptr:&NB_UE_INST, defuintval:1, TYPE_UINT16, 0}, \
{"ue-rxgain", CONFIG_HLP_UERXG, 0, dblptr:&(rx_gain[0][0]), defdblval:130, 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:&nb_antenna_rx, defuintval:1, TYPE_UINT8, 0}, \
{"ue-nb-ant-tx", CONFIG_HLP_UENANTT, 0, u8ptr:&nb_antenna_tx, defuintval:1, TYPE_UINT8, 0}, \
{"ue-scan-carrier", CONFIG_HLP_UESCAN, PARAMFLAG_BOOL, iptr:&UE_scan_carrier, defintval:0, TYPE_INT, 0}, \
{"ue-max-power", NULL, 0, iptr:&(tx_max_power[0]), defintval:23, TYPE_INT, 0}, \
{"emul-iface", CONFIG_HLP_EMULIFACE, 0, strptr:&emul_iface, defstrval:"lo", TYPE_STRING, 100}, \
{"L2-emul", NULL, 0, u8ptr:&nfapi_mode, defuintval:3, TYPE_UINT8, 0}, \
{"num-ues", NULL, 0, u16ptr:&(NB_UE_INST), defuintval:1, TYPE_UINT16, 0}, \
{"nums_ue_thread", NULL, 0, u16ptr:&(NB_THREAD_INST), defuintval:1, TYPE_UINT16, 0}, \
{"r" , CONFIG_HLP_PRB, 0, u8ptr:&(frame_parms[0]->N_RB_DL), defintval:25, TYPE_UINT8, 0}, \
{"dlsch-demod-shift", CONFIG_HLP_DLSHIFT, 0, iptr:(int32_t *)&dlsch_demod_shift, defintval:0, TYPE_INT, 0}, \
{"usrp-args", CONFIG_HLP_USRP_ARGS, 0, strptr:(char **)&usrp_args, defstrval:"type=b200",TYPE_STRING, 0}, \
{"usrp-clksrc", CONFIG_HLP_USRP_CLK_SRC,0, strptr:(char **)&usrp_clksrc, defstrval:"internal", TYPE_STRING, 0}, \
{"mmapped-dma", CONFIG_HLP_DMAMAP, PARAMFLAG_BOOL, uptr:&mmapped_dma, defintval:0, TYPE_INT, 0}, \
{"clock", CONFIG_HLP_CLK, 0, uptr:&clock_source, defintval:0, TYPE_UINT, 0}, \
{"s" , CONFIG_HLP_SNR, 0, iptr:&snr_dB, defintval:25, TYPE_INT, 0}, \
{"T" , CONFIG_HLP_TDD, PARAMFLAG_BOOL, iptr:&tddflag, defintval:0, TYPE_INT, 0}, \
{"A", CONFIG_HLP_TADV, 0, iptr:&(timingadv), defintval:0, TYPE_INT, 0} \
}
/*-------------------------------------------------------------------------------------------------------------------------------------------------------*/
/* command line parameters specific to UE threads */
/* optname helpstr paramflags XXXptr defXXXval type numelt */
/*-------------------------------------------------------------------------------------------------------------------------------------------------------*/
#define CMDLINE_UETHREADSPARAMS_DESC { \
{"threadIQ", NULL, 0, iptr:&(threads.iq), defintval:1, TYPE_INT, 0}, \
{"threadOneSubframe", NULL, 0, iptr:&(threads.one), defintval:1, TYPE_INT, 0}, \
{"threadTwoSubframe", NULL, 0, iptr:&(threads.two), defintval:1, TYPE_INT, 0}, \
{"threadThreeSubframe", NULL, 0, iptr:&(threads.three), defintval:1, TYPE_INT, 0}, \
{"threadSlot1ProcOne", NULL, 0, iptr:&(threads.slot1_proc_one), defintval:1, TYPE_INT, 0}, \
{"threadSlot1ProcTwo", NULL, 0, iptr:&(threads.slot1_proc_two), defintval:1, TYPE_INT, 0}, \
}
{"threadIQ", NULL, 0, iptr:&(threads.iq), defintval:1, TYPE_INT, 0}, \
{"threadOneSubframe", NULL, 0, iptr:&(threads.one), defintval:1, TYPE_INT, 0}, \
{"threadTwoSubframe", NULL, 0, iptr:&(threads.two), defintval:1, TYPE_INT, 0}, \
{"threadThreeSubframe", NULL, 0, iptr:&(threads.three), defintval:1, TYPE_INT, 0}, \
{"threadSlot1ProcOne", NULL, 0, iptr:&(threads.slot1_proc_one), defintval:1, TYPE_INT, 0}, \
{"threadSlot1ProcTwo", NULL, 0, iptr:&(threads.slot1_proc_two), defintval:1, TYPE_INT, 0}, \
}
#define DEFAULT_DLF 2680000000
@@ -191,28 +190,26 @@
#define CLOCK_SOURCE softmodem_params.clock_source
#define USIM_TEST softmodem_params.usim_test
#define CMDLINE_PARAMS_DESC { \
{"rf-config-file", CONFIG_HLP_RFCFGF, 0, strptr:(char **)&RF_CONFIG_FILE, defstrval:NULL, TYPE_STRING, sizeof(RF_CONFIG_FILE)}, \
{"ulsch-max-errors", CONFIG_HLP_ULMAXE, 0, uptr:&ULSCH_max_consecutive_errors, defuintval:0, TYPE_UINT, 0}, \
{"phy-test", CONFIG_HLP_PHYTST, PARAMFLAG_BOOL, iptr:&PHY_TEST, defintval:0, TYPE_INT, 0}, \
{"usim-test", CONFIG_HLP_USIM, PARAMFLAG_BOOL, u8ptr:&USIM_TEST, defintval:0, TYPE_UINT8, 0}, \
{"emulate-rf" , CONFIG_HLP_EMULATE_RF, PARAMFLAG_BOOL, iptr:&EMULATE_RF, defintval:0, TYPE_INT, 0}, \
{"clock", CONFIG_HLP_CLK, 0, uptr:&CLOCK_SOURCE, defintval:0, TYPE_UINT, 0}, \
{"wait-for-sync", NULL, PARAMFLAG_BOOL, iptr:&WAIT_FOR_SYNC, defintval:0, TYPE_INT, 0}, \
{"single-thread-enable", CONFIG_HLP_NOSNGLT, PARAMFLAG_BOOL, iptr:&SINGLE_THREAD_FLAG, defintval:0, TYPE_INT, 0}, \
{"C" , CONFIG_HLP_DLF, 0, uptr:&(downlink_frequency[0][0]), defuintval:2680000000, TYPE_UINT, 0}, \
{"a" , CONFIG_HLP_CHOFF, 0, iptr:&CHAIN_OFFSET, defintval:0, TYPE_INT, 0}, \
{"d" , CONFIG_HLP_SOFTS, PARAMFLAG_BOOL, uptr:(uint32_t *)&DO_FORMS, defintval:0, TYPE_INT8, 0}, \
{"W" , CONFIG_HLP_L2MONW, 0, strptr:(char **)&in_ip, defstrval:"127.0.0.1", TYPE_STRING, sizeof(in_ip)}, \
{"P" , CONFIG_HLP_L2MONP, 0, strptr:(char **)&in_path, defstrval:"/tmp/oai_opt.pcap", TYPE_STRING, sizeof(in_path)}, \
{"q" , CONFIG_HLP_STMON, PARAMFLAG_BOOL, iptr:&opp_enabled, defintval:0, TYPE_INT, 0}, \
{"S" , CONFIG_HLP_MSLOTS, PARAMFLAG_BOOL, u8ptr:&exit_missed_slots, defintval:1, TYPE_UINT8, 0}, \
{"numerology" , CONFIG_HLP_NUMEROLOGY, PARAMFLAG_BOOL, iptr:&NUMEROLOGY, defintval:0, TYPE_INT, 0}, \
{"parallel-config", CONFIG_HLP_PARALLEL_CMD,0, strptr:(char **)&parallel_config, defstrval:NULL, TYPE_STRING, 0}, \
{"worker-config", CONFIG_HLP_WORKER_CMD, 0, strptr:(char **)&worker_config, defstrval:NULL, TYPE_STRING, 0}, \
{"noS1", CONFIG_HLP_NOS1, PARAMFLAG_BOOL, uptr:&noS1, defintval:0, TYPE_INT, 0}, \
{"nokrnmod", CONFIG_HLP_NOKRNMOD, PARAMFLAG_BOOL, uptr:&nokrnmod, defintval:0, TYPE_INT, 0}, \
{"nbiot-disable", CONFIG_HLP_DISABLNBIOT, PARAMFLAG_BOOL, uptr:&nonbiot, defuintval:0, TYPE_INT, 0}, \
}
{"rf-config-file", CONFIG_HLP_RFCFGF, 0, strptr:(char **)&RF_CONFIG_FILE, defstrval:NULL, TYPE_STRING, sizeof(RF_CONFIG_FILE)}, \
{"ulsch-max-errors", CONFIG_HLP_ULMAXE, 0, uptr:&ULSCH_max_consecutive_errors, defuintval:0, TYPE_UINT, 0}, \
{"phy-test", CONFIG_HLP_PHYTST, PARAMFLAG_BOOL, iptr:&PHY_TEST, defintval:0, TYPE_INT, 0}, \
{"usim-test", CONFIG_HLP_USIM, PARAMFLAG_BOOL, u8ptr:&USIM_TEST, defintval:0, TYPE_UINT8, 0}, \
{"emulate-rf" , CONFIG_HLP_EMULATE_RF, PARAMFLAG_BOOL, iptr:&EMULATE_RF, defintval:0, TYPE_INT, 0}, \
{"clock", CONFIG_HLP_CLK, 0, uptr:&CLOCK_SOURCE, defintval:0, TYPE_UINT, 0}, \
{"wait-for-sync", NULL, PARAMFLAG_BOOL, iptr:&WAIT_FOR_SYNC, defintval:0, TYPE_INT, 0}, \
{"single-thread-enable", CONFIG_HLP_NOSNGLT, PARAMFLAG_BOOL, iptr:&SINGLE_THREAD_FLAG, defintval:0, TYPE_INT, 0}, \
{"C" , CONFIG_HLP_DLF, 0, uptr:&(downlink_frequency[0][0]), defuintval:2680000000, TYPE_UINT, 0}, \
{"a" , CONFIG_HLP_CHOFF, 0, iptr:&CHAIN_OFFSET, defintval:0, TYPE_INT, 0}, \
{"d" , CONFIG_HLP_SOFTS, PARAMFLAG_BOOL, uptr:(uint32_t *)&DO_FORMS, defintval:0, TYPE_INT8, 0}, \
{"q" , CONFIG_HLP_STMON, PARAMFLAG_BOOL, iptr:&opp_enabled, defintval:0, TYPE_INT, 0}, \
{"S" , CONFIG_HLP_MSLOTS, PARAMFLAG_BOOL, u8ptr:&exit_missed_slots, defintval:1, TYPE_UINT8, 0}, \
{"numerology" , CONFIG_HLP_NUMEROLOGY, PARAMFLAG_BOOL, iptr:&NUMEROLOGY, defintval:0, TYPE_INT, 0}, \
{"parallel-config", CONFIG_HLP_PARALLEL_CMD,0, strptr:(char **)&parallel_config, defstrval:NULL, TYPE_STRING, 0}, \
{"worker-config", CONFIG_HLP_WORKER_CMD, 0, strptr:(char **)&worker_config, defstrval:NULL, TYPE_STRING, 0}, \
{"noS1", CONFIG_HLP_NOS1, PARAMFLAG_BOOL, uptr:&noS1, defintval:0, TYPE_INT, 0}, \
{"nokrnmod", CONFIG_HLP_NOKRNMOD, PARAMFLAG_BOOL, uptr:&nokrnmod, defintval:0, TYPE_INT, 0}, \
{"nbiot-disable", CONFIG_HLP_DISABLNBIOT, PARAMFLAG_BOOL, uptr:&nonbiot, defuintval:0, TYPE_INT, 0}, \
}
#define CONFIG_HLP_FLOG "Enable online log \n"
#define CONFIG_HLP_LOGL "Set the global log level, valide options: (4:trace, 3:debug, 2:info, 1:warn, (0:error))\n"
@@ -224,17 +221,24 @@
/*---------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
#define START_MSC softmodem_params.start_msc
#define CMDLINE_LOGPARAMS_DESC { \
{"R" , CONFIG_HLP_FLOG, 0, uptr:&online_log_messages, defintval:1, TYPE_INT, 0}, \
{"g" , CONFIG_HLP_LOGL, 0, uptr:&glog_level, defintval:0, TYPE_UINT, 0}, \
{"telnetsrv", CONFIG_HLP_TELN, PARAMFLAG_BOOL, uptr:&start_telnetsrv, defintval:0, TYPE_UINT, 0}, \
{"msc", CONFIG_HLP_MSC, PARAMFLAG_BOOL, uptr:&START_MSC, defintval:0, TYPE_UINT, 0}, \
}
#define CMDLINE_ONLINELOG_IDX 0
{"R" , CONFIG_HLP_FLOG, 0, uptr:&online_log_messages, defintval:1, TYPE_INT, 0}, \
{"g" , CONFIG_HLP_LOGL, 0, uptr:&glog_level, defintval:0, TYPE_UINT, 0}, \
{"telnetsrv", CONFIG_HLP_TELN, PARAMFLAG_BOOL, uptr:&start_telnetsrv, defintval:0, TYPE_UINT, 0}, \
{"msc", CONFIG_HLP_MSC, PARAMFLAG_BOOL, uptr:&START_MSC, defintval:0, TYPE_UINT, 0}, \
}
#define CMDLINE_ONLINELOG_IDX 0
#define CMDLINE_GLOGLEVEL_IDX 1
#define CMDLINE_STARTTELN_IDX 2
/* check function for global log level */
#define CMDLINE_LOGPARAMS_CHECK_DESC { \
{ .s5= {NULL }} , \
{ .s2= { config_check_intrange, {0,4}}}, \
{ .s5= {NULL }} , \
{ .s5= {NULL }} , \
}
/***************************************************************************************************************************************/
/***************************************************************************************************************************************/
/* */
#include "threads_t.h"
@@ -242,30 +246,29 @@
#define SOFTMODEM_NOKRNMOD_BIT (1<<1)
#define SOFTMODEM_NONBIOT_BIT (1<<2)
typedef struct {
uint64_t optmask;
THREAD_STRUCT thread_struct;
char rf_config_file[1024];
int phy_test;
uint8_t usim_test;
int emulate_rf;
int wait_for_sync; //eNodeB only
int single_thread_flag; //eNodeB only
int chain_offset;
uint32_t do_forms;
int numerology;
unsigned int start_msc;
int nonbiotflag;
uint32_t clock_source;
int hw_timing_advance;
uint64_t optmask;
THREAD_STRUCT thread_struct;
char rf_config_file[1024];
int phy_test;
uint8_t usim_test;
int emulate_rf;
int wait_for_sync; //eNodeB only
int single_thread_flag; //eNodeB only
int chain_offset;
uint32_t do_forms;
int numerology;
unsigned int start_msc;
uint32_t clock_source;
int hw_timing_advance;
} softmodem_params_t;
#define SOFTMODEM_NOS1 ( get_softmodem_optmask() & SOFTMODEM_NOS1_BIT)
#define SOFTMODEM_NOKRNMOD ( get_softmodem_optmask() & SOFTMODEM_NOKRNMOD_BIT)
#define SOFTMODEM_NONBIOT ( get_softmodem_optmask() & SOFTMODEM_NONBIOT_BIT)
#define IS_SOFTMODEM_NOS1 ( get_softmodem_optmask() & SOFTMODEM_NOS1_BIT)
#define IS_SOFTMODEM_NOKRNMOD ( get_softmodem_optmask() & SOFTMODEM_NOKRNMOD_BIT)
#define IS_SOFTMODEM_NONBIOT ( get_softmodem_optmask() & SOFTMODEM_NONBIOT_BIT)
extern uint64_t get_softmodem_optmask(void);
extern uint64_t set_softmodem_optmask(uint64_t bitmask);
extern void get_common_options(void);
extern softmodem_params_t* get_softmodem_params(void);
extern softmodem_params_t *get_softmodem_params(void);
uint64_t get_pdcp_optmask(void);
extern pthread_cond_t sync_cond;
@@ -290,22 +293,15 @@ extern int sync_var;
extern int transmission_mode;
extern double cpuf;
#if defined(ENABLE_ITTI)
extern volatile int start_eNB;
extern volatile int start_UE;
#endif
// In lte-enb.c
extern void init_eNB(int single_thread_flag,int wait_for_sync);
extern void stop_eNB(int);
extern void kill_eNB_proc(int inst);
// In lte-ru.c
extern void init_RU(char*);
extern void init_RU(char *);
extern void stop_ru(RU_t *ru);
extern void init_ru_vnf(void);
extern void init_RU_proc(RU_t *ru);
extern void stop_RU(int nb_ru);
extern void kill_RU_proc(RU_t *ru);
@@ -315,8 +311,9 @@ extern void set_function_spec_param(RU_t *ru);
extern int setup_ue_buffers(PHY_VARS_UE **phy_vars_ue, openair0_config_t *openair0_cfg);
extern void fill_ue_band_info(void);
extern void init_UE(int nb_inst,int eMBMS_active, int uecap_xer_in, int timing_correction, int phy_test, int UE_scan, int UE_scan_carrier, runmode_t mode,int rxgain,int txpowermax, LTE_DL_FRAME_PARMS *fp);
extern void init_thread(int sched_runtime, int sched_deadline, int sched_fifo, cpu_set_t *cpuset, char * name);
extern void init_UE(int nb_inst,int eMBMS_active, int uecap_xer_in, int timing_correction, int phy_test, int UE_scan, int UE_scan_carrier, runmode_t mode,int rxgain,int txpowermax,
LTE_DL_FRAME_PARMS *fp);
extern void init_thread(int sched_runtime, int sched_deadline, int sched_fifo, cpu_set_t *cpuset, char *name);
extern void reset_opp_meas(void);
extern void print_opp_meas(void);
@@ -331,7 +328,7 @@ extern void RCConfig_sim(void);
extern void init_ocm(double,double);
extern void init_ue_devices(PHY_VARS_UE *);
PHY_VARS_UE* init_ue_vars(LTE_DL_FRAME_PARMS *frame_parms,
PHY_VARS_UE *init_ue_vars(LTE_DL_FRAME_PARMS *frame_parms,
uint8_t UE_id,
uint8_t abstraction_flag);
void init_eNB_afterRU(void);
@@ -346,8 +343,8 @@ extern int restart_L1L2(module_id_t enb_id);
extern void init_UE_stub_single_thread(int nb_inst,int eMBMS_active, int uecap_xer_in, char *emul_iface);
extern PHY_VARS_UE* init_ue_vars(LTE_DL_FRAME_PARMS *frame_parms,
uint8_t UE_id,
uint8_t abstraction_flag);
extern PHY_VARS_UE *init_ue_vars(LTE_DL_FRAME_PARMS *frame_parms,
uint8_t UE_id,
uint8_t abstraction_flag);
#endif
+163 -55
View File
@@ -94,7 +94,7 @@ extern int oai_nfapi_rx_ind(nfapi_rx_indication_t *ind);
extern int multicast_link_write_sock(int groupP, char *dataP, uint32_t sizeP);
extern int simL1flag;
extern uint16_t sf_ahead;
//extern int tx_req_UE_MAC1();
void ue_stub_rx_handler(unsigned int, char *);
@@ -102,9 +102,11 @@ void ue_stub_rx_handler(unsigned int, char *);
int32_t **rxdata;
int32_t **txdata;
int timer_subframe;
int timer_frame;
SF_ticking *phy_stub_ticking;
int timer_subframe = 0;
int timer_frame = 0;
SF_ticking *phy_stub_ticking = NULL;
int next_ra_frame = 0;
module_id_t next_Mod_id = 0;
#define KHz (1000UL)
#define MHz (1000*KHz)
@@ -386,7 +388,7 @@ void init_UE_stub_single_thread(int nb_inst,int eMBMS_active, int uecap_xer_in,
for (inst=0;inst<nb_inst;inst++) {
LOG_I(PHY,"Initializing memory for UE instance %d (%p)\n",inst,PHY_vars_UE_g[inst]);
PHY_vars_UE_g[inst][0] = init_ue_vars(NULL,inst,0);
// PHY_vars_UE_g[inst][0] = init_ue_vars(NULL,inst,0);
}
init_timer_thread();
init_UE_single_thread_stub(nb_inst);
@@ -963,31 +965,57 @@ static void *UE_phy_stub_single_thread_rxn_txnp4(void *arg) {
thread_top_init("UE_phy_stub_thread_rxn_txnp4",1,870000L,1000000L,1000000L);
module_id_t Mod_id = 0;
// for multipule UE's L2-emulator
//module_id_t Mod_id = 0;
//int init_ra_UE = -1; // This counter is used to initiate the RA of each UE in different SFrames
static __thread int UE_thread_rxtx_retval;
struct rx_tx_thread_data *rtd = arg;
UE_rxtx_proc_t *proc = rtd->proc;
// Initializations for nfapi-L2-emulator mode
dl_config_req = NULL;
ul_config_req = NULL;
hi_dci0_req = NULL;
tx_request_pdu_list = NULL;
PHY_VARS_UE *UE; //= rtd->UE;
// settings for nfapi-L2-emulator mode
module_id_t ue_thread_id = rtd->ue_thread_id;
uint16_t ue_index = 0;
uint16_t ue_num = NB_UE_INST/NB_THREAD_INST+((NB_UE_INST%NB_THREAD_INST > ue_thread_id) ? 1 :0);
module_id_t ue_Mod_id;
PHY_VARS_UE *UE = NULL;
int ret;
uint8_t end_flag;
proc = &PHY_vars_UE_g[0][0]->proc.proc_rxtx[0];
phy_stub_ticking->num_single_thread[ue_thread_id] = -1;
if (rtd != NULL) {
UE = rtd->UE;
}
phy_stub_ticking->ticking_var = -1;
proc->subframe_rx=proc->sub_frame_start;
if(ue_thread_id == 0){
phy_stub_ticking->ticking_var = -1;
proc->subframe_rx=proc->sub_frame_start;
// Initializations for nfapi-L2-emulator mode
dl_config_req = NULL;
ul_config_req = NULL;
hi_dci0_req = NULL;
tx_request_pdu_list = NULL;
// waiting for all UE's threads set phy_stub_ticking->num_single_thread[ue_thread_id] = -1.
do{
end_flag = 1;
for(uint16_t i = 0;i< NB_THREAD_INST;i++){
if(phy_stub_ticking->num_single_thread[i] == 0){
end_flag = 0;
}
}
}while(end_flag == 0);
sync_var=0;
}
//PANOS: CAREFUL HERE!
wait_sync("UE_phy_stub_single_thread_rxn_txnp4");
while (!oai_exit) {
if(ue_thread_id == 0){
if (pthread_mutex_lock(&phy_stub_ticking->mutex_ticking) != 0) {
LOG_E( MAC, "[SCHED][UE] error locking mutex for UE RXTX\n" );
exit_fun("nothing to add");
@@ -1006,12 +1034,24 @@ static void *UE_phy_stub_single_thread_rxn_txnp4(void *arg) {
proc->subframe_rx=timer_subframe;
proc->frame_rx = timer_frame;
proc->subframe_tx=(timer_subframe+4)%10;
proc->frame_tx = proc->frame_rx + (proc->subframe_rx>5?1:0);
// FDD and TDD tx timing settings.
// XXX:It is the result of timing adjustment in debug.
// It is necessary to investigate why this will work in the future.
proc->subframe_tx=(timer_subframe+sf_ahead)%10;
proc->frame_tx = proc->frame_rx + (proc->subframe_rx>(9-sf_ahead)?1:0);
//oai_subframe_ind(proc->frame_rx, proc->subframe_rx);
oai_subframe_ind(timer_frame, timer_subframe);
if (UE != NULL) {
if (UE->frame_parms.frame_type == FDD) {
oai_subframe_ind(proc->frame_rx, proc->subframe_rx);
} else {
oai_subframe_ind(proc->frame_tx, proc->subframe_tx);
}
} else {
// Default will be FDD
oai_subframe_ind(proc->frame_rx, proc->subframe_rx);
}
//Guessing that the next 4 lines are not needed for the phy_stub mode.
/*initRefTimes(t2);
@@ -1035,14 +1075,45 @@ static void *UE_phy_stub_single_thread_rxn_txnp4(void *arg) {
UL_INFO->harq_ind.harq_indication_body.number_of_harqs = 0;
UL_INFO->sr_ind.sr_indication_body.sr_pdu_list = (nfapi_sr_indication_pdu_t*)malloc(NB_UE_INST*sizeof(nfapi_sr_indication_pdu_t));
UL_INFO->sr_ind.sr_indication_body.number_of_srs = 0;
UL_INFO->sr_ind.sr_indication_body.number_of_srs = 0;
UL_INFO->cqi_ind.cqi_pdu_list = (nfapi_cqi_indication_pdu_t*)malloc(NB_UE_INST*sizeof(nfapi_cqi_indication_pdu_t));
UL_INFO->cqi_ind.cqi_raw_pdu_list = (nfapi_cqi_indication_raw_pdu_t*)malloc(NB_UE_INST*sizeof(nfapi_cqi_indication_raw_pdu_t));
UL_INFO->cqi_ind.number_of_cqis = 0;
if (pthread_mutex_lock(&phy_stub_ticking->mutex_single_thread) != 0) {
LOG_E( MAC, "[SCHED][UE] error locking mutex for ue_thread_id %d (mutex_single_thread)\n",ue_thread_id);
exit_fun("nothing to add");
}
memset(&phy_stub_ticking->num_single_thread[0],0,sizeof(int)*NB_THREAD_INST);
pthread_cond_broadcast(&phy_stub_ticking->cond_single_thread);
if (pthread_mutex_unlock(&phy_stub_ticking->mutex_single_thread) != 0) {
LOG_E( MAC, "[SCHED][UE] error unlocking mutex for ue_thread_id %d (mutex_single_thread)\n",ue_thread_id);
exit_fun("nothing to add");
}
}else{
if (pthread_mutex_lock(&phy_stub_ticking->mutex_single_thread) != 0) {
LOG_E( MAC, "[SCHED][UE] error locking mutex for ue_thread_id %d (mutex_single_thread)\n",ue_thread_id);
exit_fun("nothing to add");
}
while (phy_stub_ticking->num_single_thread[ue_thread_id] < 0) {
// most of the time, the thread is waiting here
LOG_D(MAC,"Waiting for single_thread (ue_thread_id %d)\n",ue_thread_id);
pthread_cond_wait( &phy_stub_ticking->cond_single_thread, &phy_stub_ticking->mutex_single_thread);
}
if (pthread_mutex_unlock(&phy_stub_ticking->mutex_single_thread) != 0) {
LOG_E( MAC, "[SCHED][UE] error unlocking mutex for ue_thread_id %d (mutex_single_thread)\n",ue_thread_id);
exit_fun("nothing to add");
}
}
for (Mod_id=0; Mod_id<NB_UE_INST; Mod_id++) {
//LOG_D(MAC, "UE_phy_stub_single_thread_rxn_txnp4, NB_UE_INST:%d, Mod_id:%d \n", NB_UE_INST, Mod_id);
UE = PHY_vars_UE_g[Mod_id][0];
//for (Mod_id=0; Mod_id<NB_UE_INST; Mod_id++) {
for (ue_index=0; ue_index < ue_num; ue_index++) {
ue_Mod_id = ue_thread_id + NB_THREAD_INST*ue_index;
UE = PHY_vars_UE_g[ue_Mod_id][0];
//LOG_D(MAC, "UE_phy_stub_single_thread_rxn_txnp4, NB_UE_INST:%d, Mod_id:%d \n", NB_UE_INST, Mod_id);
//UE = PHY_vars_UE_g[Mod_id][0];
lte_subframe_t sf_type = subframe_select( &UE->frame_parms, proc->subframe_rx);
if ((sf_type == SF_DL) ||
(UE->frame_parms.frame_type == FDD) ||
@@ -1068,12 +1139,12 @@ static void *UE_phy_stub_single_thread_rxn_txnp4(void *arg) {
if (dl_config_req!=NULL && tx_request_pdu_list!=NULL){
//if(dl_config_req!= NULL) {
dl_config_req_UE_MAC(dl_config_req, Mod_id);
dl_config_req_UE_MAC(dl_config_req, ue_Mod_id);
}
if (hi_dci0_req!=NULL && hi_dci0_req->hi_dci0_request_body.hi_dci0_pdu_list!=NULL){
hi_dci0_req_UE_MAC(hi_dci0_req, Mod_id);
hi_dci0_req_UE_MAC(hi_dci0_req, ue_Mod_id);
}
if(nfapi_mode!=3)
@@ -1087,7 +1158,7 @@ static void *UE_phy_stub_single_thread_rxn_txnp4(void *arg) {
if (UE->mac_enabled==1) {
ret = ue_scheduler(UE->Mod_id,
ret = ue_scheduler(ue_Mod_id,
proc->frame_rx,
proc->subframe_rx,
proc->frame_tx,
@@ -1113,34 +1184,37 @@ static void *UE_phy_stub_single_thread_rxn_txnp4(void *arg) {
// We make the start of RA between consecutive UEs differ by 20 frames
//if ((UE_mac_inst[Mod_id].UE_mode[0] == PRACH && Mod_id == 0) || (UE_mac_inst[Mod_id].UE_mode[0] == PRACH && Mod_id>0 && proc->frame_rx >= UE_mac_inst[Mod_id-1].ra_frame + 20) ) {
if (UE_mac_inst[Mod_id].UE_mode[0] == PRACH && Mod_id == next_Mod_id && proc->frame_rx >= next_ra_frame) {
if (UE_mac_inst[ue_Mod_id].UE_mode[0] == PRACH && ue_Mod_id == next_Mod_id) {
next_ra_frame++;
if(next_ra_frame > 200){
// check if we have PRACH opportunity
if (is_prach_subframe(&UE->frame_parms,proc->frame_tx, proc->subframe_tx) && UE_mac_inst[Mod_id].SI_Decoded == 1) {
if (is_prach_subframe(&UE->frame_parms,proc->frame_tx, proc->subframe_tx) && UE_mac_inst[ue_Mod_id].SI_Decoded == 1) {
// The one working strangely...
//if (is_prach_subframe(&UE->frame_parms,proc->frame_tx, proc->subframe_tx && Mod_id == (module_id_t) init_ra_UE) ) {
PRACH_RESOURCES_t *prach_resources = ue_get_rach(Mod_id, 0, proc->frame_tx, 0, proc->subframe_tx);
PRACH_RESOURCES_t *prach_resources = ue_get_rach(ue_Mod_id, 0, proc->frame_tx, 0, proc->subframe_tx);
if(prach_resources!=NULL ) {
UE_mac_inst[Mod_id].ra_frame = proc->frame_rx;
LOG_D(MAC, "UE_phy_stub_thread_rxn_txnp4 before RACH, Mod_id: %d \n", Mod_id );
fill_rach_indication_UE_MAC(Mod_id, proc->frame_tx ,proc->subframe_tx, UL_INFO, prach_resources->ra_PreambleIndex, prach_resources->ra_RNTI);
Msg1_transmitted(Mod_id, 0, proc->frame_tx, 0);
UE_mac_inst[Mod_id].UE_mode[0] = RA_RESPONSE;
next_Mod_id = Mod_id + 1;
next_ra_frame = (proc->frame_rx + 20)%1000;
UE_mac_inst[ue_Mod_id].ra_frame = proc->frame_rx;
LOG_D(MAC, "UE_phy_stub_thread_rxn_txnp4 before RACH, Mod_id: %d frame %d subframe %d\n", ue_Mod_id ,proc->frame_tx, proc->subframe_tx);
fill_rach_indication_UE_MAC(ue_Mod_id, proc->frame_tx ,proc->subframe_tx, UL_INFO, prach_resources->ra_PreambleIndex, prach_resources->ra_RNTI);
Msg1_transmitted(ue_Mod_id, 0, proc->frame_tx, 0);
UE_mac_inst[ue_Mod_id].UE_mode[0] = RA_RESPONSE;
next_Mod_id = ue_Mod_id + 1;
//next_ra_frame = (proc->frame_rx + 20)%1000;
next_ra_frame = 0;
}
//ue_prach_procedures(ue,proc,eNB_id,abstraction_flag,mode);
}
}
} // mode is PRACH
// Substitute call to phy_procedures Tx with call to phy_stub functions in order to trigger
// UE Tx procedures directly at the MAC layer, based on the received ul_config requests from the vnf (eNB).
// Generate UL_indications which correspond to UL traffic.
if(ul_config_req!=NULL){ //&& UE_mac_inst[Mod_id].ul_config_req->ul_config_request_body.ul_config_pdu_list != NULL){
ul_config_req_UE_MAC(ul_config_req, timer_frame, timer_subframe, Mod_id);
ul_config_req_UE_MAC(ul_config_req, timer_frame, timer_subframe, ue_Mod_id);
}
}
@@ -1149,6 +1223,19 @@ static void *UE_phy_stub_single_thread_rxn_txnp4(void *arg) {
} //for (Mod_id=0; Mod_id<NB_UE_INST; Mod_id++)
phy_stub_ticking->num_single_thread[ue_thread_id] = -1;
// waiting for all UE's threads set phy_stub_ticking->num_single_thread[ue_thread_id] = -1.
if(ue_thread_id == 0){
do{
end_flag = 1;
for(uint16_t i = 0;i< NB_THREAD_INST;i++){
if(phy_stub_ticking->num_single_thread[i] == 0){
end_flag = 0;
}
}
}while(end_flag == 0);
if (UL_INFO->crc_ind.crc_indication_body.number_of_crcs>0)
{
@@ -1163,6 +1250,9 @@ static void *UE_phy_stub_single_thread_rxn_txnp4(void *arg) {
//LOG_D(PHY,"UL_info->rx_ind.number_of_pdus:%d RX_IND:SFN/SF:%d\n", UL_info->rx_ind.rx_indication_body.number_of_pdus, NFAPI_SFNSF2DEC(UL_info->rx_ind.sfn_sf));
//LOG_I(MAC, "ul_config_req_UE_MAC 2.3, SFN/SF of PNF counter:%d.%d, number_of_pdus: %d \n", timer_frame, timer_subframe, UL_INFO->rx_ind.rx_indication_body.number_of_pdus);
oai_nfapi_rx_ind(&UL_INFO->rx_ind);
for(uint8_t num_pdu = 0;num_pdu < UL_INFO->rx_ind.rx_indication_body.number_of_pdus;num_pdu++){
free(UL_INFO->rx_ind.rx_indication_body.rx_pdu_list[num_pdu].data);
}
//LOG_I(MAC, "ul_config_req_UE_MAC 2.31 \n");
UL_INFO->rx_ind.rx_indication_body.number_of_pdus = 0;
}
@@ -1199,14 +1289,19 @@ static void *UE_phy_stub_single_thread_rxn_txnp4(void *arg) {
free(UL_INFO->sr_ind.sr_indication_body.sr_pdu_list);
UL_INFO->sr_ind.sr_indication_body.sr_pdu_list = NULL;
//}
free(UL_INFO->cqi_ind.cqi_pdu_list);
UL_INFO->cqi_ind.cqi_pdu_list = NULL;
free(UL_INFO->cqi_ind.cqi_raw_pdu_list);
UL_INFO->cqi_ind.cqi_raw_pdu_list = NULL;
free(UL_INFO);
UL_INFO = NULL;
// De-allocate memory of nfapi requests copies before next subframe round
if(dl_config_req!=NULL){
if(dl_config_req->vendor_extension)
free(dl_config_req->vendor_extension);
if(dl_config_req->vendor_extension!=NULL){
free(dl_config_req->vendor_extension);
dl_config_req->vendor_extension = NULL;
}
if(dl_config_req->dl_config_request_body.dl_config_pdu_list!=NULL){
free(dl_config_req->dl_config_request_body.dl_config_pdu_list);
dl_config_req->dl_config_request_body.dl_config_pdu_list = NULL;
@@ -1236,7 +1331,7 @@ static void *UE_phy_stub_single_thread_rxn_txnp4(void *arg) {
hi_dci0_req = NULL;
}
}
}
// thread finished
@@ -1780,6 +1875,13 @@ void init_UE_single_thread_stub(int nb_inst) {
AssertFatal(PHY_vars_UE_g!=NULL,"PHY_vars_UE_g is NULL\n");
AssertFatal(PHY_vars_UE_g[i]!=NULL,"PHY_vars_UE_g[inst] is NULL\n");
AssertFatal(PHY_vars_UE_g[i][0]!=NULL,"PHY_vars_UE_g[inst][0] is NULL\n");
if(nfapi_mode == 3){
#ifdef NAS_UE
MessageDef *message_p;
message_p = itti_alloc_new_message(TASK_NAS_UE, INITIALIZE_MESSAGE);
itti_send_msg_to_task (TASK_NAS_UE, i + NB_eNB_INST, message_p);
#endif
}
}
UE = PHY_vars_UE_g[0][0];
@@ -1794,19 +1896,22 @@ void init_UE_single_thread_stub(int nb_inst) {
// In phy_stub_UE mode due to less heavy processing operations we don't need two threads
//int nb_threads=RX_NB_TH;
int nb_threads=1;
for (int i=0; i<nb_threads; i++) {
rtd = calloc(1, sizeof(struct rx_tx_thread_data));
if (rtd == NULL) abort();
rtd->UE = UE;
rtd->proc = &UE->proc.proc_rxtx[i];
pthread_mutex_init(&UE->proc.proc_rxtx[i].mutex_rxtx,NULL);
pthread_cond_init(&UE->proc.proc_rxtx[i].cond_rxtx,NULL);
UE->proc.proc_rxtx[i].sub_frame_start=i;
UE->proc.proc_rxtx[i].sub_frame_step=nb_threads;
printf("Init_UE_threads rtd %d proc %d nb_threads %d i %d\n",rtd->proc->sub_frame_start, UE->proc.proc_rxtx[i].sub_frame_start,nb_threads, i);
pthread_create(&UE->proc.proc_rxtx[i].pthread_rxtx, NULL, UE_phy_stub_single_thread_rxn_txnp4, rtd);
for(uint16_t ue_thread_id = 0;ue_thread_id < NB_THREAD_INST;ue_thread_id++){
UE = PHY_vars_UE_g[ue_thread_id][0];
for (int i=0; i<nb_threads; i++) {
rtd = calloc(1, sizeof(struct rx_tx_thread_data));
if (rtd == NULL) abort();
rtd->UE = UE;
rtd->proc = &UE->proc.proc_rxtx[i];
rtd->ue_thread_id = ue_thread_id;
pthread_mutex_init(&UE->proc.proc_rxtx[i].mutex_rxtx,NULL);
pthread_cond_init(&UE->proc.proc_rxtx[i].cond_rxtx,NULL);
UE->proc.proc_rxtx[i].sub_frame_start=i;
UE->proc.proc_rxtx[i].sub_frame_step=nb_threads;
printf("Init_UE_threads rtd %d proc %d nb_threads %d i %d\n",rtd->proc->sub_frame_start, UE->proc.proc_rxtx[i].sub_frame_start,nb_threads, i);
pthread_create(&UE->proc.proc_rxtx[i].pthread_rxtx, NULL, UE_phy_stub_single_thread_rxn_txnp4, rtd);
}
}
// Remove thread for UE_sync in phy_stub_UE mode.
//pthread_create(&UE->proc.pthread_synch,NULL,UE_thread_synch,(void*)UE);
@@ -2076,8 +2181,11 @@ int init_timer_thread(void) {
pthread_mutex_init(&UE->timer_mutex,NULL);
pthread_cond_init(&UE->timer_cond,NULL);
UE->instance_cnt_timer = -1;
memset(&phy_stub_ticking->num_single_thread[0],0,sizeof(int)*NB_THREAD_INST);
pthread_mutex_init(&phy_stub_ticking->mutex_ticking,NULL);
pthread_cond_init(&phy_stub_ticking->cond_ticking,NULL);
pthread_mutex_init(&phy_stub_ticking->mutex_single_thread,NULL);
pthread_cond_init(&phy_stub_ticking->cond_single_thread,NULL);
pthread_create(&phy_stub_ticking->pthread_timer, NULL, &timer_thread, NULL);
return 0;
}
+78 -73
View File
@@ -110,9 +110,13 @@ pthread_mutex_t nfapi_sync_mutex;
int nfapi_sync_var=-1; //!< protected by mutex \ref nfapi_sync_mutex
uint8_t nfapi_mode = 0;
#ifdef PDCP_USE_NETLINK
#ifdef UESIM_EXPANSION
uint16_t inst_pdcp_list[NUMBER_OF_UE_MAX];
#endif
#endif
uint16_t sf_ahead=2;
int tddflag;
char *emul_iface;
@@ -124,10 +128,6 @@ int config_sync_var=-1;
uint16_t runtime_phy_rx[29][6]; // SISO [MCS 0-28][RBs 0-5 : 6, 15, 25, 50, 75, 100]
uint16_t runtime_phy_tx[29][6]; // SISO [MCS 0-28][RBs 0-5 : 6, 15, 25, 50, 75, 100]
#if defined(ENABLE_ITTI)
volatile int start_eNB = 0;
volatile int start_UE = 0;
#endif
volatile int oai_exit = 0;
clock_source_t clock_source = internal;
@@ -398,48 +398,6 @@ static void *scope_thread(void *arg) {
#if defined(ENABLE_ITTI)
void *l2l1_task(void *arg) {
MessageDef *message_p = NULL;
int result;
itti_set_task_real_time(TASK_L2L1);
itti_mark_task_ready(TASK_L2L1);
do {
// Wait for a message
itti_receive_msg (TASK_L2L1, &message_p);
switch (ITTI_MSG_ID(message_p)) {
case TERMINATE_MESSAGE:
oai_exit=1;
itti_exit_task ();
break;
case ACTIVATE_MESSAGE:
start_UE = 1;
break;
case DEACTIVATE_MESSAGE:
start_UE = 0;
break;
case MESSAGE_TEST:
LOG_I(SIM, "Received %s\n", ITTI_MSG_NAME(message_p));
break;
default:
LOG_E(SIM, "Received unexpected message %s\n", ITTI_MSG_NAME(message_p));
break;
}
result = itti_free (ITTI_MSG_ORIGIN_ID(message_p), message_p);
AssertFatal (result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result);
} while(!oai_exit);
return NULL;
}
#endif
extern int16_t dlsch_demod_shift;
static void get_options(void) {
@@ -452,7 +410,6 @@ static void get_options(void) {
CONFIG_SETRTFLAG(CONFIG_NOEXITONHELP);
/* unknown parameters on command line will be checked in main
after all init have been performed */
CONFIG_SETRTFLAG(CONFIG_NOCHECKUNKOPT);
get_common_options();
get_uethreads_params();
paramdef_t cmdline_uemodeparams[] =CMDLINE_UEMODEPARAMS_DESC;
@@ -491,10 +448,12 @@ static void get_options(void) {
}
UE_scan=0;
if (tddflag > 0) {
for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++)
for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
frame_parms[CC_id]->frame_type = TDD;
frame_parms[CC_id]->tdd_config = tddflag;
}
}
if (frame_parms[0]->N_RB_DL !=0) {
@@ -722,9 +681,15 @@ int main( int argc, char **argv ) {
#endif
int CC_id;
uint8_t abstraction_flag=0;
#ifdef PDCP_USE_NETLINK
#ifdef UESIM_EXPANSION
memset(inst_pdcp_list, 0, sizeof(inst_pdcp_list));
#endif
#endif
// Default value for the number of UEs. It will hold,
// if not changed from the command line option --num-ues
NB_UE_INST=1;
NB_THREAD_INST=1;
#if defined (XFORMS)
int ret;
#endif
@@ -742,20 +707,42 @@ int main( int argc, char **argv ) {
for (int i=0; i<MAX_NUM_CCs; i++) tx_max_power[i]=23;
CONFIG_SETRTFLAG(CONFIG_NOCHECKUNKOPT);
get_options ();
printf("Running with %d UE instances\n",NB_UE_INST);
if (NB_UE_INST > 1 && simL1flag != 1) {
if (NB_UE_INST > 1 && simL1flag != 1 && nfapi_mode != 3) {
printf("Running with more than 1 UE instance and simL1 is not active, this will result in undefined behaviour for now, exiting.\n");
abort();
}
printf("NFAPI_MODE value: %d \n", nfapi_mode);
// Checking option of nums_ue_thread.
if(NB_THREAD_INST < 1){
printf("Running with 0 UE rxtx thread, exiting.\n");
abort();
}
// Checking option's relation between nums_ue_thread and num-ues
if(NB_UE_INST <NB_THREAD_INST ){
printf("Number of UEs < number of UE rxtx threads, exiting.\n");
abort();
}
// Not sure if the following is needed here
/*if (CONFIG_ISFLAGSET(CONFIG_ABORT)) {
if (UE_flag == 0) {
fprintf(stderr,"Getting configuration failed\n");
exit(-1);
}
else {
printf("Setting nfapi mode to UE_STUB_OFFNET\n");
nfapi_mode = 4;
}
}*/
#if T_TRACER
T_Config_Init();
#endif
CONFIG_CLEARRTFLAG(CONFIG_NOCHECKUNKOPT);
//randominit (0);
set_taus_seed (0);
cpuf=get_cpu_freq_GHz();
@@ -772,12 +759,7 @@ int main( int argc, char **argv ) {
MSC_INIT(MSC_E_UTRAN, THREAD_MAX+TASK_MAX);
#endif
if (opt_type != OPT_NONE) {
if (init_opt(in_path, in_ip) == -1)
LOG_E(OPT,"failed to run OPT \n");
}
init_opt();
#ifdef PDCP_USE_NETLINK
printf("PDCP netlink\n");
netlink_init();
@@ -834,6 +816,8 @@ int main( int argc, char **argv ) {
RCConfig_sim();
}
// source code written in below moved to later to avoid keeping waiting for nfapi_sync_cond in wait_nfapi_init.
/*
// start the main UE threads
int eMBMS_active = 0;
@@ -862,7 +846,8 @@ int main( int argc, char **argv ) {
PHY_vars_UE_g[0][CC_id]->rf_map.chain=CC_id+(get_softmodem_params()->chain_offset);
}
}
*/
cpuf=get_cpu_freq_GHz();
#ifndef DEADLINE_SCHEDULER
printf("NO deadline scheduler\n");
@@ -907,8 +892,7 @@ int main( int argc, char **argv ) {
LOG_I(HW, "CPU Affinity of main() function is... %s\n", cpu_affinity);
#endif
#if defined(ENABLE_ITTI)
if (create_tasks_ue(1) < 0) {
if (create_tasks_ue(NB_UE_INST) < 0) {
printf("cannot create ITTI tasks\n");
exit(-1); // need a softer mode
}
@@ -922,6 +906,8 @@ int main( int argc, char **argv ) {
mlockall(MCL_CURRENT | MCL_FUTURE);
rt_sleep_ns(10*100000000ULL);
const char *nfapi_mode_str = "<UNKNOWN>";
// start the main UE threads
int eMBMS_active = 0;
switch(nfapi_mode) {
case 0:
@@ -951,6 +937,33 @@ int main( int argc, char **argv ) {
printf("NFAPI MODE:%s\n", nfapi_mode_str);
if (nfapi_mode==3) // UE-STUB-PNF
{
config_sync_var=0;
wait_nfapi_init("main?");
//Panos: Temporarily we will be using single set of threads for multiple UEs.
//init_UE_stub(1,eMBMS_active,uecap_xer_in,emul_iface);
init_UE_stub_single_thread(NB_UE_INST,eMBMS_active,uecap_xer_in,emul_iface);
}
else {
init_UE(NB_UE_INST,eMBMS_active,uecap_xer_in,0,get_softmodem_params()->phy_test,UE_scan,UE_scan_carrier,mode,(int)rx_gain[0][0],tx_max_power[0],
frame_parms[0]);
}
if (get_softmodem_params()->phy_test==0) {
printf("Filling UE band info\n");
fill_ue_band_info();
dl_phy_sync_success (0, 0, 0, 1);
}
if (nfapi_mode!=3){
number_of_cards = 1;
for(CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
PHY_vars_UE_g[0][CC_id]->rf_map.card=0;
PHY_vars_UE_g[0][CC_id]->rf_map.chain=CC_id+(get_softmodem_params()->chain_offset);
}
}
// connect the TX/RX buffers
/*
@@ -1010,13 +1023,7 @@ int main( int argc, char **argv ) {
}
#endif
ret=config_check_unknown_cmdlineopt(CONFIG_CHECKALLSECTIONS);
if (ret != 0) {
LOG_E(ENB_APP, "%i unknown options in command line (invalid section name)\n",ret);
exit_fun("");
}
config_check_unknown_cmdlineopt(CONFIG_CHECKALLSECTIONS);
printf("Sending sync to all threads (%p,%p,%p)\n",&sync_var,&sync_cond,&sync_mutex);
pthread_mutex_lock(&sync_mutex);
sync_var=0;
@@ -1067,9 +1074,7 @@ int main( int argc, char **argv ) {
if (PHY_vars_UE_g[0][0]->rfdevice.trx_end_func)
PHY_vars_UE_g[0][0]->rfdevice.trx_end_func(&PHY_vars_UE_g[0][0]->rfdevice);
if (opt_enabled == 1)
terminate_opt();
terminate_opt();
logClean();
printf("Bye.\n");
return 0;