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
promise
OpenXG-RAN
Commits
d92bc77a
Commit
d92bc77a
authored
Jun 14, 2018
by
hongzhi wang
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
ue nr pbch fix
parent
7b5b739e
Changes
4
Show whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
53 additions
and
54 deletions
+53
-54
openair1/PHY/MODULATION/slot_fep.c
openair1/PHY/MODULATION/slot_fep.c
+2
-2
openair1/PHY/NR_REFSIG/nr_dmrs_rx.c
openair1/PHY/NR_REFSIG/nr_dmrs_rx.c
+5
-4
openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c
openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c
+25
-29
openair1/PHY/NR_UE_TRANSPORT/nr_pbch.c
openair1/PHY/NR_UE_TRANSPORT/nr_pbch.c
+21
-19
No files found.
openair1/PHY/MODULATION/slot_fep.c
View file @
d92bc77a
...
...
@@ -39,7 +39,7 @@ int slot_fep_pbch(PHY_VARS_NR_UE *ue,
NR_UE_COMMON
*
common_vars
=
&
ue
->
common_vars
;
uint8_t
eNB_id
=
0
;
//ue_common_vars->eNb_id;
unsigned
char
aa
;
unsigned
char
symbol
=
l
+
((
7
-
frame_parms
->
Ncp
)
*
(
Ns
&
1
));
///symbol within sub-frame
unsigned
char
symbol
=
l
;
//
+((7-frame_parms->Ncp)*(Ns&1)); ///symbol within sub-frame
unsigned
int
nb_prefix_samples
=
(
no_prefix
?
0
:
frame_parms
->
nb_prefix_samples
);
unsigned
int
nb_prefix_samples0
=
(
no_prefix
?
0
:
frame_parms
->
nb_prefix_samples0
);
unsigned
int
subframe_offset
;
//,subframe_offset_F;
...
...
@@ -181,7 +181,7 @@ int slot_fep_pbch(PHY_VARS_NR_UE *ue,
}
if
(
ue
->
perfect_ce
==
0
)
{
if
((
l
==
0
)
||
(
l
==
(
4
-
frame_parms
->
Ncp
)
))
{
if
((
l
>
0
)
&&
(
l
<
4
))
{
for
(
aa
=
0
;
aa
<
frame_parms
->
nb_antenna_ports_eNB
;
aa
++
)
{
#ifdef DEBUG_FEP
...
...
openair1/PHY/NR_REFSIG/nr_dmrs_rx.c
View file @
d92bc77a
...
...
@@ -145,11 +145,12 @@ int nr_pbch_dmrs_rx(unsigned int *nr_gold_pbch,
/// BPSK modulation
for
(
m
=
0
;
m
<
NR_PBCH_DMRS_LENGTH
;
m
++
)
{
output
[
m
<<
1
]
=
nr_mod_table
[((
1
+
((
nr_gold_pbch
[
m
>>
5
]
&
(
1
<<
(
m
&
0x1f
)))
>>
(
m
&
0x1f
)))
<<
1
)];
output
[(
m
<<
1
)
+
1
]
=
nr_mod_table
[((
1
+
((
nr_gold_pbch
[
m
>>
5
]
&
(
1
<<
(
m
&
0x1f
)))
>>
(
m
&
0x1f
)))
<<
1
)
+
1
];
((
int16_t
*
)
output
)
[
m
<<
1
]
=
nr_mod_table
[((
1
+
((
nr_gold_pbch
[
m
>>
5
]
&
(
1
<<
(
m
&
0x1f
)))
>>
(
m
&
0x1f
)))
<<
1
)];
((
int16_t
*
)
output
)
[(
m
<<
1
)
+
1
]
=
nr_mod_table
[((
1
+
((
nr_gold_pbch
[
m
>>
5
]
&
(
1
<<
(
m
&
0x1f
)))
>>
(
m
&
0x1f
)))
<<
1
)
+
1
];
#ifdef DEBUG_PBCH
printf
(
"nr_gold_pbch[m>>5] %x
\n
"
,
nr_gold_pbch
[
m
>>
5
]);
printf
(
"m %d output %d %d
\n
"
,
m
,
output
[
2
*
m
],
output
[
2
*
m
+
1
]);
//printf("nr_gold_pbch[m>>5] %x\n",nr_gold_pbch[m>>5]);
if
(
m
<
6
)
printf
(
"m %d output %d %d addr %p
\n
"
,
m
,
output
[
2
*
m
],
output
[
2
*
m
+
1
],
&
output
[
0
]);
#endif
}
...
...
openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c
View file @
d92bc77a
...
...
@@ -38,10 +38,10 @@ int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue,
unsigned
char
symbol
)
{
int
pilot
[
2
][
200
]
__attribute__
((
aligned
(
16
)));
unsigned
char
nu
,
aarx
;
unsigned
char
aarx
;
unsigned
short
k
;
unsigned
int
rb
,
pilot_cnt
;
int16_t
ch
[
2
],
*
pil
,
*
rxF
,
*
dl_ch
,
*
dl_ch_prev
,
*
fl
,
*
fm
,
*
f2l
,
*
fr
,
f1
,
*
f2r
,
*
fl_dc
,
*
fm_dc
,
*
fr_dc
;
unsigned
int
pilot_cnt
;
int16_t
ch
[
2
],
*
pil
,
*
rxF
,
*
dl_ch
,
*
fl
,
*
fm
,
*
f2l
,
*
fr
,
f1
,
*
f2r
,
*
fl_dc
,
*
fm_dc
,
*
fr_dc
;
int
ch_offset
,
symbol_offset
;
uint16_t
Nid_cell
=
(
eNB_offset
==
0
)
?
ue
->
frame_parms
.
Nid_cell
:
ue
->
measurements
.
adj_cell_id
[
eNB_offset
-
1
];
...
...
@@ -65,8 +65,8 @@ int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue,
k
=
nushift
;
#ifdef DEBUG_CH
printf
(
"PBCH 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
);
printf
(
"PBCH Channel Estimation : ThreadId %d, eNB_offset %d cell_id %d ch_offset %d, OFDM size %d, Ncp=%d, l=%d, Ns=%d, k=%d
symbol %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
,
symbol
);
#endif
switch
(
k
)
{
...
...
@@ -133,7 +133,7 @@ int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue,
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
))];
rxF
=
(
int16_t
*
)
&
rxdataF
[
aarx
][(
symbol_offset
+
k
+
(
ue
->
frame_parms
.
ofdm_symbol_size
-
10
*
12
))];
dl_ch
=
(
int16_t
*
)
&
dl_ch_estimates
[(
p
<<
1
)
+
aarx
][
ch_offset
];
memset
(
dl_ch
,
0
,
4
*
(
ue
->
frame_parms
.
ofdm_symbol_size
));
...
...
@@ -142,7 +142,10 @@ int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue,
ue
->
ch_est_alpha
,
dl_ch
-
(
ue
->
frame_parms
.
ofdm_symbol_size
<<
1
),
1
,
ue
->
frame_parms
.
ofdm_symbol_size
);
#ifdef DEBUG_CH
printf
(
"ch est pilot addr %p RB_DL %d
\n
"
,
&
pilot
[
p
][
0
],
ue
->
frame_parms
.
N_RB_DL
);
printf
(
"k %d, first_carrier %d
\n
"
,
k
,
ue
->
frame_parms
.
first_carrier_offset
);
printf
(
"rxF addr %p
\n
"
,
rxF
);
printf
(
"dl_ch addr %p
\n
"
,
dl_ch
);
#endif
if
((
ue
->
frame_parms
.
N_RB_DL
&
1
)
==
0
)
{
...
...
@@ -160,9 +163,7 @@ int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue,
pil
+=
2
;
rxF
+=
8
;
for
(
int
i
=
0
;
i
<
8
;
i
++
)
printf
(
"dl_ch %d %d
\n
"
,
dl_ch
+
i
,
*
(
dl_ch
+
i
));
//dl_ch+=6;
printf
(
"after dl_ch %d %d
\n
"
,
dl_ch
,
*
(
dl_ch
));
printf
(
"dl_ch addr %p %d
\n
"
,
dl_ch
+
i
,
*
(
dl_ch
+
i
));
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
);
...
...
@@ -174,19 +175,17 @@ int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue,
dl_ch
,
16
);
//printf("after dl_ch %d %d\n", dl_ch, *(dl_ch));
for
(
int
i
=
0
;
i
<
16
;
i
++
)
printf
(
"dl_ch %d %d
\n
"
,
dl_ch
+
i
,
*
(
dl_ch
+
i
));
//
for (int i= 0; i<16; i++)
//
printf("dl_ch %d %d\n", dl_ch+i, *(dl_ch+i));
pil
+=
2
;
rxF
+=
8
;
//dl_ch+=6;
printf
(
"after 6 dl_ch %d %d
\n
"
,
dl_ch
,
*
(
dl_ch
));
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
]);
printf
(
"pilot
2
: rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d)
\n
"
,
rxF
[
0
],
rxF
[
1
],
ch
[
0
],
ch
[
1
],
pil
[
0
],
pil
[
1
]);
#endif
multadd_real_vector_complex_scalar
(
fr
,
...
...
@@ -195,33 +194,33 @@ int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue,
16
);
pil
+=
2
;
rxF
+=
8
;
dl_ch
+=
16
;
for
(
pilot_cnt
=
6
;
pilot_cnt
<
((
ue
->
frame_parms
.
N_RB_DL
)
-
1
);
pilot_cnt
+=
6
)
{
dl_ch
+=
24
;
for
(
pilot_cnt
=
3
;
pilot_cnt
<
(
3
*
20
);
pilot_cnt
+=
3
)
{
if
(
pilot_cnt
==
30
)
rxF
=
(
int16_t
*
)
&
rxdataF
[
aarx
][(
symbol_offset
+
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 %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 %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]);
#endif
multadd_real_vector_complex_scalar
(
fl
,
ch
,
dl_ch
,
16
);
for
(
int
i
=
0
;
i
<
8
;
i
++
)
printf
(
"pilot_cnt %d dl_ch %d %d
\n
"
,
pilot_cnt
,
dl_ch
+
i
,
*
(
dl_ch
+
i
));
//
for (int i= 0; i<8; i++)
//
printf("pilot_cnt %d dl_ch %d %d\n", pilot_cnt, dl_ch+i, *(dl_ch+i));
pil
+=
2
;
rxF
+=
8
;
//dl_ch+=6;
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 %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]);
#endif
multadd_real_vector_complex_scalar
(
fm
,
ch
,
...
...
@@ -229,13 +228,12 @@ int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue,
16
);
pil
+=
2
;
rxF
+=
8
;
//dl_ch+=6;
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
]);
//
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]);
#endif
multadd_real_vector_complex_scalar
(
fr
,
...
...
@@ -244,16 +242,14 @@ int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue,
16
);
pil
+=
2
;
rxF
+=
8
;
dl_ch
+=
16
;
dl_ch
+=
24
;
}
}
printf
(
"dl_ch %d
\n
"
,
dl_ch
);
printf
(
"finish dl_ch addr %p
\n
"
,
dl_ch
);
}
...
...
openair1/PHY/NR_UE_TRANSPORT/nr_pbch.c
View file @
d92bc77a
...
...
@@ -68,14 +68,12 @@ uint16_t nr_pbch_extract(int **rxdataF,
int32_t
*
dl_ch0
,
*
dl_ch0_ext
,
*
rxF
,
*
rxF_ext
;
int
rx_offset
=
frame_parms
->
ofdm_symbol_size
-
10
*
12
;
int
ch_offset
=
frame_parms
->
N_RB_DL
*
6
-
10
*
12
;
int
nushiftmod4
=
frame_parms
->
nushift
;
for
(
aarx
=
0
;
aarx
<
frame_parms
->
nb_antennas_rx
;
aarx
++
)
{
printf
(
"extract_rbs (nushift %d): rx_offset=%d, ch_offset=%d symbol %d
\n
"
,
frame_parms
->
nushift
,
(
rx_offset
+
(
symbol
*
(
frame_parms
->
ofdm_symbol_size
))),
LTE_CE_OFFSET
+
ch_offset
+
(
symbol
*
(
frame_parms
->
ofdm_symbol_size
)),
symbol
);
printf
(
"extract_rbs (nushift %d): rx_offset=%d, symbol %d
\n
"
,
frame_parms
->
nushift
,
(
rx_offset
+
(
symbol
*
(
frame_parms
->
ofdm_symbol_size
))),
symbol
);
rxF
=
&
rxdataF
[
aarx
][(
rx_offset
+
(
symbol
*
(
frame_parms
->
ofdm_symbol_size
)))];
rxF_ext
=
&
rxdataF_ext
[
aarx
][
symbol
*
(
20
*
12
)];
...
...
@@ -88,10 +86,12 @@ uint16_t nr_pbch_extract(int **rxdataF,
#endif
for
(
rb
=
0
;
rb
<
20
;
rb
++
)
{
if
(
rb
==
10
)
{
rxF
=
&
rxdataF
[
aarx
][((
symbol
*
(
frame_parms
->
ofdm_symbol_size
)))];
}
if
((
symbol
==
1
)
||
(
symbol
==
3
))
{
j
=
0
;
if
((
symbol
==
1
)
||
(
symbol
==
3
))
{
for
(
i
=
0
;
i
<
12
;
i
++
)
{
if
((
i
!=
nushiftmod4
)
&&
(
i
!=
(
nushiftmod4
+
4
))
&&
...
...
@@ -103,7 +103,7 @@ uint16_t nr_pbch_extract(int **rxdataF,
}
rxF
+=
12
;
rxF_ext
+=
8
;
rxF_ext
+=
9
;
}
else
{
//symbol 2
if
((
rb
<
4
)
&&
(
rb
>
15
)){
for
(
i
=
0
;
i
<
12
;
i
++
)
{
...
...
@@ -118,34 +118,36 @@ uint16_t nr_pbch_extract(int **rxdataF,
}
rxF
+=
12
;
rxF_ext
+=
8
;
rxF_ext
+=
9
;
}
}
for
(
aatx
=
0
;
aatx
<
4
;
aatx
++
)
{
//
frame_parms->nb_antenna_ports_eNB;aatx++) {
for
(
aatx
=
0
;
aatx
<
frame_parms
->
nb_antenna_ports_eNB
;
aatx
++
)
{
if
(
high_speed_flag
==
1
)
dl_ch0
=
&
dl_ch_estimates
[(
aatx
<<
1
)
+
aarx
][
LTE_CE_OFFSET
+
ch_offset
+
(
symbol
*
(
frame_parms
->
ofdm_symbol_size
))];
dl_ch0
=
&
dl_ch_estimates
[(
aatx
<<
1
)
+
aarx
][(
symbol
*
(
frame_parms
->
ofdm_symbol_size
))];
else
dl_ch0
=
&
dl_ch_estimates
[(
aatx
<<
1
)
+
aarx
][
LTE_CE_OFFSET
+
ch_offset
];
dl_ch0
=
&
dl_ch_estimates
[(
aatx
<<
1
)
+
aarx
][
0
];
printf
(
"dl_ch0 addr %p
\n
"
,
dl_ch0
);
dl_ch0_ext
=
&
dl_ch_estimates_ext
[(
aatx
<<
1
)
+
aarx
][
symbol
*
(
20
*
12
)];
for
(
rb
=
0
;
rb
<
20
;
rb
++
)
{
if
((
symbol
==
1
)
||
(
symbol
==
3
))
{
j
=
0
;
if
((
symbol
==
1
)
||
(
symbol
==
3
))
{
for
(
i
=
0
;
i
<
12
;
i
++
)
{
if
((
i
!=
nushiftmod4
)
&&
(
i
!=
(
nushiftmod4
+
4
))
&&
(
i
!=
(
nushiftmod4
+
8
)))
{
dl_ch0_ext
[
j
]
=
dl_ch0
[
i
];
//printf("dl ch0 ext[%d] = %d dl_ch0 [%d]= %d\n",j,dl_ch0_ext[j],i,dl_ch0[i]);
if
((
rb
==
0
)
&&
(
i
<
2
))
printf
(
"dl ch0 ext[%d] = %d dl_ch0 [%d]= %d
\n
"
,
j
,
dl_ch0_ext
[
j
],
i
,
dl_ch0
[
i
]);
j
++
;
}
}
dl_ch0
+=
12
;
dl_ch0_ext
+=
8
;
dl_ch0_ext
+=
9
;
}
else
{
//symbol 2
if
((
rb
<
4
)
&&
(
rb
>
15
)){
...
...
@@ -160,7 +162,7 @@ uint16_t nr_pbch_extract(int **rxdataF,
}
dl_ch0
+=
12
;
dl_ch0_ext
+=
8
;
dl_ch0_ext
+=
9
;
}
}
...
...
@@ -558,7 +560,7 @@ uint16_t nr_rx_pbch( PHY_VARS_NR_UE *ue,
#endif
printf
(
"address dataf %p"
,
nr_ue_common_vars
->
common_vars_rx_data_per_thread
[
ue
->
current_thread_id
[
subframe_rx
]].
rxdataF
);
write_output
(
"rxdataF0_pbch.m"
,
"rxF0pbch"
,
nr_ue_common_vars
->
common_vars_rx_data_per_thread
[
ue
->
current_thread_id
[
subframe_rx
]].
rxdataF
,
frame_parms
->
ofdm_symbol_size
*
4
,
2
,
1
);
//
write_output("rxdataF0_pbch.m","rxF0pbch",nr_ue_common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[subframe_rx]].rxdataF,frame_parms->ofdm_symbol_size*4,2,1);
nr_pbch_extract
(
nr_ue_common_vars
->
common_vars_rx_data_per_thread
[
ue
->
current_thread_id
[
subframe_rx
]].
rxdataF
,
nr_ue_common_vars
->
common_vars_rx_data_per_thread
[
ue
->
current_thread_id
[
subframe_rx
]].
dl_ch_estimates
[
eNB_id
],
...
...
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