Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
O
OpenXG UE
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
OpenXG
OpenXG UE
Commits
5e376039
Commit
5e376039
authored
Jun 01, 2018
by
Hongzhi Wang
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
UE adding nr_init
parent
cd68b730
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
118 additions
and
645 deletions
+118
-645
cmake_targets/CMakeLists.txt
cmake_targets/CMakeLists.txt
+1
-0
targets/RT/USER/nr-ue.c
targets/RT/USER/nr-ue.c
+29
-0
targets/RT/USER/nr-uesoftmodem.c
targets/RT/USER/nr-uesoftmodem.c
+88
-645
No files found.
cmake_targets/CMakeLists.txt
View file @
5e376039
...
...
@@ -1285,6 +1285,7 @@ set(PHY_SRC_UE
${
OPENAIR1_DIR
}
/PHY/TOOLS/sqrt.c
${
OPENAIR1_DIR
}
/PHY/TOOLS/time_meas.c
${
OPENAIR1_DIR
}
/PHY/TOOLS/lut.c
${
OPENAIR1_DIR
}
/PHY/INIT/nr_init_ue.c
)
...
...
targets/RT/USER/nr-ue.c
View file @
5e376039
...
...
@@ -135,6 +135,31 @@ static const eutra_band_t eutra_bands[] = {
{
44
,
703
*
MHz
,
803
*
MHz
,
703
*
MHz
,
803
*
MHz
,
TDD
},
};
PHY_VARS_NR_UE
*
init_nr_ue_vars
(
NR_DL_FRAME_PARMS
*
frame_parms
,
uint8_t
UE_id
,
uint8_t
abstraction_flag
)
{
PHY_VARS_NR_UE
*
ue
;
if
(
frame_parms
!=
(
NR_DL_FRAME_PARMS
*
)
NULL
)
{
// if we want to give initial frame parms, allocate the PHY_VARS_UE structure and put them in
ue
=
(
PHY_VARS_NR_UE
*
)
malloc
(
sizeof
(
PHY_VARS_NR_UE
));
memset
(
ue
,
0
,
sizeof
(
PHY_VARS_NR_UE
));
memcpy
(
&
(
ue
->
frame_parms
),
frame_parms
,
sizeof
(
NR_DL_FRAME_PARMS
));
}
else
ue
=
PHY_vars_UE_g
[
UE_id
][
0
];
ue
->
Mod_id
=
UE_id
;
ue
->
mac_enabled
=
1
;
// initialize all signal buffers
init_nr_ue_signal
(
ue
,
1
,
abstraction_flag
);
// intialize transport
//init_nr_ue_transport(ue,abstraction_flag);
return
(
ue
);
}
void
init_thread
(
int
sched_runtime
,
int
sched_deadline
,
int
sched_fifo
,
cpu_set_t
*
cpuset
,
char
*
name
)
{
#ifdef DEADLINE_SCHEDULER
...
...
@@ -190,6 +215,10 @@ void init_UE(int nb_inst)
for
(
inst
=
0
;
inst
<
nb_inst
;
inst
++
)
{
// UE->rfdevice.type = NONE_DEV;
PHY_VARS_NR_UE
*
UE
=
PHY_vars_UE_g
[
inst
][
0
];
LOG_I
(
PHY
,
"Initializing memory for UE instance %d (%p)
\n
"
,
inst
,
PHY_vars_UE_g
[
inst
]);
PHY_vars_UE_g
[
inst
][
0
]
=
init_nr_ue_vars
(
NULL
,
inst
,
0
);
AssertFatal
(
0
==
pthread_create
(
&
UE
->
proc
.
pthread_ue
,
&
UE
->
proc
.
attr_ue
,
UE_thread
,
...
...
targets/RT/USER/nr-uesoftmodem.c
View file @
5e376039
...
...
@@ -399,10 +399,8 @@ void exit_fun(const char* s) {
sleep
(
1
);
//allow lte-softmodem threads to exit first
itti_terminate_tasks
(
TASK_UNKNOWN
);
#endif
}
#ifdef XFORMS
...
...
@@ -453,10 +451,7 @@ static void *scope_thread(void *arg) {
# ifdef ENABLE_XFORMS_WRITE_STATS
if
(
UE_flag
==
1
)
UE_stats
=
fopen
(
"UE_stats.txt"
,
"w"
);
else
eNB_stats
=
fopen
(
"eNB_stats.txt"
,
"w"
);
UE_stats
=
fopen
(
"UE_stats.txt"
,
"w"
);
#endif
...
...
@@ -483,13 +478,11 @@ static void *scope_thread(void *arg) {
# ifdef ENABLE_XFORMS_WRITE_STATS
if
(
UE_flag
==
1
)
{
if
(
UE_stats
)
{
rewind
(
UE_stats
);
fwrite
(
stats_buffer
,
1
,
len
,
UE_stats
);
fclose
(
UE_stats
);
}
}
# endif
...
...
@@ -508,46 +501,13 @@ void *l2l1_task(void *arg) {
itti_set_task_real_time
(
TASK_L2L1
);
itti_mark_task_ready
(
TASK_L2L1
);
if
(
UE_flag
==
0
)
{
/* Wait for the initialize message */
printf
(
"Wait for the ITTI initialize message
\n
"
);
do
{
if
(
message_p
!=
NULL
)
{
result
=
itti_free
(
ITTI_MSG_ORIGIN_ID
(
message_p
),
message_p
);
AssertFatal
(
result
==
EXIT_SUCCESS
,
"Failed to free memory (%d)!
\n
"
,
result
);
}
itti_receive_msg
(
TASK_L2L1
,
&
message_p
);
switch
(
ITTI_MSG_ID
(
message_p
))
{
case
INITIALIZE_MESSAGE
:
/* Start eNB thread */
LOG_D
(
EMU
,
"L2L1 TASK received %s
\n
"
,
ITTI_MSG_NAME
(
message_p
));
start_eNB
=
1
;
break
;
do
{
// Wait for a message
itti_receive_msg
(
TASK_L2L1
,
&
message_p
);
case
TERMINATE_MESSAGE
:
printf
(
"received terminate message
\n
"
);
oai_exit
=
1
;
itti_exit_task
();
break
;
default:
LOG_E
(
EMU
,
"Received unexpected message %s
\n
"
,
ITTI_MSG_NAME
(
message_p
));
break
;
}
}
while
(
ITTI_MSG_ID
(
message_p
)
!=
INITIALIZE_MESSAGE
);
result
=
itti_free
(
ITTI_MSG_ORIGIN_ID
(
message_p
),
message_p
);
AssertFatal
(
result
==
EXIT_SUCCESS
,
"Failed to free memory (%d)!
\n
"
,
result
);
}
do
{
// Wait for a message
itti_receive_msg
(
TASK_L2L1
,
&
message_p
);
switch
(
ITTI_MSG_ID
(
message_p
))
{
case
TERMINATE_MESSAGE
:
switch
(
ITTI_MSG_ID
(
message_p
))
{
case
TERMINATE_MESSAGE
:
oai_exit
=
1
;
itti_exit_task
();
break
;
...
...
@@ -577,7 +537,6 @@ void *l2l1_task(void *arg) {
}
#endif
extern
int16_t
dlsch_demod_shift
;
static
void
get_options
(
int
argc
,
char
**
argv
)
{
...
...
@@ -588,11 +547,12 @@ static void get_options (int argc, char **argv) {
uint32_t
online_log_messages
;
uint32_t
glog_level
,
glog_verbosity
;
uint32_t
start_telnetsrv
;
nfapi_config_request_t
*
config
[
MAX_NUM_CCs
];
paramdef_t
cmdline_params
[]
=
CMDLINE_PARAMS_DESC
;
paramdef_t
cmdline_logparams
[]
=
CMDLINE_LOGPARAMS_DESC
;
//set_default_frame_parms(
frame_parms);
set_default_frame_parms
(
config
,
frame_parms
);
config_process_cmdline
(
cmdline_params
,
sizeof
(
cmdline_params
)
/
sizeof
(
paramdef_t
),
NULL
);
if
(
strlen
(
in_path
)
>
0
)
{
...
...
@@ -652,509 +612,10 @@ static void get_options (int argc, char **argv) {
}
/* UE with config file */
int
c
;
// char line[1000];
// int l;
int
k
,
i
;
//,j,k;
#if defined(OAI_USRP) || defined(CPRIGW) || defined(OAI_ADRV9371_ZC706)
int
clock_src
;
#endif
enum
long_option_e
{
LONG_OPTION_START
=
0x100
,
/* Start after regular single char options */
LONG_OPTION_RF_CONFIG_FILE
,
LONG_OPTION_ULSCH_MAX_CONSECUTIVE_ERRORS
,
LONG_OPTION_CALIB_UE_RX
,
LONG_OPTION_CALIB_UE_RX_MED
,
LONG_OPTION_CALIB_UE_RX_BYP
,
LONG_OPTION_DEBUG_UE_PRACH
,
LONG_OPTION_NO_L2_CONNECT
,
LONG_OPTION_CALIB_PRACH_TX
,
LONG_OPTION_RXGAIN
,
LONG_OPTION_RXGAINOFF
,
LONG_OPTION_TXGAIN
,
LONG_OPTION_NBRXANT
,
LONG_OPTION_NBTXANT
,
LONG_OPTION_SCANCARRIER
,
LONG_OPTION_MAXPOWER
,
LONG_OPTION_DUMP_FRAME
,
LONG_OPTION_LOOPMEMORY
,
LONG_OPTION_PHYTEST
,
LONG_OPTION_USIMTEST
,
LONG_OPTION_MMAPPED_DMA
,
LONG_OPTION_EXTERNAL_CLOCK
,
LONG_OPTION_WAIT_FOR_SYNC
,
LONG_OPTION_SINGLE_THREAD_DISABLE
,
LONG_OPTION_THREADIQ
,
LONG_OPTION_THREADONESUBFRAME
,
LONG_OPTION_THREADTWOSUBFRAME
,
LONG_OPTION_THREADTHREESUBFRAME
,
LONG_OPTION_THREADSLOT1PROCONE
,
LONG_OPTION_THREADSLOT1PROCTWO
,
LONG_OPTION_THREADSLOT1PROCTHREE
,
LONG_OPTION_THREADDLSCHTDONE
,
LONG_OPTION_THREADDLSCHTDTWO
,
LONG_OPTION_THREADDLSCHTDTHREE
,
LONG_OPTION_THREADDLSCHTD1ONE
,
LONG_OPTION_THREADDLSCHTD1TWO
,
LONG_OPTION_THREADDLSCHTD1THREE
,
LONG_OPTION_DCIFORMAT
,
LONG_OPTION_AGREGATIONLEVEL
,
LONG_OPTION_DEMOD_SHIFT
,
#if T_TRACER
LONG_OPTION_T_PORT
,
LONG_OPTION_T_NOWAIT
,
LONG_OPTION_T_DONT_FORK
,
#endif
};
static
const
struct
option
long_options
[]
=
{
{
"rf-config-file"
,
required_argument
,
NULL
,
LONG_OPTION_RF_CONFIG_FILE
},
{
"ulsch-max-errors"
,
required_argument
,
NULL
,
LONG_OPTION_ULSCH_MAX_CONSECUTIVE_ERRORS
},
{
"calib-ue-rx"
,
required_argument
,
NULL
,
LONG_OPTION_CALIB_UE_RX
},
{
"calib-ue-rx-med"
,
required_argument
,
NULL
,
LONG_OPTION_CALIB_UE_RX_MED
},
{
"calib-ue-rx-byp"
,
required_argument
,
NULL
,
LONG_OPTION_CALIB_UE_RX_BYP
},
{
"debug-ue-prach"
,
no_argument
,
NULL
,
LONG_OPTION_DEBUG_UE_PRACH
},
{
"no-L2-connect"
,
no_argument
,
NULL
,
LONG_OPTION_NO_L2_CONNECT
},
{
"calib-prach-tx"
,
no_argument
,
NULL
,
LONG_OPTION_CALIB_PRACH_TX
},
{
"ue-rxgain"
,
required_argument
,
NULL
,
LONG_OPTION_RXGAIN
},
{
"ue-rxgain-off"
,
required_argument
,
NULL
,
LONG_OPTION_RXGAINOFF
},
{
"ue-txgain"
,
required_argument
,
NULL
,
LONG_OPTION_TXGAIN
},
{
"ue-nb-ant-rx"
,
required_argument
,
NULL
,
LONG_OPTION_NBRXANT
},
{
"ue-nb-ant-tx"
,
required_argument
,
NULL
,
LONG_OPTION_NBTXANT
},
{
"ue-scan-carrier"
,
no_argument
,
NULL
,
LONG_OPTION_SCANCARRIER
},
{
"ue-max-power"
,
required_argument
,
NULL
,
LONG_OPTION_MAXPOWER
},
{
"ue-dump-frame"
,
no_argument
,
NULL
,
LONG_OPTION_DUMP_FRAME
},
{
"loop-memory"
,
required_argument
,
NULL
,
LONG_OPTION_LOOPMEMORY
},
{
"phy-test"
,
no_argument
,
NULL
,
LONG_OPTION_PHYTEST
},
{
"usim-test"
,
no_argument
,
NULL
,
LONG_OPTION_USIMTEST
},
{
"mmapped-dma"
,
no_argument
,
NULL
,
LONG_OPTION_MMAPPED_DMA
},
{
"external-clock"
,
no_argument
,
NULL
,
LONG_OPTION_EXTERNAL_CLOCK
},
{
"wait-for-sync"
,
no_argument
,
NULL
,
LONG_OPTION_WAIT_FOR_SYNC
},
{
"single-thread-disable"
,
no_argument
,
NULL
,
LONG_OPTION_SINGLE_THREAD_DISABLE
},
{
"threadIQ"
,
required_argument
,
NULL
,
LONG_OPTION_THREADIQ
},
{
"threadOneSubframe"
,
required_argument
,
NULL
,
LONG_OPTION_THREADONESUBFRAME
},
{
"threadTwoSubframe"
,
required_argument
,
NULL
,
LONG_OPTION_THREADTWOSUBFRAME
},
{
"threadThreeSubframe"
,
required_argument
,
NULL
,
LONG_OPTION_THREADTHREESUBFRAME
},
{
"threadSlot1ProcOne"
,
required_argument
,
NULL
,
LONG_OPTION_THREADSLOT1PROCONE
},
{
"threadSlot1ProcTwo"
,
required_argument
,
NULL
,
LONG_OPTION_THREADSLOT1PROCTWO
},
{
"threadSlot1ProcThree"
,
required_argument
,
NULL
,
LONG_OPTION_THREADSLOT1PROCTHREE
},
{
"threadDlschTdOne"
,
required_argument
,
NULL
,
LONG_OPTION_THREADDLSCHTDONE
},
{
"threadDlschTdTwo"
,
required_argument
,
NULL
,
LONG_OPTION_THREADDLSCHTDTWO
},
{
"threadDlschTdThree"
,
required_argument
,
NULL
,
LONG_OPTION_THREADDLSCHTDTHREE
},
{
"threadDlschTd1One"
,
required_argument
,
NULL
,
LONG_OPTION_THREADDLSCHTD1ONE
},
{
"threadDlschTd1Two"
,
required_argument
,
NULL
,
LONG_OPTION_THREADDLSCHTD1TWO
},
{
"threadDlschTd1Three"
,
required_argument
,
NULL
,
LONG_OPTION_THREADDLSCHTD1THREE
},
{
"DCIformat"
,
required_argument
,
NULL
,
LONG_OPTION_DCIFORMAT
},
{
"AgregationLevel"
,
required_argument
,
NULL
,
LONG_OPTION_AGREGATIONLEVEL
},
{
"dlsch-demod-shift"
,
required_argument
,
NULL
,
LONG_OPTION_DEMOD_SHIFT
},
#if T_TRACER
{
"T_port"
,
required_argument
,
0
,
LONG_OPTION_T_PORT
},
{
"T_nowait"
,
no_argument
,
0
,
LONG_OPTION_T_NOWAIT
},
{
"T_dont_fork"
,
no_argument
,
0
,
LONG_OPTION_T_DONT_FORK
},
#endif
{
NULL
,
0
,
NULL
,
0
}
};
while
((
c
=
getopt_long
(
argc
,
argv
,
"A:a:C:dEK:g:F:G:hqO:m:n:SUVRM:r:P:Ws:t:Tx:"
,
long_options
,
NULL
))
!=
-
1
)
{
switch
(
c
)
{
case
LONG_OPTION_RF_CONFIG_FILE
:
if
((
strcmp
(
"null"
,
optarg
)
==
0
)
||
(
strcmp
(
"NULL"
,
optarg
)
==
0
))
{
printf
(
"no configuration filename is provided
\n
"
);
}
else
if
(
strlen
(
optarg
)
<=
1024
){
strcpy
(
rf_config_file
,
optarg
);
}
else
{
printf
(
"Configuration filename is too long
\n
"
);
exit
(
-
1
);
}
break
;
case
LONG_OPTION_MAXPOWER
:
tx_max_power
[
0
]
=
atoi
(
optarg
);
for
(
CC_id
=
1
;
CC_id
<
MAX_NUM_CCs
;
CC_id
++
)
tx_max_power
[
CC_id
]
=
tx_max_power
[
0
];
break
;
case
LONG_OPTION_ULSCH_MAX_CONSECUTIVE_ERRORS
:
ULSCH_max_consecutive_errors
=
atoi
(
optarg
);
printf
(
"Set ULSCH_max_consecutive_errors = %d
\n
"
,
ULSCH_max_consecutive_errors
);
break
;
case
LONG_OPTION_CALIB_UE_RX
:
mode
=
rx_calib_ue
;
rx_input_level_dBm
=
atoi
(
optarg
);
printf
(
"Running with UE calibration on (LNA max), input level %d dBm
\n
"
,
rx_input_level_dBm
);
break
;
case
LONG_OPTION_CALIB_UE_RX_MED
:
mode
=
rx_calib_ue_med
;
rx_input_level_dBm
=
atoi
(
optarg
);
printf
(
"Running with UE calibration on (LNA med), input level %d dBm
\n
"
,
rx_input_level_dBm
);
break
;
case
LONG_OPTION_CALIB_UE_RX_BYP
:
mode
=
rx_calib_ue_byp
;
rx_input_level_dBm
=
atoi
(
optarg
);
printf
(
"Running with UE calibration on (LNA byp), input level %d dBm
\n
"
,
rx_input_level_dBm
);
break
;
case
LONG_OPTION_DEBUG_UE_PRACH
:
mode
=
debug_prach
;
break
;
case
LONG_OPTION_NO_L2_CONNECT
:
mode
=
no_L2_connect
;
break
;
case
LONG_OPTION_CALIB_PRACH_TX
:
mode
=
calib_prach_tx
;
printf
(
"Setting mode to calib_prach_tx (%d)
\n
"
,
mode
);
break
;
case
LONG_OPTION_RXGAIN
:
for
(
i
=
0
;
i
<
4
;
i
++
)
rx_gain
[
0
][
i
]
=
atof
(
optarg
);
break
;
case
LONG_OPTION_RXGAINOFF
:
rx_gain_off
=
atof
(
optarg
);
break
;
case
LONG_OPTION_TXGAIN
:
for
(
i
=
0
;
i
<
4
;
i
++
)
tx_gain
[
0
][
i
]
=
atof
(
optarg
);
break
;
case
LONG_OPTION_NBRXANT
:
nb_antenna_rx
=
atof
(
optarg
);
break
;
case
LONG_OPTION_NBTXANT
:
nb_antenna_tx
=
atof
(
optarg
);
break
;
case
LONG_OPTION_SCANCARRIER
:
UE_scan_carrier
=
1
;
break
;
case
LONG_OPTION_LOOPMEMORY
:
mode
=
loop_through_memory
;
input_fd
=
fopen
(
optarg
,
"r"
);
AssertFatal
(
input_fd
!=
NULL
,
"Please provide an input file
\n
"
);
break
;
case
LONG_OPTION_DUMP_FRAME
:
mode
=
rx_dump_frame
;
break
;
case
LONG_OPTION_PHYTEST
:
phy_test
=
1
;
break
;
case
LONG_OPTION_USIMTEST
:
usim_test
=
1
;
break
;
case
LONG_OPTION_MMAPPED_DMA
:
mmapped_dma
=
1
;
break
;
case
LONG_OPTION_SINGLE_THREAD_DISABLE
:
single_thread_flag
=
0
;
break
;
case
LONG_OPTION_EXTERNAL_CLOCK
:
clock_source
=
external
;
break
;
case
LONG_OPTION_WAIT_FOR_SYNC
:
wait_for_sync
=
1
;
break
;
case
LONG_OPTION_THREADIQ
:
threads
.
iq
=
atoi
(
optarg
);
break
;
case
LONG_OPTION_THREADONESUBFRAME
:
threads
.
one
=
atoi
(
optarg
);
break
;
case
LONG_OPTION_THREADTWOSUBFRAME
:
threads
.
two
=
atoi
(
optarg
);
break
;
case
LONG_OPTION_THREADTHREESUBFRAME
:
threads
.
three
=
atoi
(
optarg
);
break
;
case
LONG_OPTION_THREADSLOT1PROCONE
:
threads
.
slot1_proc_one
=
atoi
(
optarg
);
break
;
case
LONG_OPTION_THREADSLOT1PROCTWO
:
threads
.
slot1_proc_two
=
atoi
(
optarg
);
break
;
case
LONG_OPTION_THREADSLOT1PROCTHREE
:
threads
.
slot1_proc_three
=
atoi
(
optarg
);
break
;
case
LONG_OPTION_THREADDLSCHTDONE
:
threads
.
dlsch_td_one
=
atoi
(
optarg
);
break
;
case
LONG_OPTION_THREADDLSCHTDTWO
:
threads
.
dlsch_td_two
=
atoi
(
optarg
);
break
;
case
LONG_OPTION_THREADDLSCHTDTHREE
:
threads
.
dlsch_td_three
=
atoi
(
optarg
);
break
;
case
LONG_OPTION_THREADDLSCHTD1ONE
:
threads
.
dlsch_td1_one
=
atoi
(
optarg
);
break
;
case
LONG_OPTION_THREADDLSCHTD1TWO
:
threads
.
dlsch_td1_two
=
atoi
(
optarg
);
break
;
case
LONG_OPTION_THREADDLSCHTD1THREE
:
threads
.
dlsch_td1_three
=
atoi
(
optarg
);
break
;
case
LONG_OPTION_DCIFORMAT
:
dci_Format
=
atoi
(
optarg
);
break
;
case
LONG_OPTION_AGREGATIONLEVEL
:
agregation_Level
=
atoi
(
optarg
);
break
;
case
LONG_OPTION_DEMOD_SHIFT
:
{
extern
int16_t
dlsch_demod_shift
;
dlsch_demod_shift
=
atof
(
optarg
);
break
;
}
#if T_TRACER
case
LONG_OPTION_T_PORT
:
{
extern
int
T_port
;
if
(
optarg
==
NULL
)
abort
();
/* should not happen */
T_port
=
atoi
(
optarg
);
break
;
}
case
LONG_OPTION_T_NOWAIT
:
{
extern
int
T_wait
;
T_wait
=
0
;
break
;
}
case
LONG_OPTION_T_DONT_FORK
:
{
extern
int
T_dont_fork
;
T_dont_fork
=
1
;
break
;
}
#endif
case
'A'
:
timing_advance
=
atoi
(
optarg
);
break
;
case
'C'
:
for
(
CC_id
=
0
;
CC_id
<
MAX_NUM_CCs
;
CC_id
++
)
{
downlink_frequency
[
CC_id
][
0
]
=
atof
(
optarg
);
// Use float to avoid issue with frequency over 2^31.
downlink_frequency
[
CC_id
][
1
]
=
downlink_frequency
[
CC_id
][
0
];
downlink_frequency
[
CC_id
][
2
]
=
downlink_frequency
[
CC_id
][
0
];
downlink_frequency
[
CC_id
][
3
]
=
downlink_frequency
[
CC_id
][
0
];
printf
(
"Downlink for CC_id %d frequency set to %u
\n
"
,
CC_id
,
downlink_frequency
[
CC_id
][
0
]);
}
UE_scan
=
0
;
break
;
case
'a'
:
chain_offset
=
atoi
(
optarg
);
break
;
case
'd'
:
#ifdef XFORMS
do_forms
=
1
;
printf
(
"Running with XFORMS!
\n
"
);
#endif
break
;
case
'E'
:
threequarter_fs
=
1
;
break
;
case
'K'
:
#if defined(ENABLE_ITTI)
itti_dump_file
=
strdup
(
optarg
);
#else
printf
(
"-K option is disabled when ENABLE_ITTI is not defined
\n
"
);
#endif
break
;
case
'O'
:
conf_config_file_name
=
optarg
;
break
;
case
'U'
:
UE_flag
=
1
;
break
;
case
'm'
:
target_dl_mcs
=
atoi
(
optarg
);
break
;
case
't'
:
target_ul_mcs
=
atoi
(
optarg
);
break
;
case
'W'
:
opt_enabled
=
1
;
opt_type
=
OPT_WIRESHARK
;
strncpy
(
in_ip
,
"127.0.0.1"
,
sizeof
(
in_ip
));
in_ip
[
sizeof
(
in_ip
)
-
1
]
=
0
;
// terminate string
printf
(
"Enabling OPT for wireshark for local interface"
);
/*
if (optarg == NULL){
in_ip[0] =NULL;
printf("Enabling OPT for wireshark for local interface");
} else {
strncpy(in_ip, optarg, sizeof(in_ip));
in_ip[sizeof(in_ip) - 1] = 0; // terminate string
printf("Enabling OPT for wireshark with %s \n",in_ip);
}
*/
break
;
case
'P'
:
opt_type
=
OPT_PCAP
;
opt_enabled
=
1
;
if
(
optarg
==
NULL
)
{
strncpy
(
in_path
,
"/tmp/oai_opt.pcap"
,
sizeof
(
in_path
));
in_path
[
sizeof
(
in_path
)
-
1
]
=
0
;
// terminate string
printf
(
"Enabling OPT for PCAP with the following path /tmp/oai_opt.pcap"
);
}
else
{
strncpy
(
in_path
,
optarg
,
sizeof
(
in_path
));
in_path
[
sizeof
(
in_path
)
-
1
]
=
0
;
// terminate string
printf
(
"Enabling OPT for PCAP with the following file %s
\n
"
,
in_path
);
}
break
;
case
'V'
:
ouput_vcd
=
1
;
break
;
case
'q'
:
opp_enabled
=
1
;
break
;
case
'R'
:
online_log_messages
=
1
;
break
;
/*case 'r':
UE_scan = 0;
for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
switch(atoi(optarg)) {
case 6:
frame_parms[CC_id]->N_RB_DL=6;
frame_parms[CC_id]->N_RB_UL=6;
break;
case 25:
frame_parms[CC_id]->N_RB_DL=25;
frame_parms[CC_id]->N_RB_UL=25;
break;
case 50:
frame_parms[CC_id]->N_RB_DL=50;
frame_parms[CC_id]->N_RB_UL=50;
break;
case 100:
frame_parms[CC_id]->N_RB_DL=100;
frame_parms[CC_id]->N_RB_UL=100;
break;
default:
printf("Unknown N_RB_DL %d, switching to 25\n",atoi(optarg));
break;
}
}
break;*/
case
's'
:
#if defined(OAI_USRP) || defined(CPRIGW) || defined(OAI_ADRV9371_ZC706)
clock_src
=
atoi
(
optarg
);
if
(
clock_src
==
0
)
{
// char ref[128] = "internal";
//strncpy(uhd_ref, ref, strlen(ref)+1);
}
else
if
(
clock_src
==
1
)
{
//char ref[128] = "external";
//strncpy(uhd_ref, ref, strlen(ref)+1);
}
#else
printf
(
"Note: -s not defined for ExpressMIMO2
\n
"
);
#endif
break
;
case
'S'
:
exit_missed_slots
=
0
;
printf
(
"Skip exit for missed slots
\n
"
);
break
;
case
'g'
:
glog_level
=
atoi
(
optarg
);
// value between 1 - 9
break
;
case
'F'
:
break
;
case
'G'
:
glog_verbosity
=
atoi
(
optarg
);
// value from 0, 0x5, 0x15, 0x35, 0x75
break
;
case
'x'
:
printf
(
"Transmission mode should be set in config file now
\n
"
);
exit
(
-
1
);
/*
transmission_mode = atoi(optarg);
if (transmission_mode > 7) {
printf("Transmission mode %d not supported for the moment\n",transmission_mode);
exit(-1);
}
*/
break
;
case
'T'
:
for
(
CC_id
=
0
;
CC_id
<
MAX_NUM_CCs
;
CC_id
++
)
frame_parms
[
CC_id
]
->
frame_type
=
TDD
;
break
;
case
'n'
:
numerology
=
atoi
(
optarg
);
break
;
case
'h'
:
help
();
exit
(
-
1
);
default:
help
();
exit
(
-
1
);
break
;
}
}
if
(
UE_flag
==
0
)
AssertFatal
(
conf_config_file_name
!=
NULL
,
"Please provide a configuration file
\n
"
);
if
(
UE_flag
==
1
)
{
if
(
conf_config_file_name
!=
NULL
)
{
// Here the configuration file is the XER encoded UE capabilities
// Read it in and store in asn1c data structures
strcpy
(
uecap_xer
,
conf_config_file_name
);
uecap_xer_in
=
1
;
}
}
}
#if T_TRACER
...
...
@@ -1163,11 +624,11 @@ int T_port = 2021; /* default port to listen to to wait for the tracer */
int
T_dont_fork
=
0
;
/* default is to fork, see 'T_init' to understand */
#endif
void
set_default_frame_parms
(
nfapi_config_request_t
*
config
[
MAX_NUM_CCs
],
NR_DL_FRAME_PARMS
*
frame_parms
[
MAX_NUM_CCs
])
{
void
set_default_frame_parms
(
nfapi_config_request_t
*
config
[
MAX_NUM_CCs
],
NR_DL_FRAME_PARMS
*
frame_parms
[
MAX_NUM_CCs
])
{
int
CC_id
;
int
CC_id
;
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
]
=
(
NR_DL_FRAME_PARMS
*
)
malloc
(
sizeof
(
NR_DL_FRAME_PARMS
));
/* Set some default values that may be overwritten while reading options */
frame_parms
[
CC_id
]
=
(
NR_DL_FRAME_PARMS
*
)
malloc
(
sizeof
(
NR_DL_FRAME_PARMS
));
...
...
@@ -1181,7 +642,7 @@ void set_default_frame_parms(nfapi_config_request_t *config[MAX_NUM_CCs], NR_DL_
config
[
CC_id
]
->
rf_config
.
rx_antenna_ports
.
value
=
1
;
config
[
CC_id
]
->
sch_config
.
physical_cell_id
.
value
=
0
;
/*frame_parms[CC_id]->frame_type = FDD;
/*frame_parms[CC_id]->frame_type = FDD;
frame_parms[CC_id]->tdd_config = 3;
frame_parms[CC_id]->tdd_config_S = 0;
frame_parms[CC_id]->N_RB_DL = 100;
...
...
@@ -1198,7 +659,7 @@ void set_default_frame_parms(nfapi_config_request_t *config[MAX_NUM_CCs], NR_DL_
///frame_parms[CC_id]->phich_config_common.phich_resource = oneSixth;
//frame_parms[CC_id]->phich_config_common.phich_duration = normal;
// UL RS Config
// UL RS Config
/*frame_parms[CC_id]->pusch_config_common.ul_ReferenceSignalsPUSCH.cyclicShift = 1;//n_DMRS1 set to 0
frame_parms[CC_id]->pusch_config_common.ul_ReferenceSignalsPUSCH.groupHoppingEnabled = 1;
frame_parms[CC_id]->pusch_config_common.ul_ReferenceSignalsPUSCH.sequenceHoppingEnabled = 0;
...
...
@@ -1229,7 +690,7 @@ void set_default_frame_parms(nfapi_config_request_t *config[MAX_NUM_CCs], NR_DL_
}
}
/*
void init_openair0(void);
void
init_openair0
(
void
);
void
init_openair0
()
{
int
card
;
...
...
@@ -1329,7 +790,7 @@ void init_openair0() {
}
}
*/
}
int
main
(
int
argc
,
char
**
argv
)
{
int
i
,
j
,
k
,
aa
,
re
;
...
...
@@ -1356,6 +817,8 @@ int main( int argc, char **argv ) {
#endif
PHY_VARS_NR_UE
*
UE
[
MAX_NUM_CCs
];
UE
[
0
]
=
malloc
(
sizeof
(
PHY_VARS_NR_UE
*
));
//UE[1] = (PHY_VARS_NR_UE *)malloc(sizeof(PHY_VARS_NR_UE));
mode
=
normal_txrx
;
memset
(
&
openair0_cfg
[
0
],
0
,
sizeof
(
openair0_config_t
)
*
MAX_CARDS
);
...
...
@@ -1378,7 +841,7 @@ int main( int argc, char **argv ) {
#endif
// initialize the log (see log.h for details)
set_glog
(
glog_level
,
glog_verbosity
);
//
set_glog(glog_level, glog_verbosity);
//randominit (0);
set_taus_seed
(
0
);
...
...
@@ -1453,7 +916,7 @@ int main( int argc, char **argv ) {
#endif
check_clock
();
check_clock
();
#ifndef PACKAGE_VERSION
# define PACKAGE_VERSION "UNKNOWN-EXPERIMENTAL"
...
...
@@ -1464,13 +927,13 @@ int main( int argc, char **argv ) {
// init the parameters
for
(
CC_id
=
0
;
CC_id
<
MAX_NUM_CCs
;
CC_id
++
)
{
if
(
UE_flag
==
1
)
{
frame_parms
[
CC_id
]
->
nb_antennas_tx
=
nb_antenna_tx
;
frame_parms
[
CC_id
]
->
nb_antennas_rx
=
nb_antenna_rx
;
frame_parms
[
CC_id
]
->
nb_antenna_ports_eNB
=
1
;
//initial value overwritten by initial sync later
LOG_I
(
PHY
,
"Set nb_rx_antenna %d , nb_tx_antenna %d
\n
"
,
frame_parms
[
CC_id
]
->
nb_antennas_rx
,
frame_parms
[
CC_id
]
->
nb_antennas_tx
);
}
//init_ul_hopping(frame_parms[CC_id]);
//nr_init_frame_parms(frame_parms[CC_id],1);
...
...
@@ -1480,27 +943,28 @@ int main( int argc, char **argv ) {
for
(
CC_id
=
0
;
CC_id
<
MAX_NUM_CCs
;
CC_id
++
)
{
for
(
CC_id
=
0
;
CC_id
<
MAX_NUM_CCs
;
CC_id
++
)
{
//init prach for openair1 test
// prach_fmt = get_prach_fmt(frame_parms->prach_config_common.prach_ConfigInfo.prach_ConfigIndex, frame_parms->frame_type);
// N_ZC = (prach_fmt <4)?839:139;
}
if
(
UE_flag
==
1
)
{
NB_UE_INST
=
1
;
/*NB_UE_INST=1;
NB_INST=1;
PHY_vars_UE_g = malloc(sizeof(PHY_VARS_NR_UE**));
PHY_vars_UE_g
[
0
]
=
malloc
(
sizeof
(
PHY_VARS_NR_UE
*
)
*
MAX_NUM_CCs
);
PHY_vars_UE_g[0] = malloc(sizeof(PHY_VARS_NR_UE*)*MAX_NUM_CCs);
*/
for
(
CC_id
=
0
;
CC_id
<
MAX_NUM_CCs
;
CC_id
++
)
{
NB_UE_INST
=
1
;
NB_INST
=
1
;
PHY_vars_UE_g
=
malloc
(
sizeof
(
PHY_VARS_NR_UE
**
));
PHY_vars_UE_g
[
0
]
=
malloc
(
sizeof
(
PHY_VARS_NR_UE
*
)
*
MAX_NUM_CCs
);
//PHY_vars_UE_g[0][CC_id] = init_lte_UE(frame_parms[CC_id], 0,abstraction_flag);
UE
[
CC_id
]
=
PHY_vars_UE_g
[
0
][
CC_id
];
printf
(
"PHY_vars_UE_g[0][%d] = %p
\n
"
,
CC_id
,
UE
[
CC_id
]);
PHY_vars_UE_g
[
0
][
CC_id
]
=
init_nr_ue_vars
(
frame_parms
[
CC_id
],
0
,
abstraction_flag
);
UE
[
CC_id
]
=
PHY_vars_UE_g
[
0
][
CC_id
];
if
(
phy_test
==
1
)
UE
[
CC_id
]
->
mac_enabled
=
0
;
else
...
...
@@ -1508,24 +972,28 @@ int main( int argc, char **argv ) {
if
(
UE
[
CC_id
]
->
mac_enabled
==
0
)
{
//set default UL parameters for testing mode
for
(
i
=
0
;
i
<
NUMBER_OF_CONNECTED_eNB_MAX
;
i
++
)
{
UE
[
CC_id
]
->
pusch_config_dedicated
[
i
].
betaOffset_ACK_Index
=
beta_ACK
;
//UE[CC_id]->pusch_config_dedicated[i] = malloc(sizeof(PUSCH_CONFIG_DEDICATED));
//UE[CC_id]->scheduling_request_config[i] = malloc(sizeof(SCHEDULING_REQUEST_CONFIG));
/*UE[CC_id]->pusch_config_dedicated[i].betaOffset_ACK_Index = beta_ACK;
UE[CC_id]->pusch_config_dedicated[i].betaOffset_RI_Index = beta_RI;
UE[CC_id]->pusch_config_dedicated[i].betaOffset_CQI_Index = beta_CQI;
UE[CC_id]->scheduling_request_config[i].sr_PUCCH_ResourceIndex = 0;
UE[CC_id]->scheduling_request_config[i].sr_ConfigIndex = 7+(0%3);
UE
[
CC_id
]
->
scheduling_request_config
[
i
].
dsr_TransMax
=
sr_n4
;
UE[CC_id]->scheduling_request_config[i].dsr_TransMax = sr_n4;
*/
}
}
UE
[
CC_id
]
->
UE_scan
=
UE_scan
;
UE
[
CC_id
]
->
UE_scan_carrier
=
UE_scan_carrier
;
UE
[
CC_id
]
->
mode
=
mode
;
printf
(
"UE[%d]->mode = %d
\n
"
,
CC_id
,
mode
);
//
printf("UE[%d]->mode = %d\n",CC_id,mode);
for
(
uint8_t
i
=
0
;
i
<
RX_NB_TH_MAX
;
i
++
)
{
UE
[
CC_id
]
->
pdcch_vars
[
i
][
0
]
->
agregationLevel
=
agregation_Level
;
UE
[
CC_id
]
->
pdcch_vars
[
i
][
0
]
->
dciFormat
=
dci_Format
;
//
UE[CC_id]->pdcch_vars[i][0]->agregationLevel = agregation_Level;
//
UE[CC_id]->pdcch_vars[i][0]->dciFormat = dci_Format;
}
/*compute_prach_seq(&UE[CC_id]->frame_parms.prach_config_common,
...
...
@@ -1534,17 +1002,17 @@ int main( int argc, char **argv ) {
if
(
UE
[
CC_id
]
->
mac_enabled
==
1
)
{
UE
[
CC_id
]
->
pdcch_vars
[
0
][
0
]
->
crnti
=
0x1234
;
UE
[
CC_id
]
->
pdcch_vars
[
1
][
0
]
->
crnti
=
0x1234
;
//
UE[CC_id]->pdcch_vars[0][0]->crnti = 0x1234;
//
UE[CC_id]->pdcch_vars[1][0]->crnti = 0x1234;
}
else
{
UE
[
CC_id
]
->
pdcch_vars
[
0
][
0
]
->
crnti
=
0x1235
;
UE
[
CC_id
]
->
pdcch_vars
[
1
][
0
]
->
crnti
=
0x1235
;
//
UE[CC_id]->pdcch_vars[0][0]->crnti = 0x1235;
//
UE[CC_id]->pdcch_vars[1][0]->crnti = 0x1235;
}
UE
[
CC_id
]
->
rx_total_gain_dB
=
(
int
)
rx_gain
[
CC_id
][
0
]
+
rx_gain_off
;
UE
[
CC_id
]
->
tx_power_max_dBm
=
tx_max_power
[
CC_id
];
//
UE[CC_id]->rx_total_gain_dB = (int)rx_gain[CC_id][0] + rx_gain_off;
//
UE[CC_id]->tx_power_max_dBm = tx_max_power[CC_id];
if
(
frame_parms
[
CC_id
]
->
frame_type
==
FDD
)
{
UE
[
CC_id
]
->
N_TA_offset
=
0
;
...
...
@@ -1560,7 +1028,7 @@ int main( int argc, char **argv ) {
}
// printf("tx_max_power = %d -> amp %d\n",tx_max_power,get_tx_amp(tx_max_poHwer,tx_max_power));
}
fill_modeled_runtime_table
(
runtime_phy_rx
,
runtime_phy_tx
);
cpuf
=
get_cpu_freq_GHz
();
...
...
@@ -1592,28 +1060,24 @@ int main( int argc, char **argv ) {
}
#endif
/* Check the actual affinity mask assigned to the thread */
s
=
pthread_getaffinity_np
(
pthread_self
(),
sizeof
(
cpu_set_t
),
&
cpuset
);
if
(
s
!=
0
)
{
perror
(
"pthread_getaffinity_np"
);
exit_fun
(
"Error getting processor affinity "
);
}
memset
(
cpu_affinity
,
0
,
sizeof
(
cpu_affinity
));
for
(
int
j
=
0
;
j
<
CPU_SETSIZE
;
j
++
)
{
if
(
CPU_ISSET
(
j
,
&
cpuset
))
{
char
temp
[
1024
];
sprintf
(
temp
,
" CPU_%d "
,
j
);
strcat
(
cpu_affinity
,
temp
);
}
/* Check the actual affinity mask assigned to the thread */
s
=
pthread_getaffinity_np
(
pthread_self
(),
sizeof
(
cpu_set_t
),
&
cpuset
);
if
(
s
!=
0
)
{
perror
(
"pthread_getaffinity_np"
);
exit_fun
(
"Error getting processor affinity "
);
}
memset
(
cpu_affinity
,
0
,
sizeof
(
cpu_affinity
));
for
(
int
j
=
0
;
j
<
CPU_SETSIZE
;
j
++
)
{
if
(
CPU_ISSET
(
j
,
&
cpuset
))
{
char
temp
[
1024
];
sprintf
(
temp
,
" CPU_%d "
,
j
);
strcat
(
cpu_affinity
,
temp
);
}
LOG_I
(
HW
,
"CPU Affinity of main() function is... %s
\n
"
,
cpu_affinity
);
}
LOG_I
(
HW
,
"CPU Affinity of main() function is... %s
\n
"
,
cpu_affinity
);
#endif
openair0_cfg
[
0
].
log_level
=
glog_level
;
/*int eMBMS_active=0;
if (node_function[0] <= NGFI_RAU_IF4p5) { // don't initialize L2 for RRU
LOG_I(PHY,"Intializing L2\n");
...
...
@@ -1658,13 +1122,12 @@ int main( int argc, char **argv ) {
#ifdef XFORMS
int
UE_id
;
if
(
do_forms
==
1
)
{
fl_initialize
(
&
argc
,
argv
,
NULL
,
0
,
0
);
if
(
do_forms
==
1
)
{
fl_initialize
(
&
argc
,
argv
,
NULL
,
0
,
0
);
if
(
UE_flag
==
1
)
{
//form_stats = create_form_stats_form();
//fl_show_form (form_stats->stats_form, FL_PLACE_HOTSPOT, FL_FULLBORDER, "stats");
UE_id
=
0
;
//form_stats = create_form_stats_form();
//fl_show_form (form_stats->stats_form, FL_PLACE_HOTSPOT, FL_FULLBORDER, "stats");
UE_id
=
0
;
form_ue
[
UE_id
]
=
create_lte_phy_scope_ue
();
sprintf
(
title
,
"LTE DL SCOPE UE"
);
fl_show_form
(
form_ue
[
UE_id
]
->
lte_phy_scope_ue
,
FL_PLACE_HOTSPOT
,
FL_FULLBORDER
,
title
);
...
...
@@ -1679,7 +1142,7 @@ int main( int argc, char **argv ) {
}*/
fl_set_button
(
form_ue
[
UE_id
]
->
button_0
,
0
);
fl_set_object_label
(
form_ue
[
UE_id
]
->
button_0
,
"IA Receiver OFF"
);
}
ret
=
pthread_create
(
&
forms_thread
,
NULL
,
scope_thread
,
NULL
);
...
...
@@ -1696,15 +1159,15 @@ int main( int argc, char **argv ) {
// start the main thread
if
(
UE_flag
==
1
)
{
if
(
UE_flag
==
1
)
{
init_UE
(
1
);
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
+
chain_offset
;
}
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
+
chain_offset
;
}
}
// connect the TX/RX buffers
if
(
UE_flag
==
1
)
{
...
...
@@ -1715,10 +1178,10 @@ int main( int argc, char **argv ) {
#if defined(OAI_USRP) || defined(OAI_ADRV9371_ZC706)
UE
[
CC_id
]
->
hw_timing_advance
=
timing_advance
;
#else
UE
[
CC_id
]
->
hw_timing_advance
=
160
;
UE
[
CC_id
]
->
hw_timing_advance
=
160
;
#endif
}
if
(
setup_ue_buffers
(
UE
,
&
openair0_cfg
[
0
])
!=
0
)
{
}
if
(
setup_ue_buffers
(
UE
,
&
openair0_cfg
[
0
])
!=
0
)
{
printf
(
"Error setting up eNB buffer
\n
"
);
exit
(
-
1
);
}
...
...
@@ -1760,44 +1223,24 @@ int main( int argc, char **argv ) {
#endif
// stop threads
// stop threads
#ifdef XFORMS
printf
(
"waiting for XFORMS thread
\n
"
);
if
(
do_forms
==
1
)
{
pthread_join
(
forms_thread
,
&
status
);
fl_hide_form
(
form_stats
->
stats_form
);
fl_free_form
(
form_stats
->
stats_form
);
if
(
UE_flag
==
1
)
{
fl_hide_form
(
form_ue
[
0
]
->
lte_phy_scope_ue
);
fl_free_form
(
form_ue
[
0
]
->
lte_phy_scope_ue
);
}
else
{
fl_hide_form
(
form_stats_l2
->
stats_form
);
fl_free_form
(
form_stats_l2
->
stats_form
);
for
(
UE_id
=
0
;
UE_id
<
scope_enb_num_ue
;
UE_id
++
)
{
for
(
CC_id
=
0
;
CC_id
<
MAX_NUM_CCs
;
CC_id
++
)
{
fl_hide_form
(
form_enb
[
CC_id
][
UE_id
]
->
lte_phy_scope_enb
);
fl_free_form
(
form_enb
[
CC_id
][
UE_id
]
->
lte_phy_scope_enb
);
}
}
}
}
printf
(
"waiting for XFORMS thread
\n
"
);
if
(
do_forms
==
1
)
{
pthread_join
(
forms_thread
,
&
status
);
fl_hide_form
(
form_stats
->
stats_form
);
fl_free_form
(
form_stats
->
stats_form
);
fl_hide_form
(
form_ue
[
0
]
->
lte_phy_scope_ue
);
fl_free_form
(
form_ue
[
0
]
->
lte_phy_scope_ue
);
}
#endif
printf
(
"stopping MODEM threads
\n
"
);
// cleanup
if
(
UE_flag
==
1
)
{
}
else
{
// stop_eNB(1);
}
printf
(
"stopping MODEM threads
\n
"
);
pthread_cond_destroy
(
&
sync_cond
);
pthread_mutex_destroy
(
&
sync_mutex
);
pthread_cond_destroy
(
&
sync_cond
);
pthread_mutex_destroy
(
&
sync_mutex
);
// *** Handle per CC_id openair0
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment