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
Michael Black
OpenXG-RAN
Commits
01dc85f7
Commit
01dc85f7
authored
Sep 22, 2022
by
laurent
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
fix review comments
parent
40db4201
Changes
13
Hide whitespace changes
Inline
Side-by-side
Showing
13 changed files
with
64 additions
and
116 deletions
+64
-116
executables/nr-uesoftmodem.h
executables/nr-uesoftmodem.h
+3
-3
openair1/PHY/INIT/nr_init.c
openair1/PHY/INIT/nr_init.c
+0
-17
openair1/PHY/INIT/nr_init_ue.c
openair1/PHY/INIT/nr_init_ue.c
+0
-18
openair1/PHY/LTE_ESTIMATION/lte_sync_time.c
openair1/PHY/LTE_ESTIMATION/lte_sync_time.c
+3
-7
openair1/PHY/NR_REFSIG/nr_gold.c
openair1/PHY/NR_REFSIG/nr_gold.c
+18
-0
openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c
openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c
+19
-20
openair1/PHY/NR_UE_TRANSPORT/pss_nr.c
openair1/PHY/NR_UE_TRANSPORT/pss_nr.c
+1
-1
openair1/PHY/defs_common.h
openair1/PHY/defs_common.h
+0
-22
openair1/PHY/defs_nr_UE.h
openair1/PHY/defs_nr_UE.h
+0
-3
openair1/SCHED_NR_UE/phy_procedures_nr_ue.c
openair1/SCHED_NR_UE/phy_procedures_nr_ue.c
+1
-2
openair2/GNB_APP/gnb_config.c
openair2/GNB_APP/gnb_config.c
+9
-10
openair2/GNB_APP/gnb_paramdef.h
openair2/GNB_APP/gnb_paramdef.h
+2
-0
targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp
targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp
+8
-13
No files found.
executables/nr-uesoftmodem.h
View file @
01dc85f7
...
...
@@ -29,9 +29,9 @@
/* optname helpstr paramflags XXXptr defXXXval type numelt */
/*------------------------------------------------------------------------------------------------------------------------------------------*/
#define CMDLINE_NRUEPARAMS_DESC { \
{"usrp-args", CONFIG_HLP_USRP_ARGS, 0, strptr:
(char **)
&usrp_args, defstrval:"type=b200", TYPE_STRING, 0}, \
{"tx_subdev", CONFIG_HLP_TX_SUBDEV, 0, strptr:
(char **)
&tx_subdev, defstrval:NULL, TYPE_STRING, 0}, \
{"rx_subdev", CONFIG_HLP_RX_SUBDEV, 0, strptr:
(char **)
&rx_subdev, defstrval:NULL, TYPE_STRING, 0}, \
{"usrp-args", CONFIG_HLP_USRP_ARGS, 0, strptr:&usrp_args, defstrval:"type=b200", TYPE_STRING, 0}, \
{"tx_subdev", CONFIG_HLP_TX_SUBDEV, 0, strptr:&tx_subdev, defstrval:NULL, TYPE_STRING, 0}, \
{"rx_subdev", CONFIG_HLP_RX_SUBDEV, 0, strptr:&rx_subdev, defstrval:NULL, TYPE_STRING, 0}, \
{"single-thread-disable", CONFIG_HLP_NOSNGLT, PARAMFLAG_BOOL, iptr:&single_thread_flag, defintval:1, TYPE_INT, 0}, \
{"dlsch-parallel", CONFIG_HLP_DLSCH_PARA, 0, u8ptr:NULL, defintval:0, TYPE_UINT8, 0}, \
{"offset-divisor", CONFIG_HLP_OFFSET_DIV, 0, uptr:&nrUE_params.ofdm_offset_divisor, defuintval:8, TYPE_UINT32, 0}, \
...
...
openair1/PHY/INIT/nr_init.c
View file @
01dc85f7
...
...
@@ -616,23 +616,6 @@ int phy_init_nr_gNB(PHY_VARS_gNB *gNB,
nr_init_csi_rs
(
&
gNB
->
frame_parms
,
gNB
->
nr_csi_info
->
nr_gold_csi_rs
,
cfg
->
cell_config
.
phy_cell_id
.
value
);
//PRS init
gNB
->
nr_gold_prs
=
(
uint32_t
****
)
malloc16
(
gNB
->
prs_vars
.
NumPRSResources
*
sizeof
(
uint32_t
***
));
uint32_t
****
prs
=
gNB
->
nr_gold_prs
;
AssertFatal
(
prs
!=
NULL
,
"NR init: positioning reference signal malloc failed
\n
"
);
for
(
int
rsc
=
0
;
rsc
<
gNB
->
prs_vars
.
NumPRSResources
;
rsc
++
)
{
prs
[
rsc
]
=
(
uint32_t
***
)
malloc16
(
fp
->
slots_per_frame
*
sizeof
(
uint32_t
**
));
AssertFatal
(
prs
[
rsc
]
!=
NULL
,
"NR init: positioning reference signal for rsc %d - malloc failed
\n
"
,
rsc
);
for
(
int
slot
=
0
;
slot
<
fp
->
slots_per_frame
;
slot
++
)
{
prs
[
rsc
][
slot
]
=
(
uint32_t
**
)
malloc16
(
fp
->
symbols_per_slot
*
sizeof
(
uint32_t
*
));
AssertFatal
(
prs
[
rsc
][
slot
]
!=
NULL
,
"NR init: positioning reference signal for slot %d - malloc failed
\n
"
,
slot
);
for
(
int
symb
=
0
;
symb
<
fp
->
symbols_per_slot
;
symb
++
)
{
prs
[
rsc
][
slot
][
symb
]
=
(
uint32_t
*
)
malloc16
(
NR_MAX_PRS_INIT_LENGTH_DWORD
*
sizeof
(
uint32_t
));
AssertFatal
(
prs
[
rsc
][
slot
][
symb
]
!=
NULL
,
"NR init: positioning reference signal for rsc %d slot %d symbol %d - malloc failed
\n
"
,
rsc
,
slot
,
symb
);
}
}
}
nr_init_prs
(
gNB
);
for
(
int
id
=
0
;
id
<
NUMBER_OF_NR_SRS_MAX
;
id
++
)
{
...
...
openair1/PHY/INIT/nr_init_ue.c
View file @
01dc85f7
...
...
@@ -251,16 +251,6 @@ void init_nr_prs_ue_vars(PHY_VARS_NR_UE *ue)
{
prs_vars
[
idx
]
=
(
NR_UE_PRS
*
)
malloc16_clear
(
sizeof
(
NR_UE_PRS
));
// PRS channel estimates
prs_vars
[
idx
]
->
ch_tmp
=
(
int16_t
*
)
malloc16_clear
(
fp
->
ofdm_symbol_size
*
sizeof
(
int32_t
));
AssertFatal
((
prs_vars
[
idx
]
->
ch_tmp
!=
NULL
),
"%s: PRS ch_tmp buffer malloc failed for gNB_id %d
\n
"
,
__FUNCTION__
,
idx
);
prs_vars
[
idx
]
->
chF_interpol
=
(
int32_t
**
)
malloc16_clear
(
fp
->
nb_antennas_rx
*
sizeof
(
int32_t
*
));
prs_vars
[
idx
]
->
chT_interpol
=
(
int32_t
**
)
malloc16_clear
(
fp
->
nb_antennas_rx
*
sizeof
(
int32_t
*
));
AssertFatal
((
prs_vars
[
idx
]
->
chF_interpol
!=
NULL
||
prs_vars
[
idx
]
->
chT_interpol
!=
NULL
),
"%s: PRS chF_interpol or chT_interpol buffer malloc failed for gNB_id %d
\n
"
,
__FUNCTION__
,
idx
);
for
(
int
j
=
0
;
j
<
fp
->
nb_antennas_rx
;
j
++
)
{
prs_vars
[
idx
]
->
chF_interpol
[
j
]
=
(
int32_t
*
)
malloc16_clear
(
NR_PRS_IDFT_OVERSAMP_FACTOR
*
fp
->
ofdm_symbol_size
*
sizeof
(
int32_t
));
prs_vars
[
idx
]
->
chT_interpol
[
j
]
=
(
int32_t
*
)
malloc16_clear
(
NR_PRS_IDFT_OVERSAMP_FACTOR
*
fp
->
ofdm_symbol_size
*
sizeof
(
int32_t
));
AssertFatal
((
prs_vars
[
idx
]
->
chF_interpol
[
j
]
!=
NULL
||
prs_vars
[
idx
]
->
chT_interpol
[
j
]
!=
NULL
),
"%s: PRS chF_interpol or chT_interpol buffer malloc failed for gNB_id %d, rx_ant %d
\n
"
,
__FUNCTION__
,
idx
,
j
);
}
for
(
int
k
=
0
;
k
<
NR_MAX_PRS_RESOURCES_PER_SET
;
k
++
)
{
...
...
@@ -688,14 +678,6 @@ void term_nr_ue_signal(PHY_VARS_NR_UE *ue, int nb_connected_gNB)
free_and_zero
(
ue
->
prs_vars
[
idx
]
->
prs_resource
[
k
].
prs_meas
);
}
for
(
int
j
=
0
;
j
<
fp
->
nb_antennas_rx
;
j
++
)
{
free_and_zero
(
ue
->
prs_vars
[
idx
]
->
chF_interpol
[
j
]);
free_and_zero
(
ue
->
prs_vars
[
idx
]
->
chT_interpol
[
j
]);
}
free_and_zero
(
ue
->
prs_vars
[
idx
]
->
chF_interpol
);
free_and_zero
(
ue
->
prs_vars
[
idx
]
->
chT_interpol
);
free_and_zero
(
ue
->
prs_vars
[
idx
]
->
ch_tmp
);
free_and_zero
(
ue
->
prs_vars
[
idx
]);
}
free_and_zero
(
ue
->
sinr_CQI_dB
);
...
...
openair1/PHY/LTE_ESTIMATION/lte_sync_time.c
View file @
01dc85f7
...
...
@@ -188,16 +188,12 @@ int lte_sync_time(int **rxdata, ///rx data in time domain
// calculate the absolute value of sync_corr[n]
for
(
s
=
0
;
s
<
3
;
s
++
)
{
double
tmp
=
absF
(
sync_out
[
s
])
+
absF
(
sync_out2
[
s
]);
double
tmp
=
squaredMod
(
sync_out
[
s
])
+
squaredMod
(
sync_out2
[
s
]);
if
(
tmp
>
peak_val
)
{
peak_val
=
tmp
;
peak_pos
=
n
;
sync_source
=
s
;
/*
printf("s %d: n %d sync_out %d, sync_out2 %d (sync_corr %d,%d), (%d,%d) (%d,%d)\n",s,n,abs32(sync_out[s]),abs32(sync_out2[s]),sync_corr_ue0[n],
sync_corr_ue0[n+length],((int16_t*)&sync_out[s])[0],((int16_t*)&sync_out[s])[1],((int16_t*)&sync_out2[s])[0],((int16_t*)&sync_out2[s])[1]);
*/
}
}
}
...
...
@@ -329,7 +325,7 @@ int lte_sync_time_eNB(int32_t **rxdata, ///rx data in time domain
result
=
dot_product
((
short
*
)
primary_synch_time
,
(
short
*
)
&
(
rxdata
[
ar
][
n
]),
frame_parms
->
ofdm_symbol_size
,
SHIFT
);
//((short*)sync_corr)[2*n] += ((short*) &result)[0];
//((short*)sync_corr)[2*n+1] += ((short*) &result)[1];
sync_corr_eNB
[
n
]
+=
abs32
(
result
);
sync_corr_eNB
[
n
]
+=
squaredMod
(
*
(
c16_t
*
)
&
result
);
}
}
...
...
@@ -412,7 +408,7 @@ int ru_sync_time(RU_t *ru,
shift
);
}
dmrs_corr
+=
abs64
(
result
);
dmrs_corr
+=
squaredMod
(
*
(
c32_t
*
)
&
result
);
}
if
(
ru
->
dmrs_corr
!=
NULL
)
...
...
openair1/PHY/NR_REFSIG/nr_gold.c
View file @
01dc85f7
...
...
@@ -131,6 +131,24 @@ void nr_init_prs(PHY_VARS_gNB* gNB)
uint16_t
Nid
;
NR_DL_FRAME_PARMS
*
fp
=
&
gNB
->
frame_parms
;
gNB
->
nr_gold_prs
=
(
uint32_t
****
)
malloc16
(
gNB
->
prs_vars
.
NumPRSResources
*
sizeof
(
uint32_t
***
));
uint32_t
****
prs
=
gNB
->
nr_gold_prs
;
AssertFatal
(
prs
!=
NULL
,
"NR init: positioning reference signal malloc failed
\n
"
);
for
(
int
rsc
=
0
;
rsc
<
gNB
->
prs_vars
.
NumPRSResources
;
rsc
++
)
{
prs
[
rsc
]
=
(
uint32_t
***
)
malloc16
(
fp
->
slots_per_frame
*
sizeof
(
uint32_t
**
));
AssertFatal
(
prs
[
rsc
]
!=
NULL
,
"NR init: positioning reference signal for rsc %d - malloc failed
\n
"
,
rsc
);
for
(
int
slot
=
0
;
slot
<
fp
->
slots_per_frame
;
slot
++
)
{
prs
[
rsc
][
slot
]
=
(
uint32_t
**
)
malloc16
(
fp
->
symbols_per_slot
*
sizeof
(
uint32_t
*
));
AssertFatal
(
prs
[
rsc
][
slot
]
!=
NULL
,
"NR init: positioning reference signal for slot %d - malloc failed
\n
"
,
slot
);
for
(
int
symb
=
0
;
symb
<
fp
->
symbols_per_slot
;
symb
++
)
{
prs
[
rsc
][
slot
][
symb
]
=
(
uint32_t
*
)
malloc16
(
NR_MAX_PRS_INIT_LENGTH_DWORD
*
sizeof
(
uint32_t
));
AssertFatal
(
prs
[
rsc
][
slot
][
symb
]
!=
NULL
,
"NR init: positioning reference signal for rsc %d slot %d symbol %d - malloc failed
\n
"
,
rsc
,
slot
,
symb
);
}
}
}
uint8_t
reset
;
uint8_t
slotNum
,
symNum
,
rsc_id
;
...
...
openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c
View file @
01dc85f7
...
...
@@ -51,14 +51,13 @@ int nr_prs_channel_estimation(uint8_t gNB_id,
int32_t
**
rxdataF
=
ue
->
common_vars
.
common_vars_rx_data_per_thread
[
proc
->
thread_id
].
rxdataF
;
prs_config_t
*
prs_cfg
=
&
ue
->
prs_vars
[
gNB_id
]
->
prs_resource
[
rsc_id
].
prs_cfg
;
prs_meas_t
**
prs_meas
=
ue
->
prs_vars
[
gNB_id
]
->
prs_resource
[
rsc_id
].
prs_meas
;
int16_t
*
ch_tmp
=
ue
->
prs_vars
[
gNB_id
]
->
ch_tmp
;
int32_t
**
chF_interpol
=
ue
->
prs_vars
[
gNB_id
]
->
chF_interpol
;
int32_t
**
chT_interpol
=
ue
->
prs_vars
[
gNB_id
]
->
chT_interpol
;
memset
(
ch_tmp
,
0
,
ue
->
frame_parms
.
ofdm_symbol_size
*
sizeof
(
int32_t
));
for
(
rxAnt
=
0
;
rxAnt
<
frame_params
->
nb_antennas_rx
;
rxAnt
++
)
{
memset
(
chF_interpol
[
rxAnt
],
0
,
NR_PRS_IDFT_OVERSAMP_FACTOR
*
ue
->
frame_parms
.
ofdm_symbol_size
*
sizeof
(
int32_t
));
memset
(
chT_interpol
[
rxAnt
],
0
,
NR_PRS_IDFT_OVERSAMP_FACTOR
*
ue
->
frame_parms
.
ofdm_symbol_size
*
sizeof
(
int32_t
));
}
c16_t
ch_tmp_buf
[
ue
->
frame_parms
.
ofdm_symbol_size
];
int32_t
chF_interpol
[
frame_params
->
nb_antennas_rx
][
NR_PRS_IDFT_OVERSAMP_FACTOR
*
ue
->
frame_parms
.
ofdm_symbol_size
];
int32_t
chT_interpol
[
frame_params
->
nb_antennas_rx
][
NR_PRS_IDFT_OVERSAMP_FACTOR
*
ue
->
frame_parms
.
ofdm_symbol_size
];
memset
(
ch_tmp_buf
,
0
,
sizeof
(
ch_tmp_buf
));
memset
(
chF_interpol
,
0
,
sizeof
(
chF_interpol
));
memset
(
chT_interpol
,
0
,
sizeof
(
chF_interpol
));
int
slot_prs
=
(
proc
->
nr_slot_rx
-
rep_num
*
prs_cfg
->
PRSResourceTimeGap
+
frame_params
->
slots_per_frame
)
%
frame_params
->
slots_per_frame
;
uint32_t
**
nr_gold_prs
=
ue
->
nr_gold_prs
[
gNB_id
][
rsc_id
][
slot_prs
];
...
...
@@ -69,7 +68,7 @@ int nr_prs_channel_estimation(uint8_t gNB_id,
#ifdef DEBUG_PRS_CHEST
char
filename
[
64
]
=
{
0
},
varname
[
64
]
=
{
0
};
#endif
int16_t
*
ch_
init
=
ch_tmp
;
int16_t
*
ch_
tmp
=
(
int16_t
*
)
ch_tmp_buf
;
int16_t
scale_factor
=
(
1
.
0
f
/
(
float
)(
prs_cfg
->
NumPRSSymbols
))
*
(
1
<<
15
);
int16_t
num_pilots
=
(
12
/
prs_cfg
->
CombSize
)
*
prs_cfg
->
NumRB
;
int16_t
start_offset
=
(
NR_PRS_IDFT_OVERSAMP_FACTOR
-
1
)
*
frame_params
->
ofdm_symbol_size
>>
1
;
...
...
@@ -152,7 +151,7 @@ int nr_prs_channel_estimation(uint8_t gNB_id,
//SNR estimation
noiseFig
[
0
]
=
rxF
[
0
]
-
(
int16_t
)(((
int32_t
)
ch
[
0
]
*
pil
[
0
]
-
(
int32_t
)
ch
[
1
]
*
pil
[
1
])
>>
15
);
noiseFig
[
1
]
=
rxF
[
1
]
-
(
int16_t
)(((
int32_t
)
ch
[
1
]
*
pil
[
0
]
+
(
int32_t
)
ch
[
0
]
*
pil
[
1
])
>>
15
);
snr
+=
10
*
log10
(
abs32
(
*
((
int32_t
*
)
rxF
))
-
abs32
(
*
((
int32_t
*
)
noiseFig
)))
-
10
*
log10
(
abs32
(
*
((
int32_t
*
)
noiseFig
)
));
snr
+=
10
*
log10
(
squaredMod
(
*
(
c16_t
*
)
rxF
)
-
squaredMod
(
*
(
c16_t
*
)
noiseFig
))
-
10
*
log10
(
squaredMod
(
*
(
c16_t
*
)
noiseFig
));
#ifdef DEBUG_PRS_PRINTS
printf
(
"[Rx %d] pilot %3d, SNR %+2d dB: rxF - > (%+3d, %+3d) addr %p ch -> (%+3d, %+3d), pil -> (%+d, %+d)
\n
"
,
rxAnt
,
0
,
snr
,
rxF
[
0
],
rxF
[
1
],
&
rxF
[
0
],
ch
[
0
],
ch
[
1
],
pil
[
0
],
pil
[
1
]);
#endif
...
...
@@ -183,7 +182,7 @@ int nr_prs_channel_estimation(uint8_t gNB_id,
//SNR estimation
noiseFig
[
0
]
=
rxF
[
0
]
-
(
int16_t
)(((
int32_t
)
ch
[
0
]
*
pil
[
0
]
-
(
int32_t
)
ch
[
1
]
*
pil
[
1
])
>>
15
);
noiseFig
[
1
]
=
rxF
[
1
]
-
(
int16_t
)(((
int32_t
)
ch
[
1
]
*
pil
[
0
]
+
(
int32_t
)
ch
[
0
]
*
pil
[
1
])
>>
15
);
snr
+=
10
*
log10
(
abs32
(
*
((
int32_t
*
)
rxF
))
-
abs32
(
*
((
int32_t
*
)
noiseFig
)))
-
10
*
log10
(
abs32
(
*
((
int32_t
*
)
noiseFig
)
));
snr
+=
10
*
log10
(
squaredMod
(
*
(
c16_t
*
)
rxF
)
-
squaredMod
(
*
(
c16_t
*
)
noiseFig
))
-
10
*
log10
(
squaredMod
(
*
(
c16_t
*
)
noiseFig
));
#ifdef DEBUG_PRS_PRINTS
printf
(
"[Rx %d] pilot %3d, SNR %+2d dB: rxF - > (%+3d, %+3d) addr %p ch -> (%+3d, %+3d), pil -> (%+d, %+d)
\n
"
,
rxAnt
,
pIdx
,
snr
/
(
pIdx
+
1
),
rxF
[
0
],
rxF
[
1
],
&
rxF
[
0
],
ch
[
0
],
ch
[
1
],
pil
[
0
],
pil
[
1
]);
#endif
...
...
@@ -211,7 +210,7 @@ int nr_prs_channel_estimation(uint8_t gNB_id,
//SNR estimation
noiseFig
[
0
]
=
rxF
[
0
]
-
(
int16_t
)(((
int32_t
)
ch
[
0
]
*
pil
[
0
]
-
(
int32_t
)
ch
[
1
]
*
pil
[
1
])
>>
15
);
noiseFig
[
1
]
=
rxF
[
1
]
-
(
int16_t
)(((
int32_t
)
ch
[
1
]
*
pil
[
0
]
+
(
int32_t
)
ch
[
0
]
*
pil
[
1
])
>>
15
);
snr
+=
10
*
log10
(
abs32
(
*
((
int32_t
*
)
rxF
))
-
abs32
(
*
((
int32_t
*
)
noiseFig
)))
-
10
*
log10
(
abs32
(
*
((
int32
_t
*
)
noiseFig
)));
snr
+=
10
*
log10
(
squaredMod
(
*
((
c16_t
*
)
rxF
))
-
squaredMod
(
*
((
c16_t
*
)
noiseFig
)))
-
10
*
log10
(
squaredMod
(
*
((
c16
_t
*
)
noiseFig
)));
#ifdef DEBUG_PRS_PRINTS
printf
(
"[Rx %d] pilot %3d, SNR %+2d dB: rxF - > (%+3d, %+3d) addr %p ch -> (%+3d, %+3d), pil -> (%+d, %+d)
\n
"
,
rxAnt
,
pIdx
+
1
,
snr
/
(
pIdx
+
2
),
rxF
[
0
],
rxF
[
1
],
&
rxF
[
0
],
ch
[
0
],
ch
[
1
],
pil
[
0
],
pil
[
1
]);
#endif
...
...
@@ -232,7 +231,7 @@ int nr_prs_channel_estimation(uint8_t gNB_id,
//SNR estimation
noiseFig
[
0
]
=
rxF
[
0
]
-
(
int16_t
)(((
int32_t
)
ch
[
0
]
*
pil
[
0
]
-
(
int32_t
)
ch
[
1
]
*
pil
[
1
])
>>
15
);
noiseFig
[
1
]
=
rxF
[
1
]
-
(
int16_t
)(((
int32_t
)
ch
[
1
]
*
pil
[
0
]
+
(
int32_t
)
ch
[
0
]
*
pil
[
1
])
>>
15
);
snr
+=
10
*
log10
(
abs32
(
*
((
int32_t
*
)
rxF
))
-
abs32
(
*
((
int32_t
*
)
noiseFig
)))
-
10
*
log10
(
abs32
(
*
((
int32
_t
*
)
noiseFig
)));
snr
+=
10
*
log10
(
squaredMod
(
*
((
c16_t
*
)
rxF
))
-
squaredMod
(
*
((
c16_t
*
)
noiseFig
)))
-
10
*
log10
(
squaredMod
(
*
((
c16
_t
*
)
noiseFig
)));
#ifdef DEBUG_PRS_PRINTS
printf
(
"[Rx %d] pilot %3d, SNR %+2d dB: rxF - > (%+3d, %+3d) addr %p ch -> (%+3d, %+3d), pil -> (%+d, %+d)
\n
"
,
rxAnt
,
num_pilots
-
1
,
snr
/
num_pilots
,
rxF
[
0
],
rxF
[
1
],
&
rxF
[
0
],
ch
[
0
],
ch
[
1
],
pil
[
0
],
pil
[
1
]);
#endif
...
...
@@ -297,7 +296,7 @@ int nr_prs_channel_estimation(uint8_t gNB_id,
//SNR estimation
noiseFig
[
0
]
=
rxF
[
0
]
-
(
int16_t
)(((
int32_t
)
ch
[
0
]
*
pil
[
0
]
-
(
int32_t
)
ch
[
1
]
*
pil
[
1
])
>>
15
);
noiseFig
[
1
]
=
rxF
[
1
]
-
(
int16_t
)(((
int32_t
)
ch
[
1
]
*
pil
[
0
]
+
(
int32_t
)
ch
[
0
]
*
pil
[
1
])
>>
15
);
snr
+=
10
*
log10
(
abs32
(
*
((
int32_t
*
)
rxF
))
-
abs32
(
*
((
int32_t
*
)
noiseFig
)))
-
10
*
log10
(
abs32
(
*
((
int32
_t
*
)
noiseFig
)));
snr
+=
10
*
log10
(
squaredMod
(
*
((
c16_t
*
)
rxF
))
-
squaredMod
(
*
((
c16_t
*
)
noiseFig
)))
-
10
*
log10
(
squaredMod
(
*
((
c16
_t
*
)
noiseFig
)));
#ifdef DEBUG_PRS_PRINTS
printf
(
"[Rx %d] pilot %3d, SNR %+2d dB: rxF - > (%+3d, %+3d) addr %p ch -> (%+3d, %+3d), pil -> (%+d, %+d)
\n
"
,
rxAnt
,
0
,
snr
,
rxF
[
0
],
rxF
[
1
],
&
rxF
[
0
],
ch
[
0
],
ch
[
1
],
pil
[
0
],
pil
[
1
]);
#endif
...
...
@@ -315,7 +314,7 @@ int nr_prs_channel_estimation(uint8_t gNB_id,
//SNR estimation
noiseFig
[
0
]
=
rxF
[
0
]
-
(
int16_t
)(((
int32_t
)
ch
[
0
]
*
pil
[
0
]
-
(
int32_t
)
ch
[
1
]
*
pil
[
1
])
>>
15
);
noiseFig
[
1
]
=
rxF
[
1
]
-
(
int16_t
)(((
int32_t
)
ch
[
1
]
*
pil
[
0
]
+
(
int32_t
)
ch
[
0
]
*
pil
[
1
])
>>
15
);
snr
+=
10
*
log10
(
abs32
(
*
((
int32_t
*
)
rxF
))
-
abs32
(
*
((
int32_t
*
)
noiseFig
)))
-
10
*
log10
(
abs32
(
*
((
int32
_t
*
)
noiseFig
)));
snr
+=
10
*
log10
(
squaredMod
(
*
((
c16_t
*
)
rxF
))
-
squaredMod
(
*
((
c16_t
*
)
noiseFig
)))
-
10
*
log10
(
squaredMod
(
*
((
c16
_t
*
)
noiseFig
)));
#ifdef DEBUG_PRS_PRINTS
printf
(
"[Rx %d] pilot %3d, SNR %+2d dB: rxF - > (%+3d, %+3d) addr %p ch -> (%+3d, %+3d), pil -> (%+d, %+d)
\n
"
,
rxAnt
,
1
,
snr
/
2
,
rxF
[
0
],
rxF
[
1
],
&
rxF
[
0
],
ch
[
0
],
ch
[
1
],
pil
[
0
],
pil
[
1
]);
#endif
...
...
@@ -337,7 +336,7 @@ int nr_prs_channel_estimation(uint8_t gNB_id,
//SNR estimation
noiseFig
[
0
]
=
rxF
[
0
]
-
(
int16_t
)(((
int32_t
)
ch
[
0
]
*
pil
[
0
]
-
(
int32_t
)
ch
[
1
]
*
pil
[
1
])
>>
15
);
noiseFig
[
1
]
=
rxF
[
1
]
-
(
int16_t
)(((
int32_t
)
ch
[
1
]
*
pil
[
0
]
+
(
int32_t
)
ch
[
0
]
*
pil
[
1
])
>>
15
);
snr
+=
10
*
log10
(
abs32
(
*
((
int32_t
*
)
rxF
))
-
abs32
(
*
((
int32_t
*
)
noiseFig
)))
-
10
*
log10
(
abs32
(
*
((
int32
_t
*
)
noiseFig
)));
snr
+=
10
*
log10
(
squaredMod
(
*
((
c16_t
*
)
rxF
))
-
squaredMod
(
*
((
c16_t
*
)
noiseFig
)))
-
10
*
log10
(
squaredMod
(
*
((
c16
_t
*
)
noiseFig
)));
#ifdef DEBUG_PRS_PRINTS
printf
(
"[Rx %d] pilot %3d, SNR %+2d dB: rxF - > (%+3d, %+3d) addr %p ch -> (%+3d, %+3d), pil -> (%+d, %+d)
\n
"
,
rxAnt
,
pIdx
,
snr
/
(
pIdx
+
1
),
rxF
[
0
],
rxF
[
1
],
&
rxF
[
0
],
ch
[
0
],
ch
[
1
],
pil
[
0
],
pil
[
1
]);
#endif
...
...
@@ -358,7 +357,7 @@ int nr_prs_channel_estimation(uint8_t gNB_id,
//SNR estimation
noiseFig
[
0
]
=
rxF
[
0
]
-
(
int16_t
)(((
int32_t
)
ch
[
0
]
*
pil
[
0
]
-
(
int32_t
)
ch
[
1
]
*
pil
[
1
])
>>
15
);
noiseFig
[
1
]
=
rxF
[
1
]
-
(
int16_t
)(((
int32_t
)
ch
[
1
]
*
pil
[
0
]
+
(
int32_t
)
ch
[
0
]
*
pil
[
1
])
>>
15
);
snr
+=
10
*
log10
(
abs32
(
*
((
int32_t
*
)
rxF
))
-
abs32
(
*
((
int32_t
*
)
noiseFig
)))
-
10
*
log10
(
abs32
(
*
((
int32
_t
*
)
noiseFig
)));
snr
+=
10
*
log10
(
squaredMod
(
*
((
c16_t
*
)
rxF
))
-
squaredMod
(
*
((
c16_t
*
)
noiseFig
)))
-
10
*
log10
(
squaredMod
(
*
((
c16
_t
*
)
noiseFig
)));
#ifdef DEBUG_PRS_PRINTS
printf
(
"[Rx %d] pilot %3d, SNR %+2d dB: rxF - > (%+3d, %+3d) addr %p ch -> (%+3d, %+3d), pil -> (%+d, %+d)
\n
"
,
rxAnt
,
num_pilots
-
2
,
snr
/
(
num_pilots
-
1
),
rxF
[
0
],
rxF
[
1
],
&
rxF
[
0
],
ch
[
0
],
ch
[
1
],
pil
[
0
],
pil
[
1
]);
#endif
...
...
@@ -376,7 +375,7 @@ int nr_prs_channel_estimation(uint8_t gNB_id,
//SNR estimation
noiseFig
[
0
]
=
rxF
[
0
]
-
(
int16_t
)(((
int32_t
)
ch
[
0
]
*
pil
[
0
]
-
(
int32_t
)
ch
[
1
]
*
pil
[
1
])
>>
15
);
noiseFig
[
1
]
=
rxF
[
1
]
-
(
int16_t
)(((
int32_t
)
ch
[
1
]
*
pil
[
0
]
+
(
int32_t
)
ch
[
0
]
*
pil
[
1
])
>>
15
);
snr
+=
10
*
log10
(
abs32
(
*
((
int32_t
*
)
rxF
))
-
abs32
(
*
((
int32_t
*
)
noiseFig
)))
-
10
*
log10
(
abs32
(
*
((
int32
_t
*
)
noiseFig
)));
snr
+=
10
*
log10
(
squaredMod
(
*
((
c16_t
*
)
rxF
))
-
squaredMod
(
*
((
c16_t
*
)
noiseFig
)))
-
10
*
log10
(
squaredMod
(
*
((
c16
_t
*
)
noiseFig
)));
#ifdef DEBUG_PRS_PRINTS
printf
(
"[Rx %d] pilot %3d, SNR %+2d dB: rxF - > (%+3d, %+3d) addr %p ch -> (%+3d, %+3d), pil -> (%+d, +%d)
\n
"
,
rxAnt
,
num_pilots
-
1
,
snr
/
num_pilots
,
rxF
[
0
],
rxF
[
1
],
&
rxF
[
0
],
ch
[
0
],
ch
[
1
],
pil
[
0
],
pil
[
1
]);
#endif
...
...
@@ -390,7 +389,7 @@ int nr_prs_channel_estimation(uint8_t gNB_id,
}
//reset channel pointer
ch_tmp
=
ch_init
;
ch_tmp
=
(
int16_t
*
)
ch_tmp_buf
;
}
// for rxAnt
}
//for l
...
...
@@ -554,7 +553,7 @@ void peak_estimator(int32_t *buffer, int32_t buf_len, int32_t *peak_idx, int32_t
int32_t
max_val
=
0
,
max_idx
=
0
,
abs_val
=
0
;
for
(
int
k
=
0
;
k
<
buf_len
;
k
++
)
{
abs_val
=
abs32
(
buffer
[
k
]);
abs_val
=
squaredMod
(((
c16_t
*
)
buffer
)
[
k
]);
if
(
abs_val
>
max_val
)
{
max_val
=
abs_val
;
...
...
openair1/PHY/NR_UE_TRANSPORT/pss_nr.c
View file @
01dc85f7
...
...
@@ -708,7 +708,7 @@ int pss_search_time_nr(int **rxdata, ///rx data in time domain
(
short
*
)
&
(
rxdata
[
ar
][
n
+
is
*
frame_parms
->
samples_per_frame
]),
frame_parms
->
ofdm_symbol_size
,
shift
);
pss_corr_ue
+=
abs64
(
result
);
pss_corr_ue
+=
squaredMod
(
*
(
c32_t
*
)
&
result
);
//((short*)pss_corr_ue[pss_index])[2*n] += ((short*) &result)[0]; /* real part */
//((short*)pss_corr_ue[pss_index])[2*n+1] += ((short*) &result)[1]; /* imaginary part */
//((short*)&synchro_out)[0] += ((int*) &result)[0]; /* real part */
...
...
openair1/PHY/defs_common.h
View file @
01dc85f7
...
...
@@ -1113,26 +1113,4 @@ static inline int release_thread(pthread_mutex_t *mutex,
return
(
0
);
}
static
inline
int32_t
abs32
(
int32_t
x
)
{
return
(((
int32_t
)((
int16_t
*
)
&
x
)[
0
])
*
((
int32_t
)((
int16_t
*
)
&
x
)[
0
])
+
((
int32_t
)((
int16_t
*
)
&
x
)[
1
])
*
((
int32_t
)((
int16_t
*
)
&
x
)[
1
]));
}
static
inline
int64_t
abs64
(
int64_t
x
)
{
return
(((
int64_t
)((
int32_t
*
)
&
x
)[
0
])
*
((
int64_t
)((
int32_t
*
)
&
x
)[
0
])
+
((
int64_t
)((
int32_t
*
)
&
x
)[
1
])
*
((
int64_t
)((
int32_t
*
)
&
x
)[
1
]));
}
static
inline
double
absF
(
struct
complexd
x
)
{
return
x
.
r
*
x
.
r
+
x
.
i
*
x
.
i
;
}
static
inline
double
angle64
(
int64_t
x
)
{
double
re
=
((
int32_t
*
)
&
x
)[
0
];
double
im
=
((
int32_t
*
)
&
x
)[
1
];
return
(
atan2
(
im
,
re
));
}
#endif // __PHY_DEFS_COMMON_H__
openair1/PHY/defs_nr_UE.h
View file @
01dc85f7
...
...
@@ -356,9 +356,6 @@ typedef struct {
typedef
struct
{
uint8_t
NumPRSResources
;
NR_PRS_RESOURCE_t
prs_resource
[
NR_MAX_PRS_RESOURCES_PER_SET
];
int16_t
*
ch_tmp
;
int32_t
**
chF_interpol
;
int32_t
**
chT_interpol
;
}
NR_UE_PRS
;
#define NR_PDCCH_DEFS_NR_UE
...
...
openair1/SCHED_NR_UE/phy_procedures_nr_ue.c
View file @
01dc85f7
...
...
@@ -1331,7 +1331,6 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue,
int
frame_rx
=
proc
->
frame_rx
;
int
nr_slot_rx
=
proc
->
nr_slot_rx
;
fapi_nr_config_request_t
*
cfg
=
&
ue
->
nrUE_config
;
prs_config_t
*
prs_config
=
NULL
;
NR_DL_FRAME_PARMS
*
fp
=
&
ue
->
frame_parms
;
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME
(
VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_RX
,
VCD_FUNCTION_IN
);
...
...
@@ -1415,7 +1414,7 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue,
{
for
(
int
rsc_id
=
0
;
rsc_id
<
ue
->
prs_vars
[
gNB_id
]
->
NumPRSResources
;
rsc_id
++
)
{
prs_config
=
&
ue
->
prs_vars
[
gNB_id
]
->
prs_resource
[
rsc_id
].
prs_cfg
;
prs_config
_t
*
prs_config
=
&
ue
->
prs_vars
[
gNB_id
]
->
prs_resource
[
rsc_id
].
prs_cfg
;
for
(
int
i
=
0
;
i
<
prs_config
->
PRSResourceRepetition
;
i
++
)
{
if
(
(((
frame_rx
*
fp
->
slots_per_frame
+
nr_slot_rx
)
-
(
prs_config
->
PRSResourceSetPeriod
[
1
]
+
prs_config
->
PRSResourceOffset
)
+
prs_config
->
PRSResourceSetPeriod
[
0
])
%
prs_config
->
PRSResourceSetPeriod
[
0
])
==
i
*
prs_config
->
PRSResourceTimeGap
)
...
...
openair2/GNB_APP/gnb_config.c
View file @
01dc85f7
...
...
@@ -675,7 +675,7 @@ void RCconfig_nr_prs(void)
{
uint16_t
j
=
0
,
k
=
0
;
prs_config_t
*
prs_config
=
NULL
;
char
str
[
7
][
100
]
=
{
'\0'
};
int16_t
n
[
7
]
=
{
0
};
char
str
[
7
][
100
]
=
{
0
};
paramdef_t
PRS_Params
[]
=
PRS_PARAMS_DESC
;
paramlist_def_t
PRS_ParamList
=
{
CONFIG_STRING_PRS_CONFIG
,
NULL
,
0
};
...
...
@@ -697,7 +697,6 @@ void RCconfig_nr_prs(void)
RC
.
gNB
[
j
]
->
Mod_id
=
j
;
}
memset
(
n
,
0
,
sizeof
(
n
));
RC
.
gNB
[
j
]
->
prs_vars
.
NumPRSResources
=
*
(
PRS_ParamList
.
paramarray
[
j
][
NUM_PRS_RESOURCES
].
uptr
);
for
(
k
=
0
;
k
<
RC
.
gNB
[
j
]
->
prs_vars
.
NumPRSResources
;
k
++
)
{
...
...
@@ -720,22 +719,22 @@ void RCconfig_nr_prs(void)
for
(
int
l
=
0
;
l
<
PRS_ParamList
.
paramarray
[
j
][
PRS_MUTING_PATTERN1_LIST
].
numelt
;
l
++
)
{
prs_config
->
MutingPattern1
[
l
]
=
PRS_ParamList
.
paramarray
[
j
][
PRS_MUTING_PATTERN1_LIST
].
uptr
[
l
];
if
(
k
==
0
)
// print only for 0th resource
n
[
5
]
+=
snprintf
(
str
[
5
]
+
n
[
5
],
sizeof
(
str
[
5
]),
"%d, "
,
prs_config
->
MutingPattern1
[
l
]);
if
(
k
==
0
)
// print only for 0th resource
snprintf
(
str
[
5
]
+
strlen
(
str
[
5
]),
sizeof
(
str
[
5
])
-
strlen
(
str
[
5
]),
"%d, "
,
prs_config
->
MutingPattern1
[
l
]);
}
for
(
int
l
=
0
;
l
<
PRS_ParamList
.
paramarray
[
j
][
PRS_MUTING_PATTERN2_LIST
].
numelt
;
l
++
)
{
prs_config
->
MutingPattern2
[
l
]
=
PRS_ParamList
.
paramarray
[
j
][
PRS_MUTING_PATTERN2_LIST
].
uptr
[
l
];
if
(
k
==
0
)
// print only for 0th resource
n
[
6
]
+=
snprintf
(
str
[
6
]
+
n
[
6
],
sizeof
(
str
[
6
]),
"%d, "
,
prs_config
->
MutingPattern2
[
l
]);
snprintf
(
str
[
6
]
+
strlen
(
str
[
6
]),
sizeof
(
str
[
6
])
-
strlen
(
str
[
6
]),
"%d, "
,
prs_config
->
MutingPattern2
[
l
]);
}
// print to buffer
n
[
0
]
+=
snprintf
(
str
[
0
]
+
n
[
0
],
sizeof
(
str
[
0
]),
"%d, "
,
prs_config
->
SymbolStart
);
n
[
1
]
+=
snprintf
(
str
[
1
]
+
n
[
1
],
sizeof
(
str
[
1
]),
"%d, "
,
prs_config
->
NumPRSSymbols
);
n
[
2
]
+=
snprintf
(
str
[
2
]
+
n
[
2
],
sizeof
(
str
[
2
]),
"%d, "
,
prs_config
->
REOffset
);
n
[
3
]
+=
snprintf
(
str
[
3
]
+
n
[
3
],
sizeof
(
str
[
3
]),
"%d, "
,
prs_config
->
PRSResourceOffset
);
n
[
4
]
+=
snprintf
(
str
[
4
]
+
n
[
4
],
sizeof
(
str
[
4
]),
"%d, "
,
prs_config
->
NPRSID
);
snprintf
(
str
[
0
]
+
strlen
(
str
[
0
]),
sizeof
(
str
[
0
])
-
strlen
(
str
[
0
]),
"%d, "
,
prs_config
->
SymbolStart
);
snprintf
(
str
[
1
]
+
strlen
(
str
[
1
]),
sizeof
(
str
[
1
])
-
strlen
(
str
[
1
]),
"%d, "
,
prs_config
->
NumPRSSymbols
);
snprintf
(
str
[
2
]
+
strlen
(
str
[
2
]),
sizeof
(
str
[
2
])
-
strlen
(
str
[
2
]),
"%d, "
,
prs_config
->
REOffset
);
snprintf
(
str
[
3
]
+
strlen
(
str
[
3
]),
sizeof
(
str
[
3
])
-
strlen
(
str
[
3
]),
"%d, "
,
prs_config
->
PRSResourceOffset
);
snprintf
(
str
[
4
]
+
strlen
(
str
[
4
]),
sizeof
(
str
[
4
])
-
strlen
(
str
[
4
]),
"%d, "
,
prs_config
->
NPRSID
);
}
// for k
prs_config
=
&
RC
.
gNB
[
j
]
->
prs_vars
.
prs_cfg
[
0
];
...
...
openair2/GNB_APP/gnb_paramdef.h
View file @
01dc85f7
...
...
@@ -369,6 +369,8 @@ typedef enum {
#define CONFIG_STRING_L1_LIST "L1s"
#define CONFIG_STRING_L1_CONFIG "l1_config"
/*----------------------------------------------------------------------------------------------------------------------------------------------------*/
/*----------------------------------------------------------------------------------------------------------------------------------------------------*/
...
...
targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp
View file @
01dc85f7
...
...
@@ -449,8 +449,8 @@ static int trx_usrp_write(openair0_device *device,
}
else
{
((
__m128i
*
)
buff_tx
[
i
])[
2
*
j
]
=
_mm_slli_epi16
(((
__m128i
*
)
buff
[
i
])[
2
*
j
],
4
);
((
__m128i
*
)
buff_tx
[
i
])[
2
*
j
+
1
]
=
_mm_slli_epi16
(((
__m128i
*
)
buff
[
i
])[
2
*
j
+
1
]
,
4
);
__m256i
tmp
=
_mm256_loadu_si256
(((
__m256i
*
)
buff
[
i
])[
j
]
);
buff_tx
[
i
][
j
]
=
_mm256_slli_epi16
(
tmp
,
4
);
}
#else
buff_tx
[
i
][
j
]
=
_mm_slli_epi16
(((
__m128i
*
)
buff
[
i
])[
j
],
4
);
...
...
@@ -596,8 +596,8 @@ void *trx_usrp_write_thread(void * arg){
}
else
{
((
__m128i
*
)
buff_tx
[
i
])[
2
*
j
]
=
_mm_slli_epi16
(((
__m128i
*
)
buff
[
i
])[
2
*
j
],
4
);
((
__m128i
*
)
buff_tx
[
i
])[
2
*
j
+
1
]
=
_mm_slli_epi16
(((
__m128i
*
)
buff
[
i
])[
2
*
j
+
1
]
,
4
);
__m256i
tmp
=
_mm256_loadu_si256
(((
__m256i
*
)
buff
[
i
])[
j
]
);
buff_tx
[
i
][
j
]
=
_mm256_slli_epi16
(
tmp
,
4
);
}
#else
buff_tx
[
i
][
j
]
=
_mm_slli_epi16
(((
__m128i
*
)
buff
[
i
])[
j
],
4
);
...
...
@@ -752,15 +752,10 @@ static int trx_usrp_read(openair0_device *device, openair0_timestamp *ptimestamp
if
((((
uintptr_t
)
buff
[
i
])
&
0x1F
)
==
0
)
{
((
__m256i
*
)
buff
[
i
])[
j
]
=
_mm256_srai_epi16
(
buff_tmp
[
i
][
j
],
rxshift
);
}
else
if
((((
uintptr_t
)
buff
[
i
])
&
0x0F
)
==
0
)
{
((
__m128i
*
)
buff
[
i
])[
2
*
j
]
=
_mm_srai_epi16
(((
__m128i
*
)
buff_tmp
[
i
])[
2
*
j
],
rxshift
);
((
__m128i
*
)
buff
[
i
])[
2
*
j
+
1
]
=
_mm_srai_epi16
(((
__m128i
*
)
buff_tmp
[
i
])[
2
*
j
+
1
],
rxshift
);
}
else
{
((
__m64
*
)
buff
[
i
])[
4
*
j
]
=
_mm_srai_pi16
(((
__m64
*
)
buff_tmp
[
i
])[
4
*
j
],
rxshift
);
((
__m64
*
)
buff
[
i
])[
4
*
j
+
1
]
=
_mm_srai_pi16
(((
__m64
*
)
buff_tmp
[
i
])[
4
*
j
+
1
],
rxshift
);
((
__m64
*
)
buff
[
i
])[
4
*
j
+
2
]
=
_mm_srai_pi16
(((
__m64
*
)
buff_tmp
[
i
])[
4
*
j
+
2
],
rxshift
);
((
__m64
*
)
buff
[
i
])[
4
*
j
+
3
]
=
_mm_srai_pi16
(((
__m64
*
)
buff_tmp
[
i
])[
4
*
j
+
3
],
rxshift
);
}
}
else
{
__m256i
tmp
=
_mm256_srai_epi16
(
buff_tmp
[
i
][
j
],
rxshift
);
_mm256_storeu_si256
(((
__m256i
*
)
buff
[
i
])[
j
],
tmp
);
}
}
#else
for
(
int
j
=
0
;
j
<
nsamps2
;
j
++
)
...
...
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