Commit 107e2561 authored by bruno mongazon's avatar bruno mongazon

fixed #320 issue

parents b016bc22 923817d8
......@@ -8,8 +8,7 @@ pipeline {
disableConcurrentBuilds()
timestamps()
gitLabConnection('OAI GitLab')
//gitlabBuilds(builds: ["Build", "Test"])
gitlabBuilds(builds: ["Local Build"])
gitlabBuilds(builds: ["Build eNb-USRP", "Build basic-sim", "Build phy-sim", "Analysis with cppcheck"])
}
stages {
......@@ -22,6 +21,7 @@ pipeline {
// GitLab-Jenkins plugin integration is lacking to perform the merge by itself
// Doing it manually --> it may have merge conflicts
sh "./ci-scripts/doGitLabMerge.sh --src-branch ${env.gitlabSourceBranch} --src-commit ${env.gitlabMergeRequestLastCommit} --target-branch ${env.gitlabTargetBranch} --target-commit ${GIT_COMMIT}"
sh "zip -r -qq localZip.zip ."
// Running astyle options on the list of modified files by the merge request
// For the moment, there is no fail criteria. Just a notification of number of files that do not follow
......@@ -38,6 +38,7 @@ pipeline {
echo "Git Branch is ${GIT_BRANCH}"
echo "Git Commit is ${GIT_COMMIT}"
sh "zip -r -qq localZip.zip ."
// Running astyle options on all C/H files in the repository
// For the moment, there is no fail criteria. Just a notification of number of files that do not follow
sh "./ci-scripts/checkCodingFormattingRules.sh"
......@@ -45,17 +46,46 @@ pipeline {
}
}
}
stage ("Local Build") {
steps {
gitlabCommitStatus(name: "Local Build") {
sh "./ci-scripts/buildLocally.sh --workspace $WORKSPACE"
stage ("Variant Builds") {
parallel {
stage ("Analysis with cppcheck") {
steps {
gitlabCommitStatus(name: "Analysis with cppcheck") {
sh "./ci-scripts/buildOnVM.sh --workspace $WORKSPACE --variant cppcheck"
}
}
}
stage ("Build eNb-USRP") {
steps {
gitlabCommitStatus(name: "Build eNb-USRP") {
sh "./ci-scripts/buildOnVM.sh --workspace $WORKSPACE --variant enb-usrp"
}
}
}
stage ("Build basic simulator") {
steps {
gitlabCommitStatus(name: "Build basic-sim") {
sh "./ci-scripts/buildOnVM.sh --workspace $WORKSPACE --variant basic-sim"
}
}
}
stage ("Build physical simulators") {
steps {
gitlabCommitStatus(name: "Build phy-sim") {
sh "./ci-scripts/buildOnVM.sh --workspace $WORKSPACE --variant phy-sim"
}
}
}
}
post {
always {
script {
if(fileExists('archives/local_build_logs.zip')) {
archiveArtifacts artifacts: 'archives/local_build_logs.zip'
dir ('archives') {
sh "zip -r vm_build_logs.zip basic_sim enb_usrp phy_sim cppcheck"
}
if(fileExists('archives/vm_build_logs.zip')) {
archiveArtifacts artifacts: 'archives/vm_build_logs.zip'
}
if ("MERGE".equals(env.gitlabActionType)) {
sh "./ci-scripts/reportBuildLocally.sh --git-url ${GIT_URL} --job-name ${JOB_NAME} --build-id ${BUILD_ID} --trigger merge-request --src-branch ${env.gitlabSourceBranch} --src-commit ${env.gitlabMergeRequestLastCommit} --target-branch ${env.gitlabTargetBranch} --target-commit ${GIT_COMMIT}"
......
#!/bin/bash
function usage {
echo "OAI VM Build Check script"
echo " Original Author: Raphael Defosseux"
echo " Requirements:"
echo " -- uvtool uvtool-libvirt apt-cacher"
echo " -- xenial image already synced"
echo " Default:"
echo " -- eNB with USRP"
echo ""
echo "Usage:"
echo "------"
echo " buildOnVM.sh [OPTIONS]"
echo ""
echo "Options:"
echo "--------"
echo " --workspace #### OR -ws ####"
echo " Specify the workspace."
echo ""
echo " --variant enb-usrp OR -v1"
echo " --variant basic-sim OR -v2"
echo " --variant phy-sim OR -v3"
echo " --variant cppcheck OR -v4"
echo " Specify the variant to build."
echo ""
echo " --keep-vm-alive OR -k"
echo " Keep the VM alive after the build."
echo ""
echo " --help OR -h"
echo " Print this help message."
echo ""
}
function variant_usage {
echo "OAI VM Build Check script"
echo " Original Author: Raphael Defosseux"
echo ""
echo " --variant enb-usrp OR -v1"
echo " --variant basic-sim OR -v2"
echo " --variant phy-sim OR -v3"
echo " --variant cppcheck OR -v4"
echo ""
}
if [ $# -lt 1 ] || [ $# -gt 5 ]
then
echo "Syntax Error: not the correct number of arguments"
echo ""
usage
exit 1
fi
VM_NAME=ci-enb-usrp
ARCHIVES_LOC=enb_usrp
LOG_PATTERN=.Rel14.txt
NB_PATTERN_FILES=4
BUILD_OPTIONS="--eNB -w USRP"
KEEP_VM_ALIVE=0
while [[ $# -gt 0 ]]
do
key="$1"
case $key in
-h|--help)
shift
usage
exit 0
;;
-ws|--workspace)
JENKINS_WKSP="$2"
shift
shift
;;
-k|--keep-vm-alive)
KEEP_VM_ALIVE=1
shift
;;
-v1)
VM_NAME=ci-enb-usrp
ARCHIVES_LOC=enb_usrp
LOG_PATTERN=.Rel14.txt
NB_PATTERN_FILES=4
BUILD_OPTIONS="--eNB -w USRP"
shift
;;
-v2)
VM_NAME=ci-basic-sim
ARCHIVES_LOC=basic_sim
LOG_PATTERN=basic_simulator
NB_PATTERN_FILES=2
BUILD_OPTIONS="--basic-simulator"
shift
;;
-v3)
VM_NAME=ci-phy-sim
ARCHIVES_LOC=phy_sim
LOG_PATTERN=.Rel14.txt
NB_PATTERN_FILES=3
BUILD_OPTIONS="--phy_simulators"
shift
;;
-v4)
VM_NAME=ci-cppcheck
ARCHIVES_LOC=cppcheck
LOG_PATTERN=cppcheck.xml
NB_PATTERN_FILES=1
BUILD_OPTIONS="--enable=warning --force --xml --xml-version=2"
shift
;;
--variant)
variant="$2"
case $variant in
enb-usrp)
VM_NAME=ci-enb-usrp
ARCHIVES_LOC=enb_usrp
LOG_PATTERN=.Rel14.txt
NB_PATTERN_FILES=4
BUILD_OPTIONS="--eNB -w USRP"
;;
basic-sim)
VM_NAME=ci-basic-sim
ARCHIVES_LOC=basic_sim
LOG_PATTERN=basic_simulator
NB_PATTERN_FILES=2
BUILD_OPTIONS="--basic-simulator"
;;
phy-sim)
VM_NAME=ci-phy-sim
ARCHIVES_LOC=phy_sim
LOG_PATTERN=.Rel14.txt
NB_PATTERN_FILES=3
BUILD_OPTIONS="--phy_simulators"
;;
cppcheck)
VM_NAME=ci-cppcheck
ARCHIVES_LOC=cppcheck
LOG_PATTERN=cppcheck.xml
NB_PATTERN_FILES=1
BUILD_OPTIONS="--enable=warning --force --xml --xml-version=2"
;;
*)
echo ""
echo "Syntax Error: Invalid Variant option -> $variant"
echo ""
variant_usage
exit 1
esac
shift
shift
;;
*)
echo "Syntax Error: unknown option: $key"
echo ""
usage
exit 1
esac
done
if [ ! -f $JENKINS_WKSP/localZip.zip ]
then
echo "Missing localZip.zip file!"
exit 1
fi
if [ ! -f /etc/apt/apt.conf.d/01proxy ]
then
echo "Missing /etc/apt/apt.conf.d/01proxy file!"
echo "Is apt-cacher installed and configured?"
exit 1
fi
VM_CMDS=${VM_NAME}_cmds.txt
ARCHIVES_LOC=${JENKINS_WKSP}/archives/${ARCHIVES_LOC}
echo "VM_NAME = $VM_NAME"
echo "VM_CMD_FILE = $VM_CMDS"
echo "JENKINS_WKSP = $JENKINS_WKSP"
echo "ARCHIVES_LOC = $ARCHIVES_LOC"
echo "BUILD_OPTIONS = $BUILD_OPTIONS"
echo "############################################################"
echo "Creating VM ($VM_NAME) on Ubuntu Cloud Image base"
echo "############################################################"
uvt-kvm create $VM_NAME release=xenial --memory 2048 --cpu 4 --unsafe-caching --template ci-scripts/template-host.xml
echo "Waiting for VM to be started"
uvt-kvm wait $VM_NAME --insecure
VM_IP_ADDR=`uvt-kvm ip $VM_NAME`
echo "$VM_NAME has for IP addr = $VM_IP_ADDR"
echo "############################################################"
echo "Copying GIT repo into VM ($VM_NAME)"
echo "############################################################"
scp -o StrictHostKeyChecking=no localZip.zip ubuntu@$VM_IP_ADDR:/home/ubuntu
scp -o StrictHostKeyChecking=no /etc/apt/apt.conf.d/01proxy ubuntu@$VM_IP_ADDR:/home/ubuntu
echo "############################################################"
echo "Running install and build script on VM ($VM_NAME)"
echo "############################################################"
echo "sudo cp 01proxy /etc/apt/apt.conf.d/" > $VM_CMDS
if [ "$VM_NAME" == "ci-cppcheck" ]
then
echo "echo \"sudo apt-get --yes --quiet install zip cppcheck \"" >> $VM_CMDS
echo "sudo apt-get update > zip-install.txt 2>&1" >> $VM_CMDS
echo "sudo apt-get --yes install zip cppcheck >> zip-install.txt 2>&1" >> $VM_CMDS
else
echo "echo \"sudo apt-get --yes --quiet install zip subversion libboost-dev \"" >> $VM_CMDS
echo "sudo apt-get --yes install zip subversion libboost-dev > zip-install.txt 2>&1" >> $VM_CMDS
fi
echo "mkdir tmp" >> $VM_CMDS
echo "cd tmp" >> $VM_CMDS
echo "echo \"unzip -qq -DD ../localZip.zip\"" >> $VM_CMDS
echo "unzip -qq -DD ../localZip.zip" >> $VM_CMDS
if [ "$VM_NAME" == "ci-cppcheck" ]
then
echo "mkdir cmake_targets/log" >> $VM_CMDS
echo "cp /home/ubuntu/zip-install.txt cmake_targets/log" >> $VM_CMDS
echo "echo \"cppcheck $BUILD_OPTIONS . \"" >> $VM_CMDS
echo "cppcheck $BUILD_OPTIONS . 2> cmake_targets/log/cppcheck.xml 1> cmake_targets/log/cppcheck_build.txt" >> $VM_CMDS
else
echo "echo \"source oaienv\"" >> $VM_CMDS
echo "source oaienv" >> $VM_CMDS
echo "cd cmake_targets/" >> $VM_CMDS
echo "mkdir log" >> $VM_CMDS
echo "cp /home/ubuntu/zip-install.txt log" >> $VM_CMDS
echo "echo \"./build_oai -I $BUILD_OPTIONS \"" >> $VM_CMDS
echo "./build_oai -I $BUILD_OPTIONS > log/install-build.txt 2>&1" >> $VM_CMDS
fi
ssh -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR < $VM_CMDS
echo "############################################################"
echo "Creating a tmp folder to store results and artifacts"
echo "############################################################"
if [ ! -d $JENKINS_WKSP/archives ]
then
mkdir $JENKINS_WKSP/archives
fi
if [ ! -d $ARCHIVES_LOC ]
then
mkdir $ARCHIVES_LOC
fi
scp -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/*.txt $ARCHIVES_LOC
if [ "$VM_NAME" == "ci-cppcheck" ]
then
scp -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/*.xml $ARCHIVES_LOC
fi
if [ $KEEP_VM_ALIVE -eq 0 ]
then
echo "############################################################"
echo "Destroying VM"
echo "############################################################"
uvt-kvm destroy $VM_NAME
ssh-keygen -R $VM_IP_ADDR
fi
rm -f $VM_CMDS
echo "############################################################"
echo "Checking build status"
echo "############################################################"
LOG_FILES=`ls $ARCHIVES_LOC/*.txt $ARCHIVES_LOC/*.xml`
STATUS=0
NB_FOUND_FILES=0
for FULLFILE in $LOG_FILES
do
if [[ $FULLFILE == *"$LOG_PATTERN"* ]]
then
filename=$(basename -- "$FULLFILE")
if [ "$LOG_PATTERN" == ".Rel14.txt" ]
then
PASS_PATTERN=`echo $filename | sed -e "s#$LOG_PATTERN##"`
fi
if [ "$LOG_PATTERN" == "basic_simulator" ]
then
PASS_PATTERN="lte-"
fi
if [ "$LOG_PATTERN" == "cppcheck.xml" ]
then
PASS_PATTERN="results version"
LOCAL_STAT=`egrep -c "$PASS_PATTERN" $FULLFILE`
else
LOCAL_STAT=`egrep -c "Built target $PASS_PATTERN" $FULLFILE`
fi
if [ $LOCAL_STAT -eq 0 ]; then STATUS=-1; fi
NB_FOUND_FILES=$((NB_FOUND_FILES + 1))
fi
done
if [ $NB_PATTERN_FILES -ne $NB_FOUND_FILES ]; then STATUS=-1; fi
if [ $STATUS -eq 0 ]
then
echo "STATUS seems OK"
else
echo "STATUS failed?"
fi
exit $STATUS
This diff is collapsed.
<domain type='kvm'>
<os>
<type>hvm</type>
<boot dev='hd'/>
</os>
<features>
<acpi/>
<apic/>
<pae/>
</features>
<cpu mode='host-passthrough'>
</cpu>
<devices>
<interface type='network'>
<source network='default'/>
<model type='virtio'/>
</interface>
<serial type='pty'>
<source path='/dev/pts/3'/>
<target port='0'/>
</serial>
<graphics type='vnc' autoport='yes' listen='127.0.0.1'>
<listen type='address' address='127.0.0.1'/>
</graphics>
<video/>
</devices>
</domain>
......@@ -516,7 +516,7 @@ int config_request(nfapi_pnf_config_t* config, nfapi_pnf_phy_config_t* phy, nfap
uint8_t num_tlv = 0;
//struct PHY_VARS_eNB_s *eNB = RC.eNB[0][0];
// Panos: In the case of nfapi_mode = 3 (UE = PNF) we should not have dependency on any eNB var. So we aim
// In the case of nfapi_mode = 3 (UE = PNF) we should not have dependency on any eNB var. So we aim
// to keep only the necessary just to keep the nfapi FSM rolling by sending a dummy response.
LTE_DL_FRAME_PARMS *fp;
if (nfapi_mode!=3) {
......@@ -1105,7 +1105,6 @@ int start_request(nfapi_pnf_config_t* config, nfapi_pnf_phy_config_t* phy, nfapi
}
if(phy_info->timing_info_mode & 0x2) {
//printf("Panos-D: start_request () Enabling timing_info_mode_aperiodic \n");
p7_config->timing_info_mode_aperiodic = 1;
}
......@@ -1173,9 +1172,6 @@ int start_request(nfapi_pnf_config_t* config, nfapi_pnf_phy_config_t* phy, nfapi
NFAPI_TRACE(NFAPI_TRACE_INFO, "[PNF] DJP - HACK - Set p7_config global ready for subframe ind%s\n", __FUNCTION__);
p7_config_g = p7_config;
//NFAPI_TRACE(NFAPI_TRACE_INFO, "[PNF] Panos-D: start_request, BUFFER SIZE: %d", p7_config_g->subframe_buffer_size);
//printf("Panos-D: start_request, bUFFER SIZE: %d", p7_config_g->subframe_buffer_size);
// Need to wait for main thread to create RU structures
while(config_sync_var<0)
{
......@@ -1189,13 +1185,7 @@ int start_request(nfapi_pnf_config_t* config, nfapi_pnf_phy_config_t* phy, nfapi
printf("[PNF] About to call init_eNB_afterRU()\n");
// Panos: Instead
/*if (nfapi_mode == 3) {
init_UE_stub(1,0,uecap_xer_in);
}*/
//else{
if (nfapi_mode != 3) {
// Panos
init_eNB_afterRU();
}
......
......@@ -1248,12 +1248,12 @@ void vnf_handle_timing_info(void *pRecvMsg, int recvMsgLen, vnf_p7_t* vnf_p7)
//NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() PNF:SFN/SF:%d VNF:SFN/SF:%d deltaSFNSF:%d\n", __FUNCTION__, NFAPI_SFNSF2DEC(ind.last_sfn_sf), NFAPI_SFNSF2DEC(vnf_p7->p7_connections[0].sfn_sf), vnf_pnf_sfnsf_delta);
// Panos: Careful here!!!
// Panos: Careful here!!! Modification of the original nfapi-code
//if (vnf_pnf_sfnsf_delta>1 || vnf_pnf_sfnsf_delta < -1)
if (vnf_pnf_sfnsf_delta>0 || vnf_pnf_sfnsf_delta < 0)
{
NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() LARGE SFN/SF DELTA between PNF and VNF delta:%d VNF:%d PNF:%d\n\n\n\n\n\n\n\n\n", __FUNCTION__, vnf_pnf_sfnsf_delta, NFAPI_SFNSF2DEC(vnf_p7->p7_connections[0].sfn_sf), NFAPI_SFNSF2DEC(ind.last_sfn_sf));
// Panos: Careful here!!!
// Panos: Careful here!!! Modification of the original nfapi-code
vnf_p7->p7_connections[0].sfn_sf = ind.last_sfn_sf;
}
}
......
......@@ -161,12 +161,12 @@ typedef struct {
UE_rxtx_proc_t proc_rxtx[RX_NB_TH];
} UE_proc_t;
/// Panos: Structure holding timer_thread related elements (phy_stub_UE mode)
/// Structure holding timer_thread related elements (phy_stub_UE mode)
typedef struct {
pthread_t pthread_timer;
/// Panos: mutex for waiting SF ticking
/// mutex for waiting SF ticking
pthread_mutex_t mutex_ticking;
/// Panos: \brief ticking var for ticking thread.
/// \brief ticking var for ticking thread.
/// \internal This variable is protected by \ref mutex_ticking.
int ticking_var;
/// condition variable for timer_thread;
......
......@@ -512,7 +512,6 @@ void ue_compute_srs_occasion(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id
{
int Mod_id = ue->Mod_id;
int CC_id = ue->CC_id;
// Panos: Substitute call to ue_get_SR() with the filled ue_SR_config->SR_payload (0, or 1).
SR_payload = ue_get_SR(Mod_id,
CC_id,
frame_tx,
......@@ -2753,7 +2752,6 @@ void ue_pbch_procedures(uint8_t eNB_id,PHY_VARS_UE *ue,UE_rxtx_proc_t *proc, uin
ue->pbch_vars[eNB_id]->pdu_errors_conseq++;
ue->pbch_vars[eNB_id]->pdu_errors++;
// Panos: Substitute call to rrc_out_of_sync_ind() with fill_bch_incication(sync=0).
if (ue->mac_enabled == 1) rrc_out_of_sync_ind(ue->Mod_id,frame_rx,eNB_id);
else AssertFatal(ue->pbch_vars[eNB_id]->pdu_errors_conseq<100,
"More that 100 consecutive PBCH errors! Exiting!\n");
......@@ -3428,7 +3426,6 @@ void process_rar(PHY_VARS_UE *ue, UE_rxtx_proc_t *proc, int eNB_id, runmode_t mo
subframe_rx,
ue->prach_resources[eNB_id]->ra_PreambleIndex);
// Panos: Substitute call to ue_process_rar() with call to fill_dlsch_rar_indication()
timing_advance = ue_process_rar(ue->Mod_id,
ue->CC_id,
frame_rx,
......@@ -3755,7 +3752,6 @@ void ue_dlsch_procedures(PHY_VARS_UE *ue,
switch (pdsch) {
case PDSCH:
// Panos: Substitute call to ue_send_sdu() with call to fill_dlsch_indication()
ue_send_sdu(ue->Mod_id,
CC_id,
frame_rx,
......@@ -3765,7 +3761,6 @@ void ue_dlsch_procedures(PHY_VARS_UE *ue,
eNB_id);
break;
case SI_PDSCH:
// Panos: Substitute call with call to fill_dlsch_indication()
ue_decode_si(ue->Mod_id,
CC_id,
frame_rx,
......@@ -3774,7 +3769,6 @@ void ue_dlsch_procedures(PHY_VARS_UE *ue,
ue->dlsch_SI[eNB_id]->harq_processes[0]->TBS>>3);
break;
case P_PDSCH:
// Panos: Substitute call with call to fill_dlsch_indication()
ue_decode_p(ue->Mod_id,
CC_id,
frame_rx,
......@@ -3783,7 +3777,6 @@ void ue_dlsch_procedures(PHY_VARS_UE *ue,
ue->dlsch_SI[eNB_id]->harq_processes[0]->TBS>>3);
break;
case RA_PDSCH:
// Panos: Substitute with call to fill_dlsch_rar_indication()
process_rar(ue,proc,eNB_id,mode,abstraction_flag);
break;
case PDSCH1:
......
......@@ -230,47 +230,6 @@ void RCconfig_flexran()
}
/*void UE_config_stub_pnf(void) {
int j;
paramdef_t L1_Params[] = L1PARAMS_DESC;
paramlist_def_t L1_ParamList = {CONFIG_STRING_L1_LIST,NULL,0};
config_getlist( &L1_ParamList,L1_Params,sizeof(L1_Params)/sizeof(paramdef_t), NULL);
if (L1_ParamList.numelt > 0) {
for (j=0; j<L1_ParamList.numelt; j++){
//nb_L1_CC = *(L1_ParamList.paramarray[j][L1_CC_IDX].uptr); // Number of component carriers is of no use for the
// phy_stub mode UE pnf. Maybe we can completely skip it.
if (strcmp(*(L1_ParamList.paramarray[j][L1_TRANSPORT_N_PREFERENCE_IDX].strptr), "local_mac") == 0) {
sf_ahead = 4; // Need 4 subframe gap between RX and TX
}
// Panos: Right now that we have only one UE (thread) it is ok to put the eth_params in the UE_mac_inst.
// Later I think we have to change that to attribute eth_params to a global element for all the UEs.
else if (strcmp(*(L1_ParamList.paramarray[j][L1_TRANSPORT_N_PREFERENCE_IDX].strptr), "nfapi") == 0) {
stub_eth_params.local_if_name = strdup(*(L1_ParamList.paramarray[j][L1_LOCAL_N_IF_NAME_IDX].strptr));
stub_eth_params.my_addr = strdup(*(L1_ParamList.paramarray[j][L1_LOCAL_N_ADDRESS_IDX].strptr));
stub_eth_params.remote_addr = strdup(*(L1_ParamList.paramarray[j][L1_REMOTE_N_ADDRESS_IDX].strptr));
stub_eth_params.my_portc = *(L1_ParamList.paramarray[j][L1_LOCAL_N_PORTC_IDX].iptr);
stub_eth_params.remote_portc = *(L1_ParamList.paramarray[j][L1_REMOTE_N_PORTC_IDX].iptr);
stub_eth_params.my_portd = *(L1_ParamList.paramarray[j][L1_LOCAL_N_PORTD_IDX].iptr);
stub_eth_params.remote_portd = *(L1_ParamList.paramarray[j][L1_REMOTE_N_PORTD_IDX].iptr);
stub_eth_params.transp_preference = ETH_UDP_MODE;
sf_ahead = 2; // Cannot cope with 4 subframes betweem RX and TX - set it to 2
//configure_nfapi_pnf(UE_mac_inst[0].eth_params_n.remote_addr, UE_mac_inst[0].eth_params_n.remote_portc, UE_mac_inst[0].eth_params_n.my_addr, UE_mac_inst[0].eth_params_n.my_portd, UE_mac_inst[0].eth_params_n.remote_portd);
configure_nfapi_pnf(stub_eth_params.remote_addr, stub_eth_params.remote_portc, stub_eth_params.my_addr, stub_eth_params.my_portd, stub_eth_params.remote_portd);
}
else { // other midhaul
}
}
}
else {
}
}*/
void RCconfig_L1(void) {
int i,j;
paramdef_t L1_Params[] = L1PARAMS_DESC;
......@@ -338,7 +297,6 @@ void RCconfig_L1(void) {
configure_nfapi_pnf(RC.eNB[j][0]->eth_params_n.remote_addr, RC.eNB[j][0]->eth_params_n.remote_portc, RC.eNB[j][0]->eth_params_n.my_addr, RC.eNB[j][0]->eth_params_n.my_portd, RC.eNB[j][0]->eth_params_n .remote_portd);
}
else { // other midhaul
//printf("Panos-D: RCconfig_L1 12 \n");
}
}// j=0..num_inst
printf("Initializing northbound interface for L1\n");
......
......@@ -1006,7 +1006,7 @@ generate_Msg4(module_id_t module_idP, int CC_idP, frame_t frameP,
#endif
{
// This is normal LTE case
LOG_D(MAC, "Panos-D: generate_Msg4 1 ra->Msg4_frame SFN/SF: %d.%d, frameP SFN/SF: %d.%d FOR eNB_Mod: %d \n", ra->Msg4_frame, ra->Msg4_subframe, frameP, subframeP, module_idP);
LOG_D(MAC, "generate_Msg4 1 ra->Msg4_frame SFN/SF: %d.%d, frameP SFN/SF: %d.%d FOR eNB_Mod: %d \n", ra->Msg4_frame, ra->Msg4_subframe, frameP, subframeP, module_idP);
if ((ra->Msg4_frame == frameP) && (ra->Msg4_subframe == subframeP)) {
// Get RRCConnectionSetup for Piggyback
......@@ -1326,7 +1326,7 @@ check_Msg4_retransmission(module_id_t module_idP, int CC_idP,
ra->rnti, round, frameP, subframeP);
// DLSCH Config
//DJP - fix this pdu_index = -1
LOG_D(MAC, "Panos:D: check_Msg4_retransmission() before fill_nfapi_dlsch_config() with pdu_index = -1 \n");
LOG_D(MAC, "check_Msg4_retransmission() before fill_nfapi_dlsch_config() with pdu_index = -1 \n");
fill_nfapi_dlsch_config(mac, dl_req_body, ra->msg4_TBsize,
-1
/* retransmission, no pdu_index */
......
......@@ -324,7 +324,6 @@ typedef struct {
uint8_t Buffer_size0:6;
} __attribute__ ((__packed__)) BSR_LONG;
// Panos:
/*!\brief mac control element: sidelink buffer status report */
typedef struct {
uint8_t DST_1:4;
......@@ -1522,13 +1521,13 @@ typedef struct {
time_stats_t rx_si;
/// UE PCCH rx processing time including RLC interface (mac_rrc_data_ind)
time_stats_t rx_p;
/// Panos: Mutex for nfapi UL_INFO
/// Mutex for nfapi UL_INFO
pthread_mutex_t UL_INFO_mutex;
/// Panos: UE_Mode variable should be used in the case of Phy_stub operation since we won't have access to PHY_VARS_UE
/// UE_Mode variable should be used in the case of Phy_stub operation since we won't have access to PHY_VARS_UE
/// where the UE_mode originally is for the full stack operation mode. The transitions between the states of the UE_Mode
/// will be triggered within phy_stub_ue.c in this case
UE_MODE_t UE_mode[NUMBER_OF_CONNECTED_eNB_MAX];
/// Panos: Phy_stub mode: Boolean variable to distinguish whether a Msg3 or a regular ULSCH data pdu should be generated
/// Phy_stub mode: Boolean variable to distinguish whether a Msg3 or a regular ULSCH data pdu should be generated
/// after the reception of NFAPI_UL_CONFIG_ULSCH_PDU_TYPE.
uint8_t first_ULSCH_Tx;
uint8_t SI_Decoded;
......
......@@ -299,8 +299,8 @@ PRACH_RESOURCES_t *ue_get_rach(module_id_t module_idP, int CC_id,
uint8_t Size = 0;
UE_MODE_t UE_mode;
// Panos: Modification for phy_stub_ue operation
if(nfapi_mode == 3) { // Panos: phy_stub_ue mode
// Modification for phy_stub_ue operation
if(nfapi_mode == 3) { // phy_stub_ue mode
UE_mode = UE_mac_inst[module_idP].UE_mode[0];
LOG_D(MAC, "ue_get_rach , UE_mode: %d", UE_mode);
}
......
......@@ -475,8 +475,8 @@ ue_send_sdu(module_id_t module_idP,
LOG_E(MAC,
"[UE %d][RAPROC] Contention detected, RA failed\n",
module_idP);
if(nfapi_mode == 3) { // Panos: phy_stub mode
// Panos: Modification for phy_stub mode operation here. We only need to make sure that the ue_mode is back to
if(nfapi_mode == 3) { // phy_stub mode
// Modification for phy_stub mode operation here. We only need to make sure that the ue_mode is back to
// PRACH state.
LOG_I(MAC, "nfapi_mode3: Setting UE_mode BACK to PRACH 1\n");
UE_mac_inst[module_idP].UE_mode[eNB_index] = PRACH;
......@@ -502,7 +502,7 @@ ue_send_sdu(module_id_t module_idP,
RA_contention_resolution_timer_active = 0;
if(nfapi_mode == 3) // phy_stub mode
{
//Panos: Modification for phy_stub mode operation here. We only need to change the ue_mode to PUSCH
// Modification for phy_stub mode operation here. We only need to change the ue_mode to PUSCH
UE_mac_inst[module_idP].UE_mode[eNB_index] = PUSCH;
}
else { // Full stack mode
......@@ -519,7 +519,7 @@ ue_send_sdu(module_id_t module_idP,
payload_ptr[0]);
#endif
// Panos: Eliminate call to process_timing_advance for the phy_stub UE operation mode. Is this correct?
// Eliminate call to process_timing_advance for the phy_stub UE operation mode. Is this correct?
if (nfapi_mode!=3)
{
process_timing_advance(module_idP,CC_id,payload_ptr[0]);
......@@ -881,17 +881,6 @@ void ue_send_sl_sdu(module_id_t module_idP,
} else { //SL_DISCOVERY
uint16_t len = sdu_len;
LOG_I( MAC, "SL DISCOVERY \n");
// Panos: Ask TTN if we should be calling mac_rrc_data_ind_ue() instead of mac_rrc_data_ind() now!
/*mac_rrc_data_ind(module_idP,
CC_id,
frameP,subframeP,
UE_mac_inst[module_idP].crnti,
SL_DISCOVERY,
sdu, //(uint8_t*)&UE_mac_inst[Mod_id].SL_Discovery[0].Rx_buffer.Payload[0],
len,
ENB_FLAG_NO,
eNB_index,
0);*/
mac_rrc_data_ind_ue(module_idP,
CC_id,
frameP,subframeP,
......@@ -1623,7 +1612,6 @@ ue_get_sdu(module_id_t module_idP, int CC_id, frame_t frameP,
uint8_t * ulsch_buffer, uint16_t buflen, uint8_t * access_mode)
{
//LOG_I(MAC, "Panos-D: UE[%d] In ue_get_sdu() 1 \n", module_idP);
uint8_t total_rlc_pdu_header_len = 0, rlc_pdu_header_len_last = 0;
uint16_t buflen_remain = 0;
uint8_t bsr_len = 0, bsr_ce_len = 0, bsr_header_len = 0;
......@@ -1997,7 +1985,7 @@ ue_get_sdu(module_id_t module_idP, int CC_id, frame_t frameP,
// build PHR and update the timers
if (phr_ce_len == sizeof(POWER_HEADROOM_CMD)) {
if(nfapi_mode ==3){
//Panos: Substitute with a static value for the MAC layer abstraction (phy_stub mode)
//Substitute with a static value for the MAC layer abstraction (phy_stub mode)
phr_p->PH = 40;
}
else{
......@@ -2212,7 +2200,6 @@ ue_get_sdu(module_id_t module_idP, int CC_id, frame_t frameP,
buflen - sdu_length_total - payload_offset);
// cycle through SDUs and place in ulsch_buffer
if (sdu_length_total) {
//LOG_I(MAC, "Panos-D: [UE %d] ue_get_sdu() 2 before copying to ulsch_buffer, SFN/SF: %d/%d \n \n \n", module_idP, frameP, subframe);
memcpy(&ulsch_buffer[payload_offset], ulsch_buff,
sdu_length_total);
}
......@@ -2466,8 +2453,8 @@ ue_scheduler(const module_id_t module_idP,
LOG_E(MAC,
"Module id %u Contention resolution timer expired, RA failed\n",
module_idP);
if(nfapi_mode == 3) { // Panos: phy_stub mode
// Panos: Modification for phy_stub mode operation here. We only need to make sure that the ue_mode is back to
if(nfapi_mode == 3) { // phy_stub mode
// Modification for phy_stub mode operation here. We only need to make sure that the ue_mode is back to
// PRACH state.
LOG_I(MAC, "nfapi_mode3: Setting UE_mode to PRACH 2 \n");
UE_mac_inst[module_idP].UE_mode[eNB_indexP] = PRACH;
......@@ -3201,16 +3188,6 @@ SLDCH_t *ue_get_sldch(module_id_t Mod_id,int CC_id,frame_t frame_tx,sub_frame_t
//UE_MAC_INST *ue = &UE_mac_inst[Mod_id];
SLDCH_t *sldch = &UE_mac_inst[Mod_id].sldch;
// Panos: Ask TTN if we should be calling mac_rrc_data_req_ue() instead of mac_rrc_data_req() now!
/*sldch->payload_length = mac_rrc_data_req(Mod_id,
CC_id,
frame_tx,
SL_DISCOVERY,
1,
(char*)(sldch->payload), //&UE_mac_inst[Mod_id].SL_Discovery[0].Tx_buffer.Payload[0],
0,
0, //eNB_indexP
0);*/
sldch->payload_length = mac_rrc_data_req_ue(Mod_id,
CC_id,
......
......@@ -491,7 +491,6 @@ int pdcp_fifo_read_input_sdus (const protocol_ctxt_t* const ctxt_pP)
#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0))
int prose_addr_len;
char send_buf[BUFSIZE], receive_buf[BUFSIZE];
// Panos: Remove the following definitions due to warnings of unused variables.
//int optval;
int bytes_received;
sidelink_pc5s_element *sl_pc5s_msg_recv = NULL;
......
......@@ -368,19 +368,16 @@ mac_rlc_status_resp_t mac_rlc_status_ind(
} else
#endif
{
//LOG_I(RLC, "Panos-D mac_rlc_status_ind 1 enb_flagP: %d, channel_idP: %d, srb_flag: %d \n", enb_flagP, channel_idP, srb_flag);
key = RLC_COLL_KEY_LCID_VALUE(module_idP, rntiP, enb_flagP, channel_idP, srb_flag);
}
}
//LOG_I(RLC, "Panos-D mac_rlc_status_ind 2 enb_flagP: %d, channel_idP: %d, srb_flag: %d \n", enb_flagP, channel_idP, srb_flag);
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;
//LOG_D(RLC , "Panos-D: mac_rlc_status_ind() In RLC_MODE_NONE \n");
//LOG_W(RLC , "[%s] RLC not configured lcid %u module %u!\n", __FUNCTION__, channel_idP, module_idP);
//LOG_D(RLC , "[%s] RLC not configured rb id %u lcid %u module %u!\n", __FUNCTION__, rb_id, channel_idP, ue_module_idP);
}
......
......@@ -192,14 +192,14 @@ typedef struct{
}UE_MAC_BCH_indication_body_t;
// Panos: Corresponding to inputs of MAC functions: ue_send_sdu(), ue_decode_si(), ue_decode_p().
// Corresponding to inputs of MAC functions: ue_send_sdu(), ue_decode_si(), ue_decode_p().
typedef struct{
uint8_t* data;
uint16_t data_len;
}UE_MAC_dlsch_pdu;
// Panos: Corresponding to inputs of MAC function: process_rar().
// Corresponding to inputs of MAC function: process_rar().
typedef struct{
rnti_t ra_rnti;
uint8_t* rar_input_buffer; // Originating from PHY
......
This diff is collapsed.
......@@ -21,7 +21,7 @@ UL_IND_t *UL_INFO;
nfapi_tx_request_pdu_t* tx_request_pdu_list;
// New
/// Panos: Pointers to config_request types. Used from nfapi callback functions.
/// 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;
......@@ -35,7 +35,7 @@ eth_params_t stub_eth_params;
// Panos: This function should return all the sched_response config messages which concern a specific UE. Inside this
// This function should return all the sched_response config messages which concern a specific UE. Inside this
// function we should somehow make the translation of config message's rnti to Mod_ID.
Sched_Rsp_t get_nfapi_sched_response(uint8_t Mod_id);
......
......@@ -403,7 +403,6 @@ void rrc_in_sync_ind(module_id_t Mod_idP, frame_t frameP, uint16_t eNB_index)
UE_rrc_inst[Mod_idP].Info[eNB_index].N310_cnt=0;
if (UE_rrc_inst[Mod_idP].Info[eNB_index].T310_active==1) {
LOG_D(RRC, "Panos-D: rrc_in_sync_ind 1 \n");
UE_rrc_inst[Mod_idP].Info[eNB_index].N311_cnt++;
}
......
......@@ -752,7 +752,6 @@ int rrc_ue_decode_ccch( const protocol_ctxt_t* const ctxt_pP, const SRB_INFO* co
char message_string[10000];
size_t message_string_size;
//LOG_I(RRC, "Panos-D: rrc_ue_decode_ccch, Before xer_sprint() \n");
if ((message_string_size = xer_sprint(message_string, sizeof(message_string), &asn_DEF_DL_CCCH_Message, (void *)dl_ccch_msg)) > 0) {
MessageDef *msg_p;
......@@ -1943,7 +1942,6 @@ rrc_ue_process_securityModeCommand(
char message_string[20000];
size_t message_string_size;
//LOG_I(RRC, "Panos-D: rrc_ue_process_securityModeCommand, Before xer_sprint() \n");
if ((message_string_size = xer_sprint(message_string, sizeof(message_string), &asn_DEF_UL_DCCH_Message, (void *) &ul_dcch_msg)) > 0) {
MessageDef *msg_p;
......@@ -2055,7 +2053,6 @@ rrc_ue_process_ueCapabilityEnquiry(
char message_string[20000];
size_t message_string_size;
//LOG_I(RRC, "Panos-D: rrc_ue_process_ueCapabilityEnquiry, Before xer_sprint() \n");
if ((message_string_size = xer_sprint(message_string, sizeof(message_string), &asn_DEF_UL_DCCH_Message, (void *) &ul_dcch_msg)) > 0) {
MessageDef *msg_p;
......@@ -2450,7 +2447,6 @@ rrc_ue_decode_dcch(
char message_string[30000];
size_t message_string_size;
//LOG_I(RRC, "Panos-D: rrc_ue_decode_dcch, Before xer_sprint() \n");
if ((message_string_size = xer_sprint(message_string, sizeof(message_string), &asn_DEF_DL_DCCH_Message, (void *)dl_dcch_msg)) > 0) {
msg_p = itti_alloc_new_message_sized (TASK_RRC_UE, RRC_DL_DCCH, message_string_size + sizeof (IttiMsgText));
msg_p->ittiMsg.rrc_dl_dcch.size = message_string_size;
......@@ -2986,7 +2982,6 @@ int decode_BCCH_DLSCH_Message(
char message_string[15000];
size_t message_string_size;
//LOG_I(RRC, "Panos-D: decode_BCCH_DLSCH_Message, Before xer_sprint() \n");
if ((message_string_size = xer_sprint(message_string, sizeof(message_string), &asn_DEF_BCCH_DL_SCH_Message, (void *)bcch_message)) > 0) {
MessageDef *msg_p;
......@@ -3012,8 +3007,6 @@ int decode_BCCH_DLSCH_Message(
sizeof(SystemInformationBlockType1_t) );
LOG_D( RRC, "[UE %"PRIu8"] Decoding First SIB1\n", ctxt_pP->module_id );
//LOG_I( RRC, "Panos-D: decode_BCCH_DLSCH_Message1 BEFORE decode_SIB1");
//printf("Panos-D: decode_BCCH_DLSCH_Message1 BEFORE decode_SIB1");
decode_SIB1( ctxt_pP, eNB_index, rsrq, rsrp );
}
}
......@@ -3032,8 +3025,6 @@ int decode_BCCH_DLSCH_Message(
LOG_D( RRC, "[UE %"PRIu8"] Decoding SI for frameP %"PRIu32"\n",
ctxt_pP->module_id,
ctxt_pP->frame );
//LOG_I( RRC, "Panos-D: decode_BCCH_DLSCH_Message1 BEFORE OTHER decode_SI");
//printf("Panos-D: decode_BCCH_DLSCH_Message1 BEFORE OTHER decode_SI");
decode_SI( ctxt_pP, eNB_index );
//if (nfapi_mode == 3)
UE_mac_inst[ctxt_pP->module_id].SI_Decoded = 1;
......@@ -3881,12 +3872,10 @@ uint64_t arfcn_to_freq(long arfcn) {
//-----------------------------------------------------------------------------
int decode_SI( const protocol_ctxt_t* const ctxt_pP, const uint8_t eNB_index )
{
//LOG_D( RRC, "Panos-D: decode_SI 1 \n");
SystemInformation_t** si = &UE_rrc_inst[ctxt_pP->module_id].si[eNB_index];
int new_sib = 0;
SystemInformationBlockType1_t* sib1 = UE_rrc_inst[ctxt_pP->module_id].sib1[eNB_index];
//LOG_D( RRC, "Panos-D: decode_SI 2 \n");
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_RRC_UE_DECODE_SI, VCD_FUNCTION_IN );
// Dump contents
......@@ -3895,20 +3884,16 @@ uint64_t arfcn_to_freq(long arfcn) {
LOG_D( RRC, "[UE] (*si)->criticalExtensions.choice.systemInformation_r8.sib_TypeAndInfo.list.count %d\n",
(*si)->criticalExtensions.choice.systemInformation_r8.sib_TypeAndInfo.list.count );
} else {
//LOG_D( RRC, "Panos-D: decode_SI 2.3 \n");
LOG_D( RRC, "[UE] Unknown criticalExtension version (not Rel8)\n" );
return -1;
}
LOG_D( RRC, "Panos-D: decode_SI 3 \n");
for (int i=0; i<(*si)->criticalExtensions.choice.systemInformation_r8.sib_TypeAndInfo.list.count; i++) {
//LOG_I( RRC, "Panos-D: SI count %d\n", i );
struct SystemInformation_r8_IEs__sib_TypeAndInfo__Member *typeandinfo;
typeandinfo = (*si)->criticalExtensions.choice.systemInformation_r8.sib_TypeAndInfo.list.array[i];
switch(typeandinfo->present) {
case SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib2:
//LOG_D( RRC, "Panos-D: decode_SI 4 \n");
if ((UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].SIStatus&2) == 0) {
UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].SIStatus|=2;
new_sib=1;
......@@ -3998,7 +3983,6 @@ uint64_t arfcn_to_freq(long arfcn) {
break; // case SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib2
case SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib3:
//LOG_D( RRC, "Panos-D: decode_SI 5 \n");
if ((UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].SIStatus&4) == 0) {
UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].SIStatus|=4;
new_sib=1;
......
......@@ -422,11 +422,13 @@ static void* eNB_thread_rxtx( void* param ) {
exit_fun( "ERROR pthread_cond_signal" );
}
pthread_mutex_unlock( &proc->mutex_rxtx );
if(get_nprocs() >= 8) wakeup_tx(eNB,eNB->proc.ru_proc);
else
{
phy_procedures_eNB_TX(eNB, proc, 1);
wakeup_txfh(proc,eNB->proc.ru_proc);
if (nfapi_mode!=2){
if(get_nprocs() >= 8) wakeup_tx(eNB,eNB->proc.ru_proc);
else
{
phy_procedures_eNB_TX(eNB, proc, 1);
wakeup_txfh(proc,eNB->proc.ru_proc);
}
}
} // while !oai_exit
......@@ -962,7 +964,7 @@ void init_eNB_proc(int inst) {
//pthread_create( &proc_rxtx[0].pthread_rxtx, attr0, eNB_thread_rxtx, proc_rxtx );
// Panos: Should we also include here the case where single_thread_flag = 1 ?
//Should we also include here the case where single_thread_flag = 1 ?
if(nfapi_mode!=2){
pthread_create( &proc_rxtx[0].pthread_rxtx, attr0, eNB_thread_rxtx, proc );
pthread_create( &proc_rxtx[1].pthread_rxtx, attr1, tx_thread, proc);
......
This diff is collapsed.
......@@ -827,7 +827,7 @@ int main( int argc, char **argv )
printf("NFAPI_MODE value: %d \n", nfapi_mode);
// Panos: Not sure if the following is needed here
// Not sure if the following is needed here
/*if (CONFIG_ISFLAGSET(CONFIG_ABORT)) {
if (UE_flag == 0) {
fprintf(stderr,"Getting configuration failed\n");
......@@ -938,29 +938,6 @@ int main( int argc, char **argv )
printf("Before CC \n");
// Panos: From old version
/*if (UE_flag==1) {
PHY_vars_UE_g = malloc(sizeof(PHY_VARS_UE**)*NB_UE_INST);
for (int i=0; i<NB_UE_INST; i++) {
for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
PHY_vars_UE_g[i] = malloc(sizeof(PHY_VARS_UE*)*MAX_NUM_CCs);
PHY_vars_UE_g[i][CC_id] = init_ue_vars(frame_parms[CC_id], i,abstraction_flag);
UE[CC_id] = PHY_vars_UE_g[i][CC_id];
printf("PHY_vars_UE_g[inst][%d] = %p\n",CC_id,UE[CC_id]);
if (phy_test==1)
UE[CC_id]->mac_enabled = 0;
else
UE[CC_id]->mac_enabled = 1;
}
}
}*/
//NB_UE_INST=1;
NB_INST=1;
if(nfapi_mode == 3){
......@@ -1093,7 +1070,7 @@ int main( int argc, char **argv )
printf("cannot create ITTI tasks\n");
exit(-1); // need a softer mode
}
if(nfapi_mode==3){ //Panos: Here we should add another nfapi_mode for the case of Supervised LTE-D2D
if(nfapi_mode==3){ // Here we should add another nfapi_mode for the case of Supervised LTE-D2D
UE_config_stub_pnf();
}
printf("ITTI tasks created\n");
......@@ -1101,7 +1078,7 @@ int main( int argc, char **argv )
// init UE_PF_PO and mutex lock
pthread_mutex_init(&ue_pf_po_mutex, NULL);
memset (&UE_PF_PO[0][0], 0, sizeof(UE_PF_PO_t)*NUMBER_OF_UE_MAX*MAX_NUM_CCs);
memset (&UE_PF_PO[0][0], 0, sizeof(UE_PF_PO_t)*MAX_MOBILES_PER_ENB*MAX_NUM_CCs);
mlockall(MCL_CURRENT | MCL_FUTURE);
......@@ -1144,7 +1121,7 @@ int main( int argc, char **argv )
{
config_sync_var=0;
wait_nfapi_init("main?");
//Panos: Temporarily we will be using single set of threads for multiple UEs.
// 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);
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment