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
Michael Black
OpenXG UE
Commits
1847a457
Commit
1847a457
authored
Dec 01, 2017
by
Cedric Roux
Browse files
Options
Browse Files
Download
Plain Diff
Merge remote-tracking branch 'origin/feature-iq-record-playback' into develop
parents
96e59cad
9e6bf159
Changes
12
Hide whitespace changes
Inline
Side-by-side
Showing
12 changed files
with
493 additions
and
11 deletions
+493
-11
cmake_targets/CMakeLists.txt
cmake_targets/CMakeLists.txt
+1
-0
cmake_targets/build_oai
cmake_targets/build_oai
+8
-0
openair1/PHY/LTE_TRANSPORT/pucch.c
openair1/PHY/LTE_TRANSPORT/pucch.c
+29
-2
openair2/LAYER2/MAC/defs.h
openair2/LAYER2/MAC/defs.h
+4
-0
openair2/LAYER2/MAC/eNB_scheduler_RA.c
openair2/LAYER2/MAC/eNB_scheduler_RA.c
+18
-0
openair2/LAYER2/MAC/eNB_scheduler_primitives.c
openair2/LAYER2/MAC/eNB_scheduler_primitives.c
+3
-0
openair2/LAYER2/PDCP_v10.1.0/pdcp_security.c
openair2/LAYER2/PDCP_v10.1.0/pdcp_security.c
+2
-2
openair2/RRC/LITE/defs.h
openair2/RRC/LITE/defs.h
+4
-0
openair2/RRC/LITE/rrc_eNB_S1AP.c
openair2/RRC/LITE/rrc_eNB_S1AP.c
+3
-1
targets/ARCH/COMMON/common_lib.h
targets/ARCH/COMMON/common_lib.h
+9
-0
targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp
targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp
+323
-6
targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.h
targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.h
+89
-0
No files found.
cmake_targets/CMakeLists.txt
View file @
1847a457
...
...
@@ -241,6 +241,7 @@ add_boolean_option(UE_AUTOTEST_TRACE False "Activate UE autotest specific logs
add_boolean_option
(
UE_DEBUG_TRACE False
"Activate UE debug trace"
)
add_boolean_option
(
UE_TIMING_TRACE False
"Activate UE timing trace"
)
add_boolean_option
(
DISABLE_LOG_X False
"Deactivate all LOG_* macros"
)
add_boolean_option
(
USRP_REC_PLAY False
"Enable USRP record playback mode"
)
add_boolean_option
(
DEBUG_CONSOLE False
"makes debugging easier, disables stdout/stderr buffering"
)
...
...
cmake_targets/build_oai
View file @
1847a457
...
...
@@ -66,6 +66,7 @@ UE_AUTOTEST_TRACE="False"
UE_DEBUG_TRACE
=
"False"
UE_TIMING_TRACE
=
"False"
DISABLE_LOG_X
=
"False"
USRP_REC_PLAY
=
"False"
BUILD_ECLIPSE
=
0
trap
handle_ctrl_c INT
...
...
@@ -158,6 +159,8 @@ Options
Disable all LOG_* macros
--build-eclipse
Build eclipse project files. Paths are auto corrected by fixprj.sh
--usrp-recplay
Build for I/Q record-playback modes
Usage (first build):
oaisim (eNB + UE): ./build_oai -I --oaisim -x --install-system-files
Eurecom EXMIMO + COTS UE : ./build_oai -I --eNB -x --install-system-files
...
...
@@ -350,6 +353,10 @@ function main() {
BUILD_TELNETSRV
=
1
echo_info
"Build embedded telnet server"
shift
;;
--usrp-recplay
)
USRP_REC_PLAY
=
"True"
echo_info
"Enabling USRP record playback mode"
shift
1
;;
-h
|
--help
)
print_help
exit
1
;;
...
...
@@ -540,6 +547,7 @@ function main() {
echo
"set (UE_DEBUG_TRACE
$UE_DEBUG_TRACE
)"
>>
$cmake_file
echo
"set (UE_TIMING_TRACE
$UE_TIMING_TRACE
)"
>>
$cmake_file
echo
"set (DISABLE_LOG_X
$DISABLE_LOG_X
)"
>>
$cmake_file
echo
"set (USRP_REC_PLAY
$USRP_REC_PLAY
)"
>>
$cmake_file
if
[
"
$UE
"
=
1
-a
"
$NOS1
"
=
"0"
]
;
then
echo_info
"Compiling UE S1 build : enabling Linux and NETLINK"
echo
"set (LINUX True )"
>>
$cmake_file
...
...
openair1/PHY/LTE_TRANSPORT/pucch.c
View file @
1847a457
...
...
@@ -1871,6 +1871,23 @@ uint32_t rx_pucch(PHY_VARS_eNB *eNB,
eNB
->
pucch1ab_stats_cnt
[
j
][
i
]
=
0
;
}
}
#if defined(USRP_REC_PLAY)
// It's probably bad to do this statically only once.
// Looks like the above is incomplete.
// Such reset needs to be done once a UE PHY structure is being used/re-used
// Don't know if this is ever possible in current architecture
for
(
i
=
0
;
i
<
10240
;
i
++
)
{
for
(
j
=
0
;
j
<
NUMBER_OF_UE_MAX
;
j
++
)
{
eNB
->
pucch1_stats
[
j
][
i
]
=
0
;
eNB
->
pucch1_stats_thres
[
j
][
i
]
=
0
;
}
}
for
(
i
=
0
;
i
<
20480
;
i
++
)
{
for
(
j
=
0
;
j
<
NUMBER_OF_UE_MAX
;
j
++
)
{
eNB
->
pucch1ab_stats
[
j
][
i
]
=
0
;
}
}
#endif
first_call
=
0
;
}
...
...
@@ -2152,8 +2169,9 @@ uint32_t rx_pucch(PHY_VARS_eNB *eNB,
}
//phase
// stat_max *= nsymb; // normalize to energy per symbol
// stat_max /= (frame_parms->N_RB_UL*12); //
// stat_max /= (frame_parms->N_RB_UL*12); //
stat_max
/=
(
nsymb
*
12
);
#ifdef DEBUG_PUCCH_RX
printf
(
"[eNB] PUCCH: stat %d, stat_max %d, phase_max %d
\n
"
,
stat
,
stat_max
,
phase_max
);
#endif
...
...
@@ -2289,8 +2307,13 @@ uint32_t rx_pucch(PHY_VARS_eNB *eNB,
stat_im
=
0
;
// Do detection now
#if defined(USRP_REC_PLAY)
// It looks like the value is a bit messy when RF is replayed.
// For instance i assume to skip pucch1_thres from the test below.
if
(
sigma2_dB
<
(
dB_fixed
(
stat_max
)))
{
//
#else
if
(
sigma2_dB
<
(
dB_fixed
(
stat_max
)
-
pucch1_thres
))
{
//
#endif
chL
=
(
nsymb
>>
1
)
-
4
;
chest_mag
=
0
;
cfo
=
(
frame_parms
->
Ncp
==
0
)
?
&
cfo_pucch_np
[
14
*
phase_max
]
:
&
cfo_pucch_ep
[
12
*
phase_max
];
...
...
@@ -2431,7 +2454,11 @@ uint32_t rx_pucch(PHY_VARS_eNB *eNB,
if
(
fmt
==
pucch_format1b
)
*
(
1
+
payload
)
=
(
stat_im
<
0
)
?
1
:
2
;
}
else
{
// insufficient energy on PUCCH so NAK
#if defined(USRP_REC_PLAY)
LOG_I
(
PHY
,
"PUCCH 1a/b: NAK subframe %d : sigma2_dB %d, stat_max %d, pucch1_thres %d
\n
"
,
subframe
,
sigma2_dB
,
dB_fixed
(
stat_max
),
pucch1_thres
);
#else
LOG_I
(
PHY
,
"PUCCH 1a/b: subframe %d : sigma2_dB %d, stat_max %d, pucch1_thres %d
\n
"
,
subframe
,
sigma2_dB
,
dB_fixed
(
stat_max
),
pucch1_thres
);
#endif
*
payload
=
4
;
// DTX
((
int16_t
*
)
&
eNB
->
pucch1ab_stats
[
UE_id
][(
subframe
<<
10
)
+
(
eNB
->
pucch1ab_stats_cnt
[
UE_id
][
subframe
])])[
0
]
=
(
int16_t
)(
stat_re
);
((
int16_t
*
)
&
eNB
->
pucch1ab_stats
[
UE_id
][(
subframe
<<
10
)
+
(
eNB
->
pucch1ab_stats_cnt
[
UE_id
][
subframe
])])[
1
]
=
(
int16_t
)(
stat_im
);
...
...
openair2/LAYER2/MAC/defs.h
View file @
1847a457
...
...
@@ -128,7 +128,11 @@
/*!\brief Maximum number od control elemenets */
#define MAX_NUM_CE 5
/*!\brief Maximum number of random access process */
#if defined(USRP_REC_PLAY)
#define NB_RA_PROC_MAX 1
#else
#define NB_RA_PROC_MAX 4
#endif
/*!\brief size of buffer status report table */
#define BSR_TABLE_SIZE 64
/*!\brief The power headroom reporting range is from -23 ...+40 dB and beyond, with step 1 */
...
...
openair2/LAYER2/MAC/eNB_scheduler_RA.c
View file @
1847a457
...
...
@@ -1579,7 +1579,25 @@ initiate_ra_proc(module_id_t module_idP,
ra
[
i
].
Msg2_subframe
=
(
subframeP
+
4
)
%
10
;
/* TODO: find better procedure to allocate RNTI */
do
{
#if defined(USRP_REC_PLAY) // deterministic rnti in usrp record/playback mode
static
int
drnti
[
NUMBER_OF_UE_MAX
]
=
{
0xbda7
,
0x71da
,
0x9c40
,
0xc350
,
0x2710
,
0x4e20
,
0x7530
,
0x1388
,
0x3a98
,
0x61a8
,
0x88b8
,
0xafc8
,
0xd6d8
,
0x1b58
,
0x4268
,
0x6978
};
int
j
=
0
;
int
nb_ue
=
0
;
for
(
j
=
0
;
j
<
NUMBER_OF_UE_MAX
;
j
++
)
{
if
(
UE_RNTI
(
module_idP
,
j
)
>
0
)
{
nb_ue
++
;
}
else
{
break
;
}
}
if
(
nb_ue
>=
NUMBER_OF_UE_MAX
)
{
printf
(
"No more free RNTI available, increase NUMBER_OF_UE_MAX
\n
"
);
abort
();
}
ra
[
i
].
rnti
=
drnti
[
nb_ue
];
#else
ra
[
i
].
rnti
=
taus
();
#endif
loop
++
;
}
while
(
loop
!=
100
&&
...
...
openair2/LAYER2/MAC/eNB_scheduler_primitives.c
View file @
1847a457
...
...
@@ -2057,6 +2057,9 @@ int add_new_ue(module_id_t mod_idP, int cc_idP, rnti_t rntiP, int harq_pidP
UE_list
->
ordered_ULCCids
[
0
][
UE_id
]
=
cc_idP
;
UE_list
->
num_UEs
++
;
UE_list
->
active
[
UE_id
]
=
TRUE
;
#if defined(USRP_REC_PLAY) // not specific to record/playback ?
UE_list
->
UE_template
[
cc_idP
][
UE_id
].
pre_assigned_mcs_ul
=
0
;
#endif
#ifdef Rel14
UE_list
->
UE_template
[
cc_idP
][
UE_id
].
rach_resource_type
=
...
...
openair2/LAYER2/PDCP_v10.1.0/pdcp_security.c
View file @
1847a457
...
...
@@ -220,7 +220,7 @@ pdcp_validate_security(
stream_decrypt
(
pdcp_pP
->
cipheringAlgorithm
,
&
decrypt_params
,
&
buffer_decrypted
);
#if !defined(USRP_REC_PLAY)
if
(
srb_flagP
)
{
/* Now check the integrity of the complete PDU */
decrypt_params
.
message
=
pdcp_pdu_buffer
;
...
...
@@ -241,7 +241,7 @@ pdcp_validate_security(
return
-
1
;
}
}
#endif
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME
(
VCD_SIGNAL_DUMPER_FUNCTIONS_PDCP_VALIDATE_SECURITY
,
VCD_FUNCTION_OUT
);
return
0
;
...
...
openair2/RRC/LITE/defs.h
View file @
1847a457
...
...
@@ -242,7 +242,11 @@ typedef enum HO_STATE_e {
// #define NUM_MAX_CBA_GROUP 4 // in the platform_constants
/* TS 36.331: RRC-TransactionIdentifier ::= INTEGER (0..3) */
#if defined(USRP_REC_PLAY)
#define RRC_TRANSACTION_IDENTIFIER_NUMBER 1
#else
#define RRC_TRANSACTION_IDENTIFIER_NUMBER 3
#endif
typedef
struct
{
unsigned
short
transport_block_size
;
/*!< \brief Minimum PDU size in bytes provided by RLC to MAC layer interface */
...
...
openair2/RRC/LITE/rrc_eNB_S1AP.c
View file @
1847a457
...
...
@@ -390,8 +390,10 @@ rrc_pdcp_config_security(
ue_context_pP
->
ue_context
.
kenb
,
&
kRRCint
);
#if !defined(USRP_REC_PLAY)
#define DEBUG_SECURITY 1
#endif
#if defined (DEBUG_SECURITY)
#undef msg
#define msg printf
...
...
targets/ARCH/COMMON/common_lib.h
View file @
1847a457
...
...
@@ -207,6 +207,15 @@ typedef struct {
int
iq_rxrescale
;
//! Configuration file for LMS7002M
char
*
configFilename
;
#if defined(USRP_REC_PLAY)
unsigned
short
sf_mode
;
// 1=record, 2=replay
char
sf_filename
[
1024
];
// subframes file path
unsigned
int
sf_max
;
// max number of recorded subframes
unsigned
int
sf_loops
;
// number of loops in replay mode
unsigned
int
sf_read_delay
;
// read delay in replay mode
unsigned
int
sf_write_delay
;
// write delay in replay mode
unsigned
int
eth_mtu
;
// ethernet MTU
#endif
}
openair0_config_t
;
/*! \brief RF mapping */
...
...
targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp
View file @
1847a457
...
...
@@ -270,11 +270,53 @@ static int sync_to_gps(openair0_device *device)
return
EXIT_SUCCESS
;
}
#if defined(USRP_REC_PLAY)
#include "usrp_lib.h"
static
FILE
*
pFile
=
NULL
;
int
mmapfd
=
0
;
struct
stat
sb
;
iqrec_t
*
ms_sample
=
NULL
;
// memory for all subframes
unsigned
int
nb_samples
=
0
;
unsigned
int
cur_samples
=
0
;
int64_t
wrap_count
=
0
;
int64_t
wrap_ts
=
0
;
unsigned
int
u_sf_mode
=
0
;
// 1=record, 2=replay
unsigned
int
u_sf_record
=
0
;
// record mode
unsigned
int
u_sf_replay
=
0
;
// replay mode
char
u_sf_filename
[
1024
];
// subframes file path
unsigned
int
u_sf_max
=
DEF_NB_SF
;
// max number of recorded subframes
unsigned
int
u_sf_loops
=
DEF_SF_NB_LOOP
;
// number of loops in replay mode
unsigned
int
u_sf_read_delay
=
DEF_SF_DELAY_READ
;
// read delay in replay mode
unsigned
int
u_sf_write_delay
=
DEF_SF_DELAY_WRITE
;
// write delay in replay mode
char
*
tmp_filename
[
1
];
// use an array of pointer (libconfig does not seems to work with char array yet)
char
config_opt_sf_file
[]
=
CONFIG_OPT_SF_FILE
;
char
config_def_sf_file
[]
=
DEF_SF_FILE
;
char
config_hlp_sf_file
[]
=
CONFIG_HLP_SF_FILE
;
char
config_opt_sf_rec
[]
=
CONFIG_OPT_SF_REC
;
char
config_hlp_sf_rec
[]
=
CONFIG_HLP_SF_REC
;
char
config_opt_sf_rep
[]
=
CONFIG_OPT_SF_REP
;
char
config_hlp_sf_rep
[]
=
CONFIG_HLP_SF_REP
;
char
config_opt_sf_max
[]
=
CONFIG_OPT_SF_MAX
;
char
config_hlp_sf_max
[]
=
CONFIG_HLP_SF_MAX
;
char
config_opt_sf_loops
[]
=
CONFIG_OPT_SF_LOOPS
;
char
config_hlp_sf_loops
[]
=
CONFIG_HLP_SF_LOOPS
;
char
config_opt_sf_rdelay
[]
=
CONFIG_OPT_SF_RDELAY
;
char
config_hlp_sf_rdelay
[]
=
CONFIG_HLP_SF_RDELAY
;
char
config_opt_sf_wdelay
[]
=
CONFIG_OPT_SF_WDELAY
;
char
config_hlp_sf_wdelay
[]
=
CONFIG_HLP_SF_WDELAY
;
#endif
/*! \brief Called to start the USRP transceiver. Return 0 if OK, < 0 if error
@param device pointer to the device structure specific to the RF hardware target
*/
static
int
trx_usrp_start
(
openair0_device
*
device
)
{
#if defined(USRP_REC_PLAY)
if
(
u_sf_mode
!=
2
)
{
// not replay mode
#endif
usrp_state_t
*
s
=
(
usrp_state_t
*
)
device
->
priv
;
...
...
@@ -313,12 +355,21 @@ static int trx_usrp_start(openair0_device *device) {
s
->
rx_count
=
0
;
s
->
tx_count
=
0
;
s
->
rx_timestamp
=
0
;
#if defined(USRP_REC_PLAY)
}
#endif
return
0
;
}
/*! \brief Terminate operation of the USRP transceiver -- free all associated resources
* \param device the hardware to use
*/
static
void
trx_usrp_end
(
openair0_device
*
device
)
{
#if defined(USRP_REC_PLAY) // For some ugly reason, this can be called several times...
static
int
done
=
0
;
if
(
done
==
1
)
return
;
done
=
1
;
if
(
u_sf_mode
!=
2
)
{
// not subframes replay
#endif
usrp_state_t
*
s
=
(
usrp_state_t
*
)
device
->
priv
;
s
->
rx_stream
->
issue_stream_cmd
(
uhd
::
stream_cmd_t
::
STREAM_MODE_STOP_CONTINUOUS
);
...
...
@@ -326,7 +377,45 @@ static void trx_usrp_end(openair0_device *device) {
s
->
tx_md
.
end_of_burst
=
true
;
s
->
tx_stream
->
send
(
""
,
0
,
s
->
tx_md
);
s
->
tx_md
.
end_of_burst
=
false
;
#if defined(USRP_REC_PLAY)
}
#endif
#if defined(USRP_REC_PLAY)
if
(
u_sf_mode
==
1
)
{
// subframes store
pFile
=
fopen
(
u_sf_filename
,
"wb+"
);
if
(
pFile
==
NULL
)
{
std
::
cerr
<<
"Cannot open "
<<
u_sf_filename
<<
std
::
endl
;
}
else
{
unsigned
int
i
=
0
;
unsigned
int
modu
=
0
;
if
((
modu
=
nb_samples
%
10
)
!=
0
)
{
nb_samples
-=
modu
;
// store entire number of frames
}
std
::
cerr
<<
"Writing "
<<
nb_samples
<<
" subframes to "
<<
u_sf_filename
<<
" ..."
<<
std
::
endl
;
for
(
i
=
0
;
i
<
nb_samples
;
i
++
)
{
fwrite
(
ms_sample
+
i
,
sizeof
(
unsigned
char
),
sizeof
(
iqrec_t
),
pFile
);
}
fclose
(
pFile
);
std
::
cerr
<<
"File "
<<
u_sf_filename
<<
" closed."
<<
std
::
endl
;
}
}
if
(
u_sf_mode
==
1
)
{
// record
if
(
ms_sample
!=
NULL
)
{
free
((
void
*
)
ms_sample
);
ms_sample
=
NULL
;
}
}
if
(
u_sf_mode
==
2
)
{
// replay
if
(
ms_sample
!=
MAP_FAILED
)
{
munmap
(
ms_sample
,
sb
.
st_size
);
ms_sample
=
NULL
;
}
if
(
mmapfd
!=
0
)
{
close
(
mmapfd
);
mmapfd
=
0
;
}
}
#endif
}
/*! \brief Called to send samples to the USRP RF target
...
...
@@ -339,6 +428,9 @@ static void trx_usrp_end(openair0_device *device) {
*/
static
int
trx_usrp_write
(
openair0_device
*
device
,
openair0_timestamp
timestamp
,
void
**
buff
,
int
nsamps
,
int
cc
,
int
flags
)
{
int
ret
=
0
;
#if defined(USRP_REC_PLAY)
if
(
u_sf_mode
!=
2
)
{
// not replay mode
#endif
usrp_state_t
*
s
=
(
usrp_state_t
*
)
device
->
priv
;
int
nsamps2
;
// aligned to upper 32 or 16 byte boundary
...
...
@@ -405,6 +497,15 @@ static int trx_usrp_write(openair0_device *device, openair0_timestamp timestamp,
if
(
ret
!=
nsamps
)
LOG_E
(
PHY
,
"[xmit] tx samples %d != %d
\n
"
,
ret
,
nsamps
);
#if defined(USRP_REC_PLAY)
}
else
{
struct
timespec
req
;
req
.
tv_sec
=
0
;
req
.
tv_nsec
=
u_sf_write_delay
*
1000
;
nanosleep
(
&
req
,
NULL
);
ret
=
nsamps
;
}
#endif
return
ret
;
}
...
...
@@ -421,9 +522,12 @@ static int trx_usrp_write(openair0_device *device, openair0_timestamp timestamp,
* \returns the number of sample read
*/
static
int
trx_usrp_read
(
openair0_device
*
device
,
openair0_timestamp
*
ptimestamp
,
void
**
buff
,
int
nsamps
,
int
cc
)
{
usrp_state_t
*
s
=
(
usrp_state_t
*
)
device
->
priv
;
int
samples_received
=
0
,
i
,
j
;
int
nsamps2
;
// aligned to upper 32 or 16 byte boundary
usrp_state_t
*
s
=
(
usrp_state_t
*
)
device
->
priv
;
int
samples_received
=
0
,
i
,
j
;
int
nsamps2
;
// aligned to upper 32 or 16 byte boundary
#if defined(USRP_REC_PLAY)
if
(
u_sf_mode
!=
2
)
{
// not replay mode
#endif
#if defined(__x86_64) || defined(__i386__)
#ifdef __AVX2__
nsamps2
=
(
nsamps
+
7
)
>>
3
;
...
...
@@ -490,7 +594,45 @@ static int trx_usrp_read(openair0_device *device, openair0_timestamp *ptimestamp
s
->
rx_count
+=
nsamps
;
s
->
rx_timestamp
=
s
->
rx_md
.
time_spec
.
to_ticks
(
s
->
sample_rate
);
*
ptimestamp
=
s
->
rx_timestamp
;
return
samples_received
;
#if defined (USRP_REC_PLAY)
}
#endif
#if defined(USRP_REC_PLAY)
if
(
u_sf_mode
==
1
)
{
// record mode
// Copy subframes to memory (later dump on a file)
if
(
nb_samples
<
u_sf_max
)
{
(
ms_sample
+
nb_samples
)
->
header
=
BELL_LABS_IQ_HEADER
;
(
ms_sample
+
nb_samples
)
->
ts
=
*
ptimestamp
;
memcpy
((
ms_sample
+
nb_samples
)
->
samples
,
buff
[
0
],
nsamps
*
4
);
nb_samples
++
;
}
}
else
if
(
u_sf_mode
==
2
)
{
// replay mode
if
(
cur_samples
==
nb_samples
)
{
cur_samples
=
0
;
wrap_count
++
;
if
(
wrap_count
==
u_sf_loops
)
{
std
::
cerr
<<
"USRP device terminating subframes replay mode after "
<<
u_sf_loops
<<
" loops."
<<
std
::
endl
;
return
0
;
// should make calling process exit
}
wrap_ts
=
wrap_count
*
(
nb_samples
*
(((
int
)(
device
->
openair0_cfg
[
0
].
sample_rate
))
/
1000
));
}
if
(
cur_samples
<
nb_samples
)
{
*
ptimestamp
=
(
ms_sample
[
0
].
ts
+
(
cur_samples
*
(((
int
)(
device
->
openair0_cfg
[
0
].
sample_rate
))
/
1000
)))
+
wrap_ts
;
if
(
cur_samples
==
0
)
{
std
::
cerr
<<
"starting subframes file with wrap_count="
<<
wrap_count
<<
" wrap_ts="
<<
wrap_ts
<<
" ts="
<<
*
ptimestamp
<<
std
::
endl
;
}
memcpy
(
buff
[
0
],
&
ms_sample
[
cur_samples
].
samples
[
0
],
nsamps
*
4
);
cur_samples
++
;
}
struct
timespec
req
;
req
.
tv_sec
=
0
;
req
.
tv_nsec
=
u_sf_read_delay
*
1000
;
nanosleep
(
&
req
,
NULL
);
return
nsamps
;
}
#endif
return
samples_received
;
}
/*! \brief Compares two variables within precision
...
...
@@ -684,12 +826,135 @@ int trx_usrp_reset_stats(openair0_device* device) {
return
(
0
);
}
#if defined(USRP_REC_PLAY)
extern
"C"
{
/*! \brief Initializer for USRP record/playback config
* \param parameter array description
* \returns 0 on success
*/
int
trx_usrp_recplay_config_init
(
paramdef_t
*
usrp_recplay_params
)
{
// --subframes-file
memcpy
(
usrp_recplay_params
[
0
].
optname
,
config_opt_sf_file
,
strlen
(
config_opt_sf_file
));
usrp_recplay_params
[
0
].
helpstr
=
config_hlp_sf_file
;
usrp_recplay_params
[
0
].
paramflags
=
PARAMFLAG_NOFREE
;
usrp_recplay_params
[
0
].
strptr
=
(
char
**
)
&
tmp_filename
[
0
];
usrp_recplay_params
[
0
].
defstrval
=
NULL
;
usrp_recplay_params
[
0
].
type
=
TYPE_STRING
;
usrp_recplay_params
[
0
].
numelt
=
sizeof
(
u_sf_filename
);
// --subframes-record
memcpy
(
usrp_recplay_params
[
1
].
optname
,
config_opt_sf_rec
,
strlen
(
config_opt_sf_rec
));
usrp_recplay_params
[
1
].
helpstr
=
config_hlp_sf_rec
;
usrp_recplay_params
[
1
].
paramflags
=
PARAMFLAG_BOOL
;
usrp_recplay_params
[
1
].
uptr
=&
u_sf_record
;
usrp_recplay_params
[
1
].
defuintval
=
0
;
usrp_recplay_params
[
1
].
type
=
TYPE_UINT
;
usrp_recplay_params
[
1
].
numelt
=
0
;
// --subframes-replay
memcpy
(
usrp_recplay_params
[
2
].
optname
,
config_opt_sf_rep
,
strlen
(
config_opt_sf_rep
));
usrp_recplay_params
[
2
].
helpstr
=
config_hlp_sf_rep
;
usrp_recplay_params
[
2
].
paramflags
=
PARAMFLAG_BOOL
;
usrp_recplay_params
[
2
].
uptr
=&
u_sf_replay
;
usrp_recplay_params
[
2
].
defuintval
=
0
;
usrp_recplay_params
[
2
].
type
=
TYPE_UINT
;
usrp_recplay_params
[
2
].
numelt
=
0
;
// --subframes-max
memcpy
(
usrp_recplay_params
[
3
].
optname
,
config_opt_sf_max
,
strlen
(
config_opt_sf_max
));
usrp_recplay_params
[
3
].
helpstr
=
config_hlp_sf_max
;
usrp_recplay_params
[
3
].
paramflags
=
0
;
usrp_recplay_params
[
3
].
uptr
=&
u_sf_max
;
usrp_recplay_params
[
3
].
defuintval
=
DEF_NB_SF
;
usrp_recplay_params
[
3
].
type
=
TYPE_UINT
;
usrp_recplay_params
[
3
].
numelt
=
0
;
// --subframes-loops
memcpy
(
usrp_recplay_params
[
4
].
optname
,
config_opt_sf_loops
,
strlen
(
config_opt_sf_loops
));
usrp_recplay_params
[
4
].
helpstr
=
config_hlp_sf_loops
;
usrp_recplay_params
[
4
].
paramflags
=
0
;
usrp_recplay_params
[
4
].
uptr
=&
u_sf_loops
;
usrp_recplay_params
[
4
].
defuintval
=
DEF_SF_NB_LOOP
;
usrp_recplay_params
[
4
].
type
=
TYPE_UINT
;
usrp_recplay_params
[
4
].
numelt
=
0
;
// --subframes-read-delay
memcpy
(
usrp_recplay_params
[
5
].
optname
,
config_opt_sf_rdelay
,
strlen
(
config_opt_sf_rdelay
));
usrp_recplay_params
[
5
].
helpstr
=
config_hlp_sf_rdelay
;
usrp_recplay_params
[
5
].
paramflags
=
0
;
usrp_recplay_params
[
5
].
uptr
=&
u_sf_read_delay
;
usrp_recplay_params
[
5
].
defuintval
=
DEF_SF_DELAY_READ
;
usrp_recplay_params
[
5
].
type
=
TYPE_UINT
;
usrp_recplay_params
[
5
].
numelt
=
0
;
// --subframes-write-delay
memcpy
(
usrp_recplay_params
[
6
].
optname
,
config_opt_sf_wdelay
,
strlen
(
config_opt_sf_wdelay
));
usrp_recplay_params
[
6
].
helpstr
=
config_hlp_sf_wdelay
;
usrp_recplay_params
[
6
].
paramflags
=
0
;
usrp_recplay_params
[
6
].
uptr
=&
u_sf_write_delay
;
usrp_recplay_params
[
6
].
defuintval
=
DEF_SF_DELAY_WRITE
;
usrp_recplay_params
[
6
].
type
=
TYPE_UINT
;
usrp_recplay_params
[
6
].
numelt
=
0
;
return
0
;
// always ok
}
}
#endif
extern
"C"
{
/*! \brief Initialize Openair USRP target. It returns 0 if OK
* \param device the hardware to use
* \param openair0_cfg RF frontend parameters set by application
*/
int
device_init
(
openair0_device
*
device
,
openair0_config_t
*
openair0_cfg
)
{
#if defined(USRP_REC_PLAY)
paramdef_t
usrp_recplay_params
[
7
];
// to check
static
int
done
=
0
;
if
(
done
==
1
)
{
return
0
;
}
// prevent from multiple init
done
=
1
;
// end to check
memset
(
usrp_recplay_params
,
0
,
7
*
sizeof
(
paramdef_t
));
memset
(
&
u_sf_filename
[
0
],
0
,
1024
);
tmp_filename
[
0
]
=
u_sf_filename
;
if
(
trx_usrp_recplay_config_init
(
usrp_recplay_params
)
!=
0
)
{
std
::
cerr
<<
"USRP device record/replay mode configuration error exiting"
<<
std
::
endl
;
return
-
1
;
}
config_process_cmdline
(
usrp_recplay_params
,
sizeof
(
usrp_recplay_params
)
/
sizeof
(
paramdef_t
),
NULL
);
if
(
strlen
(
tmp_filename
[
0
])
!=
0
)
{
(
void
)
strcpy
(
u_sf_filename
,
tmp_filename
[
0
]);
}
else
{
(
void
)
strcpy
(
u_sf_filename
,
DEF_SF_FILE
);
}
if
(
u_sf_replay
==
1
)
u_sf_mode
=
2
;
if
(
u_sf_record
==
1
)
u_sf_mode
=
1
;
if
(
u_sf_mode
==
2
)
{
// Replay subframes from from file
int
bw_gain_adjust
=
0
;
device
->
openair0_cfg
=
openair0_cfg
;
device
->
type
=
USRP_B200_DEV
;
openair0_cfg
[
0
].
rx_gain_calib_table
=
calib_table_b210_38
;
bw_gain_adjust
=
1
;
openair0_cfg
[
0
].
tx_sample_advance
=
80
;
openair0_cfg
[
0
].
tx_bw
=
20e6
;
openair0_cfg
[
0
].
rx_bw
=
20e6
;
openair0_cfg
[
0
].
iq_txshift
=
4
;
//shift
openair0_cfg
[
0
].
iq_rxrescale
=
15
;
//rescale iqs
set_rx_gain_offset
(
&
openair0_cfg
[
0
],
0
,
bw_gain_adjust
);
device
->
priv
=
NULL
;
device
->
trx_start_func
=
trx_usrp_start
;
device
->
trx_write_func
=
trx_usrp_write
;
device
->
trx_read_func
=
trx_usrp_read
;
device
->
trx_get_stats_func
=
trx_usrp_get_stats
;
device
->
trx_reset_stats_func
=
trx_usrp_reset_stats
;
device
->
trx_end_func
=
trx_usrp_end
;
device
->
trx_stop_func
=
trx_usrp_stop
;
device
->
trx_set_freq_func
=
trx_usrp_set_freq
;
device
->
trx_set_gains_func
=
trx_usrp_set_gains
;
device
->
openair0_cfg
=
openair0_cfg
;
std
::
cerr
<<
"USRP device initialized in subframes replay mode for "
<<
u_sf_loops
<<
" loops."
<<
std
::
endl
;
}
else
{
#endif
uhd
::
set_thread_priority_safe
(
1.0
);
usrp_state_t
*
s
=
(
usrp_state_t
*
)
calloc
(
sizeof
(
usrp_state_t
),
1
);
...
...
@@ -705,6 +970,11 @@ extern "C" {
int
vers
=
0
,
subvers
=
0
,
subsubvers
=
0
;
int
bw_gain_adjust
=
0
;
#if defined(USRP_REC_PLAY)
if
(
u_sf_mode
==
1
)
{
std
::
cerr
<<
"USRP device initialized in subframes record mode"
<<
std
::
endl
;
}
#endif
sscanf
(
uhd
::
get_version_string
().
c_str
(),
"%d.%d.%d"
,
&
vers
,
&
subvers
,
&
subsubvers
);
LOG_I
(
PHY
,
"Checking for USRPs : UHD %s (%d.%d.%d)
\n
"
,
uhd
::
get_version_string
().
c_str
(),
vers
,
subvers
,
subsubvers
);
...
...
@@ -742,7 +1012,9 @@ extern "C" {
//s->usrp->set_master_clock_rate(usrp_master_clock);
openair0_cfg
[
0
].
rx_gain_calib_table
=
calib_table_x310
;
#if defined(USRP_REC_PLAY)
std
::
cerr
<<
"-- Using calibration table: calib_table_x310"
<<
std
::
endl
;
// Bell Labs info
#endif
switch
((
int
)
openair0_cfg
[
0
].
sample_rate
)
{
case
30720000
:
// from usrp_time_offset
...
...
@@ -801,9 +1073,15 @@ extern "C" {
if
((
vers
==
3
)
&&
(
subvers
==
9
)
&&
(
subsubvers
>=
2
))
{
openair0_cfg
[
0
].
rx_gain_calib_table
=
calib_table_b210
;
bw_gain_adjust
=
0
;
#if defined(USRP_REC_PLAY)
std
::
cerr
<<
"-- Using calibration table: calib_table_b210"
<<
std
::
endl
;
// Bell Labs info
#endif
}
else
{
openair0_cfg
[
0
].
rx_gain_calib_table
=
calib_table_b210_38
;
bw_gain_adjust
=
1
;
#if defined(USRP_REC_PLAY)
std
::
cerr
<<
"-- Using calibration table: calib_table_b210_38"
<<
std
::
endl
;
// Bell Labs info
#endif
}
switch
((
int
)
openair0_cfg
[
0
].
sample_rate
)
{
...
...
@@ -965,6 +1243,45 @@ extern "C" {
}
}
#if defined(USRP_REC_PLAY)
}
#endif
#if defined(USRP_REC_PLAY)
if
(
u_sf_mode
==
1
)
{
// record mode
ms_sample
=
(
iqrec_t
*
)
malloc
(
u_sf_max
*
sizeof
(
iqrec_t
));
if
(
ms_sample
==
NULL
)
{
std
::
cerr
<<
"Memory allocation failed for subframe record or replay mode."
<<
std
::
endl
;
exit
(
-
1
);
}
memset
(
ms_sample
,
0
,
u_sf_max
*
BELL_LABS_IQ_BYTES_PER_SF
);
}
if
(
u_sf_mode
==
2
)
{
// use mmap
mmapfd
=
open
(
u_sf_filename
,
O_RDONLY
|
O_LARGEFILE
);
if
(
mmapfd
!=
0
)
{
fstat
(
mmapfd
,
&
sb
);
std
::
cerr
<<
"Loading subframes using mmap() from "
<<
u_sf_filename
<<
" size="
<<
(
uint64_t
)
sb
.
st_size
<<
" bytes ..."
<<
std
::
endl
;
ms_sample
=
(
iqrec_t
*
)
mmap
(
NULL
,
sb
.
st_size
,
PROT_WRITE
,
MAP_PRIVATE
,
mmapfd
,
0
);
if
(
ms_sample
!=
MAP_FAILED
)
{
nb_samples
=
(
sb
.
st_size
/
sizeof
(
iqrec_t
));
int
aligned
=
(((
unsigned
long
)
ms_sample
&
31
)
==
0
)
?
1
:
0
;
std
::
cerr
<<
"Loaded "
<<
nb_samples
<<
" subframes."
<<
std
::
endl
;
if
(
aligned
==
0
)
{
std
::
cerr
<<
"mmap address is not 32 bytes aligned, exiting."
<<
std
::
endl
;
close
(
mmapfd
);
exit
(
-
1
);
}
}
else
{
std
::
cerr
<<
"Cannot mmap file, exiting."
<<
std
::
endl
;
close
(
mmapfd
);
exit
(
-
1
);
}
}
else
{
std
::
cerr
<<
"Cannot open "
<<
u_sf_filename
<<
" , exiting."
<<
std
::
endl
;
exit
(
-
1
);
}
}
#endif
return
0
;
}
}
...
...
targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.h
0 → 100644
View file @
1847a457
#ifndef __USRP_LIB_H
#define __USRP_LIB_H
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
/** usrp_lib.h
*
* \author: bruno.mongazon-cazavet@nokia-bell-labs.com
*/
#if defined (USRP_REC_PLAY)
#include <sys/mman.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include "common/config/config_paramdesc.h"
#include "common/config/config_userapi.h"
#define BELL_LABS_IQ_HEADER 0xabababababababab
#define BELL_LABS_IQ_PER_SF 7680 // Up to 5MHz bw for now
#define BELL_LABS_IQ_BYTES_PER_SF (BELL_LABS_IQ_PER_SF * 4)
typedef
struct
{
int64_t
header
;
int64_t
ts
;
int64_t
rfu1
;
int64_t
rfu2
;
// pad for 256 bits alignement required by AVX2
unsigned
char
samples
[
BELL_LABS_IQ_BYTES_PER_SF
];
// iq's for one subframe
}
iqrec_t
;
#define DEF_NB_SF 120000 // default nb of sf or ms to capture (2 minutes at 5MHz)
#define DEF_SF_FILE "/home/nokia/iqfile" // default subframes file name
#define DEF_SF_DELAY_READ 400 // default read delay µs (860=real)
#define DEF_SF_DELAY_WRITE 15 // default write delay µs (15=real)
#define DEF_SF_NB_LOOP 5 // default nb loops
/* help strings definition for command line options, used in CMDLINE_XXX_DESC macros and printed when -h option is used */
#define CONFIG_HLP_SF_FILE "Path of the file used for subframes record or replay"
#define CONFIG_HLP_SF_REC "Record subframes from USRP driver into a file for later replay"
#define CONFIG_HLP_SF_REP "Replay subframes into USRP driver from a file"
#define CONFIG_HLP_SF_MAX "Maximum count of subframes to be recorded in subframe file"
#define CONFIG_HLP_SF_LOOPS "Number of loops to replay of the entire subframes file"
#define CONFIG_HLP_SF_RDELAY "Delay in microseconds to read a subframe in replay mode"
#define CONFIG_HLP_SF_WDELAY "Delay in microseconds to write a subframe in replay mode"
/* keyword strings for command line options, used in CMDLINE_XXX_DESC macros and printed when -h option is used */
#define CONFIG_OPT_SF_FILE "subframes-file"
#define CONFIG_OPT_SF_REC "subframes-record"
#define CONFIG_OPT_SF_REP "subframes-replay"
#define CONFIG_OPT_SF_MAX "subframes-max"
#define CONFIG_OPT_SF_LOOPS "subframes-loops"
#define CONFIG_OPT_SF_RDELAY "subframes-read-delay"
#define CONFIG_OPT_SF_WDELAY "subframes-write-delay"
/* For information only - the macro is not usable in C++ */
/*---------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
/* command line parameters for USRP record/playback */
/* optname helpstr paramflags XXXptr defXXXval type numelt */
/*---------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
#define USRP_RECPLAY_PARAMS_DESC { \
{"subframes-file", CONFIG_HLP_SF_FILE, 0, strptr:(char **)&u_sf_filename, defstrval:DEF_SF_FILE, TYPE_STRING, sizeof(u_sf_filename)}, \
{"subframes-record", CONFIG_HLP_SF_REC, PARAMFLAG_BOOL, uptr:&u_sf_record, defuintval:0, TYPE_UINT, 0}, \
{"subframes-replay", CONFIG_HLP_SF_REP, PARAMFLAG_BOOL, uptr:&u_sf_replay, defuintval:0, TYPE_UINT, 0}, \
{"subframes-max", CONFIG_HLP_SF_MAX, 0, uptr:&u_sf_max, defintval:DEF_NB_SF, TYPE_UINT, 0}, \
{"subframes-loops", CONFIG_HLP_SF_LOOPS, 0, uptr:&u_sf_loops, defintval:DEF_SF_NB_LOOP, TYPE_UINT, 0}, \
{"subframes-read-delay", CONFIG_HLP_SF_RDELAY, 0, uptr:&u_sf_read_delay, defintval:DEF_SF_DELAY_READ, TYPE_UINT, 0}, \
{"subframes-write-delay", CONFIG_HLP_SF_WDELAY, 0, uptr:&u_sf_write_delay, defintval:DEF_SF_DELAY_WRITE, TYPE_UINT, 0}, \
}
#endif // BELL_LABS_MUST
#endif // __USRP_LIB_H
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