Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
O
OpenXG-RAN
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
ZhouShuya
OpenXG-RAN
Commits
9ccb93a0
Commit
9ccb93a0
authored
Sep 09, 2019
by
Wang Tsu-Han
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
adding mask for feptx thread and VCD logging
parent
009bacc8
Changes
11
Hide whitespace changes
Inline
Side-by-side
Showing
11 changed files
with
121 additions
and
35 deletions
+121
-35
common/utils/LOG/vcd_signal_dumper.c
common/utils/LOG/vcd_signal_dumper.c
+9
-1
common/utils/LOG/vcd_signal_dumper.h
common/utils/LOG/vcd_signal_dumper.h
+8
-0
common/utils/T/T_defs.h
common/utils/T/T_defs.h
+2
-2
common/utils/T/T_messages.txt
common/utils/T/T_messages.txt
+40
-0
executables/nr-ru.c
executables/nr-ru.c
+1
-0
openair1/PHY/MODULATION/beamforming.c
openair1/PHY/MODULATION/beamforming.c
+3
-3
openair1/PHY/MODULATION/nr_modulation.h
openair1/PHY/MODULATION/nr_modulation.h
+3
-1
openair1/PHY/defs_RU.h
openair1/PHY/defs_RU.h
+5
-0
openair1/SCHED_NR/nr_ru_procedures.c
openair1/SCHED_NR/nr_ru_procedures.c
+36
-15
targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpx300.conf
.../GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpx300.conf
+1
-1
targets/RT/USER/gNB_usrp.gtkw
targets/RT/USER/gNB_usrp.gtkw
+13
-12
No files found.
common/utils/LOG/vcd_signal_dumper.c
View file @
9ccb93a0
...
...
@@ -247,7 +247,8 @@ const char* eurecomVariablesNames[] = {
"slot_number_TX0_gNB"
,
"slot_number_TX1_gNB"
,
"slot_number_RX0_gNB"
,
"slot_number_RX1_gNB"
"slot_number_RX1_gNB"
,
"ru_tx_ofdm_mask"
};
const
char
*
eurecomFunctionsNames
[]
=
{
...
...
@@ -328,6 +329,13 @@ const char* eurecomFunctionsNames[] = {
"phy_procedures_ru_feptx_ofdm7"
,
"phy_procedures_ru_feptx_ofdm8"
,
"phy_procedures_ru_feptx_ofdm9"
,
"phy_procedures_ru_feptx_ofdm10"
,
"phy_procedures_ru_feptx_ofdm11"
,
"phy_procedures_ru_feptx_ofdm12"
,
"phy_procedures_ru_feptx_ofdm13"
,
"phy_procedures_ru_feptx_ofdm14"
,
"phy_procedures_ru_feptx_ofdm15"
,
"phy_procedures_ru_feptx_ofdm16"
,
"phy_procedures_ru_feptx_prec0"
,
"phy_procedures_ru_feptx_prec1"
,
"phy_procedures_ru_feptx_prec2"
,
...
...
common/utils/LOG/vcd_signal_dumper.h
View file @
9ccb93a0
...
...
@@ -225,6 +225,7 @@ typedef enum {
VCD_SIGNAL_DUMPER_VARIABLES_SLOT_NUMBER_TX1_GNB
,
VCD_SIGNAL_DUMPER_VARIABLES_SLOT_NUMBER_RX0_GNB
,
VCD_SIGNAL_DUMPER_VARIABLES_SLOT_NUMBER_RX1_GNB
,
VCD_SIGNAL_DUMPER_VARIABLES_RU_TX_OFDM_MASK
,
VCD_SIGNAL_DUMPER_VARIABLES_END
...
...
@@ -309,6 +310,13 @@ typedef enum {
VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_OFDM7
,
VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_OFDM8
,
VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_OFDM9
,
VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_OFDM10
,
VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_OFDM11
,
VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_OFDM12
,
VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_OFDM13
,
VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_OFDM14
,
VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_OFDM15
,
VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_OFDM16
,
VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_PREC
,
VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_PREC1
,
VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_PREC2
,
...
...
common/utils/T/T_defs.h
View file @
9ccb93a0
...
...
@@ -73,10 +73,10 @@ typedef struct {
}
T_cache_t
;
/* number of VCD functions (to be kept up to date! see in T_messages.txt) */
#define VCD_NUM_FUNCTIONS (23
1
)
#define VCD_NUM_FUNCTIONS (23
8
)
/* number of VCD variables (to be kept up to date! see in T_messages.txt) */
#define VCD_NUM_VARIABLES (18
5
)
#define VCD_NUM_VARIABLES (18
6
)
/* first VCD function (to be kept up to date! see in T_messages.txt) */
#define VCD_FIRST_FUNCTION ((uintptr_t)T_VCD_FUNCTION_RT_SLEEP)
...
...
common/utils/T/T_messages.txt
View file @
9ccb93a0
...
...
@@ -2050,6 +2050,11 @@ ID = VCD_VARIABLE_SLOT_NUMBER_RX1_GNB
GROUP = ALL:VCD:ENB:VCD_VARIABLE
FORMAT = ulong,value
VCD_NAME = slot_number_RX1_gNB
ID = VCD_VARIABLE_RU_TX_OFDM_MASK
DESC = VCD variable RU_TX_OFDM_MASK
GROUP = ALL:VCD:ENB:VCD_VARIABLE
FORMAT = ulong,value
VCD_NAME = ru_tx_ofdm_mask
#functions
...
...
@@ -2418,6 +2423,41 @@ ID = VCD_FUNCTION_PHY_PROCEDURES_RU_FEPTX_OFDM9
GROUP = ALL:VCD:ENB:VCD_FUNCTION
FORMAT = int,value
VCD_NAME = phy_procedures_ru_feptx_ofdm9
ID = VCD_FUNCTION_PHY_PROCEDURES_RU_FEPTX_OFDM10
DESC = VCD function PHY_PROCEDURES_RU_FEPTX_OFDM10
GROUP = ALL:VCD:ENB:VCD_FUNCTION
FORMAT = int,value
VCD_NAME = phy_procedures_ru_feptx_ofdm10
ID = VCD_FUNCTION_PHY_PROCEDURES_RU_FEPTX_OFDM11
DESC = VCD function PHY_PROCEDURES_RU_FEPTX_OFDM11
GROUP = ALL:VCD:ENB:VCD_FUNCTION
FORMAT = int,value
VCD_NAME = phy_procedures_ru_feptx_ofdm11
ID = VCD_FUNCTION_PHY_PROCEDURES_RU_FEPTX_OFDM12
DESC = VCD function PHY_PROCEDURES_RU_FEPTX_OFDM12
GROUP = ALL:VCD:ENB:VCD_FUNCTION
FORMAT = int,value
VCD_NAME = phy_procedures_ru_feptx_ofdm12
ID = VCD_FUNCTION_PHY_PROCEDURES_RU_FEPTX_OFDM13
DESC = VCD function PHY_PROCEDURES_RU_FEPTX_OFDM13
GROUP = ALL:VCD:ENB:VCD_FUNCTION
FORMAT = int,value
VCD_NAME = phy_procedures_ru_feptx_ofdm13
ID = VCD_FUNCTION_PHY_PROCEDURES_RU_FEPTX_OFDM14
DESC = VCD function PHY_PROCEDURES_RU_FEPTX_OFDM14
GROUP = ALL:VCD:ENB:VCD_FUNCTION
FORMAT = int,value
VCD_NAME = phy_procedures_ru_feptx_ofdm14
ID = VCD_FUNCTION_PHY_PROCEDURES_RU_FEPTX_OFDM15
DESC = VCD function PHY_PROCEDURES_RU_FEPTX_OFDM15
GROUP = ALL:VCD:ENB:VCD_FUNCTION
FORMAT = int,value
VCD_NAME = phy_procedures_ru_feptx_ofdm15
ID = VCD_FUNCTION_PHY_PROCEDURES_RU_FEPTX_OFDM16
DESC = VCD function PHY_PROCEDURES_RU_FEPTX_OFDM16
GROUP = ALL:VCD:ENB:VCD_FUNCTION
FORMAT = int,value
VCD_NAME = phy_procedures_ru_feptx_ofdm16
ID = VCD_FUNCTION_PHY_PROCEDURES_RU_FEPTX_PREC
DESC = VCD function PHY_PROCEDURES_RU_FEPTX_PREC
GROUP = ALL:VCD:ENB:VCD_FUNCTION
...
...
executables/nr-ru.c
View file @
9ccb93a0
...
...
@@ -1663,6 +1663,7 @@ void init_RU_proc(RU_t *ru) {
proc
->
frame_offset
=
0
;
proc
->
num_slaves
=
0
;
proc
->
frame_tx_unwrap
=
0
;
proc
->
feptx_mask
=
0
;
for
(
i
=
0
;
i
<
10
;
i
++
)
proc
->
symbol_mask
[
i
]
=
0
;
...
...
openair1/PHY/MODULATION/beamforming.c
View file @
9ccb93a0
...
...
@@ -144,12 +144,12 @@ int nr_beam_precoding(int32_t **txdataF,
int32_t
***
beam_weights
,
int
slot
,
int
symbol
,
int
aa
)
int
aa
,
int
nb_antenna_ports
)
{
uint8_t
p
;
int
nb_antenna_ports
=
frame_parms
->
Lmax
;
// for now logical antenna ports corresponds to SSB
// clear txdata_BF[aa][re] for each call of ue_spec_beamforming
memset
(
&
txdataF_BF
[
aa
][
symbol
*
frame_parms
->
ofdm_symbol_size
],
0
,
sizeof
(
int32_t
)
*
(
frame_parms
->
ofdm_symbol_size
));
...
...
@@ -164,5 +164,5 @@ int nr_beam_precoding(int32_t **txdataF,
15
);
}
}
return
0
;
return
0
;
}
openair1/PHY/MODULATION/nr_modulation.h
View file @
9ccb93a0
...
...
@@ -87,6 +87,8 @@ int nr_beam_precoding(int32_t **txdataF,
int32_t
***
beam_weights
,
int
slot
,
int
symbol
,
int
aa
);
int
aa
,
int
nb_antenna_ports
);
#endif
openair1/PHY/defs_RU.h
View file @
9ccb93a0
...
...
@@ -183,6 +183,8 @@ typedef struct RU_feptx_t_s{
int
aa
;
//physical MAX nb_tx
int
half_slot
;
//first or second half of a slot
int
slot
;
//current slot
int
nb_antenna_ports
;
//number of logical port
int
index
;
}
RU_feptx_t
;
typedef
struct
RU_proc_t_s
{
...
...
@@ -400,9 +402,12 @@ typedef struct RU_proc_t_s {
int
ru_tx_ready
;
int
emulate_rf_busy
;
/// structure for precoding thread
RU_prec_t
prec
[
16
];
/// structure for feptx thread
RU_feptx_t
feptx
[
16
];
/// mask for checking process finished
int
feptx_mask
;
}
RU_proc_t
;
typedef
enum
{
...
...
openair1/SCHED_NR/nr_ru_procedures.c
View file @
9ccb93a0
...
...
@@ -121,6 +121,8 @@ void nr_feptx_ofdm_2thread(RU_t *ru,int frame_tx,int tti_tx) {
int
slot
=
tti_tx
;
int
i
=
0
;
int
ret
=
0
;
int
nb_antenna_ports
=
4
;
int
ofdm_mask_full
=
(
1
<<
(
ru
->
nb_tx
*
2
))
-
1
;
start_meas
(
&
ru
->
total_precoding_stats
);
...
...
@@ -129,10 +131,11 @@ void nr_feptx_ofdm_2thread(RU_t *ru,int frame_tx,int tti_tx) {
cfg
=
&
gNB
->
gNB_config
;
if
(
nr_slot_select
(
cfg
,
tti_tx
)
==
SF_UL
)
return
;
for
(
i
=
0
;
i
<
fp
->
Lmax
;
++
i
)
for
(
i
=
0
;
i
<
nb_antenna_ports
;
++
i
){
memcpy
((
void
*
)
ru
->
common
.
txdataF
[
i
],
(
void
*
)
gNB
->
common_vars
.
txdataF
[
i
],
fp
->
samples_per_slot_wCP
*
sizeof
(
int32_t
));
}
}
//num_gNB == 1
stop_meas
(
&
ru
->
total_precoding_stats
);
...
...
@@ -148,21 +151,28 @@ void nr_feptx_ofdm_2thread(RU_t *ru,int frame_tx,int tti_tx) {
AssertFatal
((
ret
=
pthread_mutex_lock
(
&
feptx
[
i
].
mutex_feptx
))
==
0
,
"mutex_lock return %d
\n
"
,
ret
);
feptx
[
i
].
half_slot
=
i
%
2
;
feptx
[
i
].
aa
=
i
>>
1
;
feptx
[
i
].
index
=
i
;
feptx
[
i
].
ru
=
ru
;
feptx
[
i
].
slot
=
slot
;
feptx
[
i
].
nb_antenna_ports
=
nb_antenna_ports
;
feptx
[
i
].
instance_cnt_feptx
=
0
;
AssertFatal
(
pthread_cond_signal
(
&
feptx
[
i
].
cond_feptx
)
==
0
,
"ERROR pthread_cond_signal for
gNB_L1
_thread
\n
"
);
AssertFatal
(
pthread_cond_signal
(
&
feptx
[
i
].
cond_feptx
)
==
0
,
"ERROR pthread_cond_signal for
feptx_ofdm
_thread
\n
"
);
AssertFatal
((
ret
=
pthread_mutex_unlock
(
&
feptx
[
i
].
mutex_feptx
))
==
0
,
"mutex_lock returns %d
\n
"
,
ret
);
}
}
// call first half-slot in this thread
i
=
0
;
while
(
1
){
if
(
feptx
[
i
].
instance_cnt_feptx
==
-
1
)
++
i
;
if
(
i
==
16
)
break
;
// wait all process to finish
AssertFatal
((
ret
=
pthread_mutex_lock
(
&
proc
->
mutex_feptx
))
==
0
,
"mutex_lock return %d
\n
"
,
ret
);
while
(
proc
->
feptx_mask
!=
ofdm_mask_full
)
{
// most of the time the thread is waiting here
// proc->instance_cnt_rxtx is -1
pthread_cond_wait
(
&
proc
->
cond_feptx
,
&
proc
->
mutex_feptx
);
// this unlocks mutex_rxtx while waiting and then locks it again
}
proc
->
feptx_mask
=
0
;
AssertFatal
((
ret
=
pthread_mutex_unlock
(
&
proc
->
mutex_feptx
))
==
0
,
"mutex_lock return %d
\n
"
,
ret
);
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME
(
VCD_SIGNAL_DUMPER_VARIABLES_RU_TX_OFDM_MASK
,
proc
->
feptx_mask
);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME
(
VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_OFDM
,
0
);
//write_output
...
...
@@ -175,19 +185,25 @@ static void *nr_feptx_thread(void *param) {
RU_feptx_t
*
feptx
=
(
RU_feptx_t
*
)
param
;
RU_t
*
ru
;
int
aa
,
slot
,
start
,
l
;
int
aa
,
slot
,
start
,
l
,
nb_antenna_ports
,
ret
;
int32_t
***
bw
;
NR_DL_FRAME_PARMS
*
fp
;
int
ofdm_mask_full
;
while
(
!
oai_exit
)
{
ret
=
0
;
if
(
wait_on_condition
(
&
feptx
->
mutex_feptx
,
&
feptx
->
cond_feptx
,
&
feptx
->
instance_cnt_feptx
,
"NR feptx thread"
)
<
0
)
break
;
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME
(
VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_OFDM
+
feptx
->
index
+
1
,
1
);
ru
=
feptx
->
ru
;
slot
=
feptx
->
slot
;
aa
=
feptx
->
aa
;
fp
=
ru
->
nr_frame_parms
;
start
=
(
feptx
->
half_slot
)
?
fp
->
symbols_per_slot
>>
1
:
0
;
nb_antenna_ports
=
feptx
->
nb_antenna_ports
;
ofdm_mask_full
=
(
1
<<
(
ru
->
nb_tx
*
2
))
-
1
;
bw
=
ru
->
beam_weights
[
0
];
for
(
l
=
0
;
l
<
fp
->
symbols_per_slot
>>
1
;
l
++
)
{
...
...
@@ -197,18 +213,22 @@ static void *nr_feptx_thread(void *param) {
bw
,
slot
,
l
+
start
,
aa
);
aa
,
nb_antenna_ports
);
}
// for (l=0;l<fp->symbols_per_slot;l++)
nr_feptx0
(
ru
,
slot
,
start
,
fp
->
symbols_per_slot
>>
1
,
aa
);
if
(
pthread_cond_signal
(
&
feptx
->
cond_feptx
)
!=
0
)
{
LOG_E
(
PHY
,
"[gNB] ERROR pthread_cond_signal for NR feptx thread exit
\n
"
);
exit_fun
(
"ERROR pthread_cond_signal"
);
return
NULL
;
}
if
(
release_thread
(
&
feptx
->
mutex_feptx
,
&
feptx
->
instance_cnt_feptx
,
"NR feptx thread"
)
<
0
)
break
;
AssertFatal
((
ret
=
pthread_mutex_lock
(
&
ru
->
proc
.
mutex_feptx
))
==
0
,
"mutex_lock return %d
\n
"
,
ret
);
ru
->
proc
.
feptx_mask
|=
1
<<
(
feptx
->
index
);
if
(
ru
->
proc
.
feptx_mask
==
ofdm_mask_full
)
AssertFatal
(
pthread_cond_signal
(
&
ru
->
proc
.
cond_feptx
)
==
0
,
"ERROR pthread_cond_signal for precoding and ofdm finish
\n
"
);
AssertFatal
((
ret
=
pthread_mutex_unlock
(
&
ru
->
proc
.
mutex_feptx
))
==
0
,
"mutex_lock returns %d
\n
"
,
ret
);
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME
(
VCD_SIGNAL_DUMPER_VARIABLES_RU_TX_OFDM_MASK
,
ru
->
proc
.
feptx_mask
);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME
(
VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_OFDM
+
feptx
->
index
+
1
,
0
);
}
return
(
NULL
);
}
...
...
@@ -400,7 +420,8 @@ void nr_feptx_prec(RU_t *ru,int frame,int tti_tx) {
bw
,
tti_tx
,
l
,
aa
);
aa
,
fp
->
Lmax
);
}
// for (aa=0;aa<ru->nb_tx;aa++)
}
// for (l=0;l<fp->symbols_per_slot;l++)
}
// if (ru->nb_tx == 1)
...
...
targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpx300.conf
View file @
9ccb93a0
...
...
@@ -70,7 +70,7 @@ gNBs =
UL_BWP_prefix_type
=
"NORMAL"
;
UL_timeAlignmentTimerCommon
=
"infinity"
;
ServingCellConfigCommon_n_TimingAdvanceOffset
=
"n0"
ServingCellConfigCommon_ssb_PositionsInBurst_PR
=
0
x0
1
;
ServingCellConfigCommon_ssb_PositionsInBurst_PR
=
0
x0
f
;
#####
ServingCellConfigCommon_ssb_periodicityServingCell
=
10
;
ServingCellConfigCommon_dmrs_TypeA_Position
=
2
;
NIA_SubcarrierSpacing
=
"kHz15"
;
...
...
targets/RT/USER/gNB_usrp.gtkw
View file @
9ccb93a0
[*]
[*] GTKWave Analyzer v3.3.
61
(w)1999-2014 BSI
[*]
Sat May 18 17:25:11
2019
[*] GTKWave Analyzer v3.3.
58
(w)1999-2014 BSI
[*]
Fri Sep 6 15:01:30
2019
[*]
[dumpfile] "/tmp/
openair_dump_gNB40
.vcd"
[dumpfile_mtime] "
Sat May 18 17:11:31
2019"
[dumpfile_size]
53148516
[savefile] "/home
/caracal/raymond
/openairinterface5g/targets/RT/USER/gNB_usrp.gtkw"
[timestart]
1155277539
0
[size] 1
840 795
[dumpfile] "/tmp/
gNB_prec
.vcd"
[dumpfile_mtime] "
Fri Sep 6 14:59:50
2019"
[dumpfile_size]
13106022
[savefile] "/home
s/wangts
/openairinterface5g/targets/RT/USER/gNB_usrp.gtkw"
[timestart]
218332000
0
[size] 1
920 1018
[pos] -1 -1
*-1
3.848083 11552814436
-1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1
*-1
8.423141 -1
-1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1
[sst_width] 386
[signals_width] 344
[sst_expanded] 1
[sst_vpaned_height]
19
7
[sst_vpaned_height]
26
7
@28
functions.trx_read
functions.trx_write
...
...
@@ -24,9 +24,8 @@ variables.frame_number_TX1_UE[63:0]
functions.ue_gain_control
@420
variables.frame_number_RX1_UE[63:0]
@25
variables.trx_ts_ue[63:0]
@24
variables.trx_ts_ue[63:0]
variables.trx_ts[63:0]
variables.trx_tst[63:0]
variables.frame_number_RX0_RU[63:0]
...
...
@@ -63,5 +62,7 @@ functions.phy_procedures_ru_feptx_ofdm0
functions.phy_procedures_ru_feptx_ofdm1
functions.phy_procedures_ru_feptx_prec0
functions.phy_procedures_ru_feptx_prec1
@23
variables.ru_tx_ofdm_mask[63:0]
[pattern_trace] 1
[pattern_trace] 0
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